diff --git a/src/Makefile.am b/src/Makefile.am
index 08b3309..25fdab2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -41,6 +41,8 @@
 libgprs_la_SOURCES = \
 	gprs_debug.cpp \
 	csn1.c \
+	csn1_dec.c \
+	csn1_enc.c \
 	gsm_rlcmac.c \
 	gprs_bssgp_pcu.c \
 	gprs_bssgp_rim.c \
diff --git a/src/csn1.c b/src/csn1.c
index 2be0392..e165e92 100644
--- a/src/csn1.c
+++ b/src/csn1.c
@@ -1,4 +1,4 @@
-/* csn1.cpp
+/* csn1_enc.c
  * Routines for CSN1 dissection in wireshark.
  *
  * Copyright (C) 2011 Ivan Klyuchnikov
@@ -38,20 +38,10 @@
 #include <osmocom/core/logging.h>
 #include <osmocom/core/utils.h>
 
-#define pvDATA(_pv, _offset) ((void*) ((unsigned char*)_pv + _offset))
-#define pui8DATA(_pv, _offset) ((guint8*) pvDATA(_pv, _offset))
-#define pui16DATA(_pv, _offset) ((guint16*) pvDATA(_pv, _offset))
-#define pui32DATA(_pv, _offset) ((guint32*) pvDATA(_pv, _offset))
-#define pui64DATA(_pv, _offset) ((guint64*) pvDATA(_pv, _offset))
-/* used to tag existence of next element in variable length lists */
-#define STANDARD_TAG 1
-#define REVERSED_TAG 0
-
-static const unsigned char ixBitsTab[] = {0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5};
-
+const unsigned char ixBitsTab[] = {0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5};
 
 /* Returns no_of_bits (up to 8) masked with 0x2B */
-static guint8
+guint8
 get_masked_bits8(struct bitvec *vector, unsigned *readIndex, gint bit_offset,  const gint no_of_bits)
 {
   static const guint8 maskBits[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
@@ -105,7 +95,7 @@
 };
 
 
-static gint16 ProcessError_impl(const char *file, int line, unsigned *readIndex,
+gint16 ProcessError_impl(const char *file, int line, unsigned *readIndex,
                                 const char* sz, gint16 err, const CSN_DESCR* pDescr)
 {
   /* Don't add trailing newline, top caller is responsible for appending it */
@@ -115,2615 +105,3 @@
             pDescr ? pDescr->sz : "-", *readIndex);
   return err;
 }
-
-#define ProcessError(readIndex, sz, err, pDescr) \
-        ProcessError_impl(__FILE__, __LINE__, readIndex, sz, err, pDescr)
-
-
-/**
- * ================================================================================================
- * Return TRUE if tag in bit stream indicates existence of next list element,
- * otherwise return FALSE.
- * Will work for tag values equal to both 0 and 1.
- * ================================================================================================
- */
-
-static gboolean
-existNextElement(struct bitvec *vector, unsigned *readIndex, guint8 Tag)
-{
-  int res = bitvec_get_bit_pos(vector, (*readIndex)++);
-  if (Tag == STANDARD_TAG)
-  {
-    return (res > 0);
-  }
-  return (res == 0);
-}
-
-
-gint16
-csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector, unsigned *readIndex, void* data)
-{
-  gint  remaining_bits_len = ar->remaining_bits_len;
-  gint  bit_offset         = ar->bit_offset;
-  guint8*  pui8 = NULL;
-  guint16* pui16;
-  guint32* pui32;
-  guint64* pui64;
-  guint8 Tag = STANDARD_TAG;
-  unsigned ib;
-
-  if (remaining_bits_len < 0)
-  {
-    return ProcessError(readIndex, __func__, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-  }
-
-  do
-  {
-    switch (pDescr->type)
-    {
-      case CSN_BIT:
-      {
-        if (remaining_bits_len > 0)
-        {
-          pui8  = pui8DATA(data, pDescr->offset);
-	  *pui8 = bitvec_read_field(vector, readIndex, 1);
-          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-          /* end add the bit value to protocol tree */
-        }
-        else if (pDescr->may_be_null)
-        {
-           pui8  = pui8DATA(data, pDescr->offset);
-           *pui8 = 0;
-           LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
-        }
-        else
-        {
-          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-
-        pDescr++;
-        remaining_bits_len--;
-        bit_offset++;
-        break;
-      }
-
-      case CSN_NULL:
-      { /* Empty member! */
-        bit_offset += pDescr->i;
-        pDescr++;
-        break;
-      }
-
-      case CSN_UINT:
-      {
-        guint8 no_of_bits = (guint8) pDescr->i;
-
-        if (remaining_bits_len >= no_of_bits)
-        {
-          if (no_of_bits <= 8)
-          {
-	    guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
-            pui8      = pui8DATA(data, pDescr->offset);
-            *pui8     = ui8;
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-          }
-          else if (no_of_bits <= 16)
-          {
-	    guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
-            pui16       = pui16DATA(data, pDescr->offset);
-            *pui16      = ui16;
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
-          }
-          else if (no_of_bits <= 32)
-          {
-	    guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
-            pui32       = pui32DATA(data, pDescr->offset);
-            *pui32      = ui32;
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = 0x%08x | ", pDescr->sz , *pui32);
-          }
-          else
-          {
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
-          }
-          remaining_bits_len -= no_of_bits;
-          bit_offset += no_of_bits;
-        }
-        else if (pDescr->may_be_null)
-        {
-          if (no_of_bits <= 8)
-          {
-            pui8      = pui8DATA(data, pDescr->offset);
-            *pui8     = 0;
-          }
-          else if (no_of_bits <= 16)
-          {
-            pui16      = pui16DATA(data, pDescr->offset);
-            *pui16     = 0;
-          }
-          else if (no_of_bits <= 32)
-          {
-            pui32      = pui32DATA(data, pDescr->offset);
-            *pui32     = 0;
-          }
-          LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
-        }
-        else
-        {
-          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_UINT_OFFSET:
-      {
-        guint8 no_of_bits = (guint8) pDescr->i;
-
-        if (remaining_bits_len >= no_of_bits)
-        {
-          if (no_of_bits <= 8)
-          {
-	    guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
-            pui8      = pui8DATA(data, pDescr->offset);
-            *pui8     = ui8 + (guint8)pDescr->descr.value;
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-          }
-          else if (no_of_bits <= 16)
-          {
-	    guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
-            pui16       = pui16DATA(data, pDescr->offset);
-            *pui16      = ui16 + (guint16)pDescr->descr.value;
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
-          }
-          else if (no_of_bits <= 32)
-          {
-	    guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
-            pui32       = pui32DATA(data, pDescr->offset);
-            *pui32      = ui32 + (guint16)pDescr->descr.value;
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
-          }
-          else
-          {
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
-          }
-        }
-        else
-        {
-          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-
-        remaining_bits_len -= no_of_bits;
-        bit_offset += no_of_bits;
-        pDescr++;
-        break;
-      }
-
-      case CSN_UINT_LH:
-      {
-        guint8 no_of_bits = (guint8) pDescr->i;
-
-        if (remaining_bits_len >= no_of_bits)
-        {
-          if (no_of_bits <= 8)
-          {
-	    guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
-            pui8      = pui8DATA(data, pDescr->offset);
-            *pui8     = ui8;
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-          }
-          else
-          {/* Maybe we should support more than 8 bits ? */
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
-          }
-        }
-        else
-        {
-          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-
-        remaining_bits_len -= no_of_bits;
-        bit_offset += no_of_bits;
-        pDescr++;
-        break;
-      }
-
-      case CSN_UINT_ARRAY:
-      {
-        guint8  no_of_bits  = (guint8) pDescr->i;
-        guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
-
-        if (pDescr->value != 0)
-        { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
-          nCount = *pui16DATA(data, nCount);
-        }
-
-        if (remaining_bits_len >= (no_of_bits * nCount))
-        {
-          remaining_bits_len -= (no_of_bits*nCount);
-          if (no_of_bits <= 8)
-          {
-            pui8 = pui8DATA(data, pDescr->offset);
-            do
-            {
-	      *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              pui8++;
-              bit_offset += no_of_bits;
-            } while (--nCount > 0);
-          }
-          else if (no_of_bits <= 16)
-          {
-            return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
-          }
-          else if (no_of_bits <= 32)
-          {
-            return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
-          }
-          else
-          {
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
-          }
-        }
-        else
-        {
-          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-        pDescr++;
-        break;
-      }
-
-      case CSN_VARIABLE_TARRAY_OFFSET:
-      case CSN_VARIABLE_TARRAY:
-      case CSN_TYPE_ARRAY:
-      {
-        gint16      Status;
-        csnStream_t arT    = *ar;
-        gint16      nCount = pDescr->i;
-        guint16      nSize  = (guint16)(gint32)pDescr->value;
-
-        pui8 = pui8DATA(data, pDescr->offset);
-        if (pDescr->type == CSN_VARIABLE_TARRAY)
-        { /* Count specified in field */
-          nCount = *pui8DATA(data, pDescr->i);
-        }
-        else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
-        { /* Count specified in field */
-          nCount = *pui8DATA(data, pDescr->i);
-	  /*  nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
-        }
-
-        while (nCount > 0)
-        { /* resulting array of length 0 is possible
-           * but no bits shall be read from bitstream
-           */
-
-          LOGPC(DCSN1, LOGL_DEBUG, "%s | ", pDescr->sz);
-          csnStreamInit(&arT, bit_offset, remaining_bits_len);
-	  Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
-          if (Status >= 0)
-          {
-            pui8    += nSize;
-            remaining_bits_len = arT.remaining_bits_len;
-            bit_offset         = arT.bit_offset;
-          }
-          else
-          {
-            return Status;
-          }
-          nCount--;
-        }
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_BITMAP:
-      { /* bitmap with given length. The result is left aligned! */
-        guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
-
-        if (no_of_bits > 0)
-        {
-          if (no_of_bits > remaining_bits_len)
-          {
-            return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-          if (no_of_bits <= 32)
-          {
-            for(ib = 0; ib < 4; ib++)
-            {
-	      guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
-              pui8      = pui8DATA(data, pDescr->offset+ib);
-              *pui8      = ui8;
-               LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
-            }
-          }
-          else if (no_of_bits <= 64)
-          {
-            for(ib = 0; ib < 8; ib++)
-            {
-	      guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
-              pui8      = pui8DATA(data, pDescr->offset+ib);
-              *pui8      = ui8;
-               LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
-            }
-          }
-          else
-          {
-          	return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
-          }
-
-          remaining_bits_len -= no_of_bits;
-          bit_offset += no_of_bits;
-        }
-        /* bitmap was successfully extracted or it was empty */
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_TYPE:
-      {
-        gint16      Status;
-        csnStream_t arT = *ar;
-        LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
-        csnStreamInit(&arT, bit_offset, remaining_bits_len);
-	Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
-        LOGPC(DCSN1, LOGL_DEBUG, ": End %s | ", pDescr->sz);
-        if (Status >= 0)
-        {
-          remaining_bits_len  = arT.remaining_bits_len;
-          bit_offset          = arT.bit_offset;
-          pDescr++;
-        }
-        else
-        {
-          /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr);  */
-          return Status;
-        }
-
-        break;
-      }
-
-      case CSN_CHOICE:
-      {
-        gint16 count = pDescr->i;
-        guint8 i     = 0;
-        CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
-
-        /* Make sure that the list of choice items is not empty */
-        if (!count)
-          return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
-        else if (count > 255) /* We can handle up to 256 (UCHAR_MAX) selectors */
-          return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
-
-        while (count > 0)
-        {
-          guint8 no_of_bits = pChoice->bits;
-	  guint8 value = bitvec_read_field(vector, readIndex, no_of_bits);
-          if (value == pChoice->value)
-          {
-            CSN_DESCR   descr[2];
-            gint16      Status;
-            csnStream_t arT = *ar;
-
-            descr[0]      = pChoice->descr;
-            memset(&descr[1], 0x00, sizeof(CSN_DESCR));
-            descr[1].type = CSN_END;
-            pui8          = pui8DATA(data, pDescr->offset);
-            *pui8         = i;
-            LOGPC(DCSN1, LOGL_DEBUG, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
-            if (!pChoice->keep_bits) {
-              bit_offset += no_of_bits;
-              remaining_bits_len -= no_of_bits;
-            }
-
-            csnStreamInit(&arT, bit_offset, remaining_bits_len);
-	    Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
-
-            if (Status >= 0)
-            {
-              remaining_bits_len = arT.remaining_bits_len;
-              bit_offset         = arT.bit_offset;
-            }
-            else
-            {
-              return Status;
-            }
-            break;
-          }
-
-          *readIndex -= no_of_bits;
-          count--;
-          pChoice++;
-          i++;
-        }
-
-        /* Neither of the choice items matched => unknown value */
-        if (!count)
-          return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_SERIALIZE:
-      {
-        StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
-        csnStream_t          arT       = *ar;
-        guint8 length_len              = pDescr->i;
-        gint16               Status    = -1;
-
-	guint8 length = bitvec_read_field(vector, readIndex, length_len);
-
-        LOGPC(DCSN1, LOGL_DEBUG, "%s length = %u | ", pDescr->sz , length);
-        bit_offset += length_len;
-        remaining_bits_len -= length_len;
-
-        csnStreamInit(&arT, bit_offset, length > 0 ? length : remaining_bits_len);
-        arT.direction = 1;
-        LOGPC(DCSN1, LOGL_DEBUG, "offset = %u | ", pDescr->offset);
-	Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
-
-        if (Status >= 0)
-        {
-          if (length > 0) {
-            remaining_bits_len -= length;
-            bit_offset         += length;
-          } else {
-            remaining_bits_len = arT.remaining_bits_len;
-            bit_offset         = arT.bit_offset;
-          }
-
-          /* Skip bits not handled by serialize(), if any */
-          if (Status > 0) {
-            LOGPC(DCSN1, LOGL_DEBUG, "skipped = %d | ", Status);
-            *readIndex += Status;
-          }
-
-          pDescr++;
-        }
-        else
-        {
-          /* Has already been processed: */
-          return Status;
-        }
-
-        break;
-      }
-
-      case CSN_UNION_LH:
-      case CSN_UNION:
-      {
-        gint16           Bits;
-        guint8           index;
-        gint16           count      = pDescr->i;
-        const CSN_DESCR* pDescrNext = pDescr;
-
-        pDescrNext += count + 1; /* now this is next after the union */
-        if ((count <= 0) || (count > 16))
-        {
-          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
-        }
-
-        /* Now get the bits to extract the index */
-        Bits = ixBitsTab[count];
-        index = 0;
-
-        while (Bits > 0)
-        {
-          index <<= 1;
-
-          if (CSN_UNION_LH == pDescr->type)
-          {
-            index |= get_masked_bits8(vector, readIndex, bit_offset, 1);
-          }
-          else
-          {
-	    index |= bitvec_read_field(vector, readIndex, 1);
-          }
-          remaining_bits_len--;
-          bit_offset++;
-          Bits--;
-        }
-
-        /* Assign UnionType */
-        pui8  = pui8DATA(data, pDescr->offset);
-        *pui8 = index;
-
-
-        /* script index to continue on, limited in case we do not have a power of 2 */
-        pDescr += (MIN(index + 1, count));
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-
-        switch (pDescr->type)
-        { /* get the right element of the union based on computed index */
-
-          case CSN_BIT:
-          {
-            pui8  = pui8DATA(data, pDescr->offset);
-            *pui8 = 0x00;
-	    if (bitvec_read_field(vector, readIndex, 1) > 0)
-            {
-              *pui8 = 0x01;
-            }
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-            remaining_bits_len -= 1;
-            bit_offset++;
-            pDescr++;
-            break;
-          }
-
-          case CSN_NULL:
-          { /* Empty member! */
-            bit_offset += pDescr->i;
-            pDescr++;
-            break;
-          }
-
-          case CSN_UINT:
-          {
-            guint8 no_of_bits = (guint8) pDescr->i;
-            if (remaining_bits_len >= no_of_bits)
-            {
-              if (no_of_bits <= 8)
-              {
-		guint8 ui8 = bitvec_read_field(vector, readIndex,  no_of_bits);
-                pui8       = pui8DATA(data, pDescr->offset);
-                *pui8      = ui8;
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              }
-              else if (no_of_bits <= 16)
-              {
-		guint16 ui16 = bitvec_read_field(vector, readIndex,  no_of_bits);
-                pui16        = pui16DATA(data, pDescr->offset);
-                *pui16       = ui16;
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
-              }
-              else if (no_of_bits <= 32)
-              {
-		guint32 ui32 = bitvec_read_field(vector, readIndex,  no_of_bits);
-                pui32       = pui32DATA(data, pDescr->offset);
-                *pui32      = ui32;
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
-              }
-              else
-              {
-                return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
-              }
-            }
-            else
-            {
-              return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
-            }
-
-            remaining_bits_len -= no_of_bits;
-            bit_offset += no_of_bits;
-            pDescr++;
-            break;
-          }
-
-          case CSN_UINT_OFFSET:
-          {
-            guint8 no_of_bits = (guint8) pDescr->i;
-
-            if (remaining_bits_len >= no_of_bits)
-            {
-              if (no_of_bits <= 8)
-              {
-		guint8 ui8 = bitvec_read_field(vector, readIndex,  no_of_bits);
-                pui8      = pui8DATA(data, pDescr->offset);
-                *pui8     = ui8 + (guint8)pDescr->descr.value;
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              }
-              else if (no_of_bits <= 16)
-              {
-		guint16 ui16 = bitvec_read_field(vector, readIndex,  no_of_bits);
-                pui16       = pui16DATA(data, pDescr->offset);
-                *pui16      = ui16 + (guint16)pDescr->descr.value;
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
-              }
-              else if (no_of_bits <= 32)
-              {
-		guint32 ui32 = bitvec_read_field(vector, readIndex,  no_of_bits);
-                pui32       = pui32DATA(data, pDescr->offset);
-                *pui32      = ui32 + (guint16)pDescr->descr.value;
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
-              }
-              else
-              {
-                return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
-              }
-            }
-            else
-            {
-              return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-            }
-
-            remaining_bits_len -= no_of_bits;
-            bit_offset += no_of_bits;
-            pDescr++;
-            break;
-          }
-
-          case CSN_UINT_LH:
-          {
-            guint8 no_of_bits = (guint8) pDescr->i;
-
-            if (remaining_bits_len >= no_of_bits)
-            {
-              if (no_of_bits <= 8)
-              {
-		guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
-                pui8      = pui8DATA(data, pDescr->offset);
-                *pui8     = ui8;
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              }
-              else
-              { /* Maybe we should support more than 8 bits ? */
-                return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
-              }
-            }
-            else
-            {
-              return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-            }
-
-            remaining_bits_len -= no_of_bits;
-            bit_offset += no_of_bits;
-            pDescr++;
-            break;
-          }
-
-          case CSN_UINT_ARRAY:
-          {
-            guint8  no_of_bits  = (guint8) pDescr->i;
-            guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
-
-            if (pDescr->value != 0)
-            { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
-              nCount = *pui16DATA(data, nCount);
-            }
-
-            if (remaining_bits_len >= (no_of_bits * nCount))
-            {
-              remaining_bits_len -= (no_of_bits * nCount);
-              if (no_of_bits <= 8)
-              {
-                pui8 = pui8DATA(data, pDescr->offset);
-
-                while (nCount > 0)
-                {
-		  *pui8 = bitvec_read_field(vector, readIndex,  no_of_bits);
-                  LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-                  pui8++;
-                  bit_offset += no_of_bits;
-                  nCount--;
-                }
-              }
-              else if (no_of_bits <= 16)
-              {
-                pui16 = pui16DATA(data, pDescr->offset);
-
-                while (nCount > 0)
-                {
-		 *pui16 = bitvec_read_field(vector, readIndex,  no_of_bits);
-                  LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
-                  pui16++;
-                  bit_offset += no_of_bits;
-                  nCount--;
-                }
-              }
-              else if (no_of_bits <= 32)
-              { /* not supported */
-                return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
-              }
-              else
-              {
-                return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
-              }
-            }
-            else
-            {
-              return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-            }
-
-            pDescr++;
-            break;
-          }
-
-          case CSN_VARIABLE_TARRAY_OFFSET:
-          case CSN_VARIABLE_TARRAY:
-          case CSN_TYPE_ARRAY:
-          {
-            gint16      Status;
-            csnStream_t arT    = *ar;
-            guint16      nCount = (guint16) pDescr->i;
-            guint16      nSize  = (guint16)(guint32)pDescr->value;
-
-            pui8  = pui8DATA(data, pDescr->offset);
-
-            if (CSN_VARIABLE_TARRAY == pDescr->type)
-            { /* Count specified in field */
-              nCount = *pui8DATA(data, pDescr->i);
-            }
-            else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
-            { /* Count specified in field */
-              nCount = *pui8DATA(data, pDescr->i);
-              nCount--; /* Offset 1 */
-            }
-
-            while (nCount--)    /* Changed to handle length = 0.  */
-            {
-              LOGPC(DCSN1, LOGL_DEBUG, "%s | ", pDescr->sz);
-              csnStreamInit(&arT, bit_offset, remaining_bits_len);
-	      Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
-              if (Status >= 0)
-              {
-                pui8    += nSize;
-                remaining_bits_len = arT.remaining_bits_len;
-                bit_offset         = arT.bit_offset;
-              }
-              else
-              {
-                return Status;
-              }
-            }
-
-            pDescr++;
-            break;
-          }
-
-          case CSN_BITMAP:
-          { /* bitmap with given length. The result is left aligned! */
-            guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
-
-            if (no_of_bits > 0)
-            {
-              if (no_of_bits > remaining_bits_len)
-              {
-                return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-              }
-
-              if (no_of_bits <= 32)
-              {
-		guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
-                pui32       = pui32DATA(data, pDescr->offset);
-                *pui32      = ui32;
-              }
-              else if (no_of_bits <= 64)
-              {
-		guint64 ui64 = bitvec_read_field(vector, readIndex, no_of_bits);
-                pui64       = pui64DATA(data, pDescr->offset);
-                *pui64      = ui64;
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %lu | ", pDescr->sz , *pui64);
-              }
-              else
-              {
-              	return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
-              }
-
-              remaining_bits_len -= no_of_bits;
-              bit_offset += no_of_bits;
-            }
-            /* bitmap was successfully extracted or it was empty */
-
-            pDescr++;
-            break;
-          }
-
-          case CSN_TYPE:
-          {
-            gint16      Status;
-            csnStream_t arT = *ar;
-            LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
-            csnStreamInit(&arT, bit_offset, remaining_bits_len);
-	    Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
-            LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
-            if (Status >= 0)
-            {
-              remaining_bits_len = arT.remaining_bits_len;
-              bit_offset         = arT.bit_offset;
-              pDescr++;
-            }
-            else
-            { /* return error code Has already been processed:  */
-              return Status;
-            }
-
-            break;
-          }
-
-          default:
-          { /* descriptions of union elements other than above are illegal */
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
-          }
-        }
-
-        pDescr = pDescrNext;
-        break;
-      }
-
-      case CSN_EXIST:
-      case CSN_EXIST_LH:
-      {
-        guint8 fExist;
-
-        pui8  = pui8DATA(data, pDescr->offset);
-
-        if (CSN_EXIST_LH == pDescr->type)
-        {
-	  fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
-        }
-        else
-        {
-	  fExist = bitvec_read_field(vector, readIndex, 1);
-        }
-
-        *pui8 = fExist;
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-        pDescr++;
-        bit_offset++;
-        remaining_bits_len -= 1;
-
-        if (!fExist)
-        {
-          ar->remaining_bits_len  = remaining_bits_len;
-          ar->bit_offset          = bit_offset;
-          return remaining_bits_len;
-        }
-
-        break;
-      }
-
-      case CSN_NEXT_EXIST:
-      {
-        guint8 fExist;
-
-        pui8  = pui8DATA(data, pDescr->offset);
-
-        /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
-        if ((pDescr->may_be_null) && (remaining_bits_len == 0))
-        { /* no more bits to decode is fine here - end of message detected and allowed */
-
-          /* Skip i entries + this entry */
-          pDescr += pDescr->i + 1;
-
-          /* Set the data member to "not exist" */
-          *pui8 = 0;
-          break;
-        }
-
-        /* the "regular" M_NEXT_EXIST description element */
-
-        fExist = 0x00;
-	if (bitvec_read_field(vector, readIndex, 1))
-        {
-          fExist = 0x01;
-        }
-
-        *pui8     = fExist;
-        remaining_bits_len -= 1;
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-        ++bit_offset;
-
-        if (fExist == 0)
-        { /* Skip 'i' entries */
-          pDescr += pDescr->i;
-        }
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_NEXT_EXIST_LH:
-      {
-        guint8 fExist;
-        pui8  = pui8DATA(data, pDescr->offset);
-
-        /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
-        if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
-        { /* no more bits to decode is fine here - end of message detected and allowed */
-
-          /* skip 'i' entries + this entry */
-          pDescr += pDescr->i + 1;
-
-          /* set the data member to "not exist" */
-          *pui8 = 0;
-          break;
-        }
-
-        /* the "regular" M_NEXT_EXIST_LH description element */
-        fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)fExist);
-        *pui8++   = fExist;
-        remaining_bits_len -= 1;
-
-        bit_offset++;
-
-        if (fExist == 0)
-        { /* Skip 'i' entries */
-          pDescr += pDescr->i;
-        }
-        pDescr++;
-
-        break;
-      }
-
-      case CSN_VARIABLE_BITMAP_1:
-      { /* Bitmap from here and to the end of message */
-
-        *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
-
-        /*no break -
-         * with a length set we have a regular variable length bitmap so we continue */
-      }
-      /* FALL THROUGH */
-      case CSN_VARIABLE_BITMAP:
-      { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
-         * <N: bit (5)> <bitmap: bit(N + offset)>
-         * Bit array with length (in bits) specified in parameter (pDescr->descr)
-         * The result is right aligned!
-         */
-        gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
-
-        no_of_bits += pDescr->i; /* adjusted by offset */
-
-        if (no_of_bits > 0)
-        {
-          remaining_bits_len -= no_of_bits;
-
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-          { /* extract bits */
-            guint8* pui8 = pui8DATA(data, pDescr->offset);
-            gint16 nB1  = no_of_bits & 0x07;/* no_of_bits Mod 8 */
-
-            if (nB1 > 0)
-            { /* take care of the first byte - it will be right aligned */
-	      *pui8 = bitvec_read_field(vector, readIndex, nB1);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              pui8++;
-              no_of_bits  -= nB1;
-              bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
-            }
-
-            /* remaining no_of_bits is a multiple of 8 or 0 */
-            while (no_of_bits > 0)
-            {
-	      *pui8 = bitvec_read_field(vector, readIndex, 8);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              pui8++;
-              no_of_bits -= 8;
-            }
-          }
-        }
-        pDescr++;
-        break;
-      }
-
-      case CSN_LEFT_ALIGNED_VAR_BMP_1:
-      { /* Bitmap from here and to the end of message */
-
-        *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
-
-        /* no break -
-         * with a length set we have a regular left aligned variable length bitmap so we continue
-         */
-      }
-      /* FALL THROUGH */
-      case CSN_LEFT_ALIGNED_VAR_BMP:
-      { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
-         * <N: bit (5)> <bitmap: bit(N + offset)>
-         * bit array with length (in bits) specified in parameter (pDescr->descr)
-         */
-        gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
-
-        no_of_bits += pDescr->i;/* size adjusted by offset */
-
-        if (no_of_bits > 0)
-        {
-          remaining_bits_len -= no_of_bits;
-
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-          { /* extract bits */
-            guint8* pui8 = pui8DATA(data, pDescr->offset);
-
-            while (no_of_bits >= 8)
-            {
-	      *pui8 = bitvec_read_field(vector, readIndex, 8);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              pui8++;
-              no_of_bits -= 8;
-            }
-            if (no_of_bits > 0)
-            {
-	      *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              pui8++;
-              bit_offset += no_of_bits;
-              no_of_bits = 0;
-            }
-          }
-        }
-
-        /* bitmap was successfully extracted or it was empty */
-        pDescr++;
-        break;
-      }
-
-      case CSN_PADDING_BITS:
-      { /* Padding from here and to the end of message */
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = ", pDescr->sz);
-        if (remaining_bits_len > 0)
-        {
-          while (remaining_bits_len > 0)
-          {
-            guint bits_to_handle = remaining_bits_len%8;
-            if (bits_to_handle > 0)
-            {
-              LOGPC(DCSN1, LOGL_DEBUG, "%d|", bitvec_get_uint(vector, bits_to_handle));
-              remaining_bits_len -= bits_to_handle;
-              bit_offset += bits_to_handle;
-            }
-            else if (bits_to_handle == 0)
-            {
-              LOGPC(DCSN1, LOGL_DEBUG, "%d|", bitvec_get_uint(vector, 8));
-              remaining_bits_len -= 8;
-              bit_offset += 8;
-            }
-          }
-        }
-        if (remaining_bits_len < 0)
-        {
-          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-
-        /* Padding was successfully extracted or it was empty */
-        pDescr++;
-        break;
-      }
-
-      case CSN_VARIABLE_ARRAY:
-      { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
-         * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
-         * Array with length specified in parameter:
-         *  <count: bit (x)>
-         *  <list: octet(count + offset)>
-         */
-        gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
-
-        count += pDescr->i; /* Adjusted by offset */
-
-        if (count > 0)
-        {
-          remaining_bits_len -= count * 8;
-
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-          pui8 = pui8DATA(data, pDescr->offset);
-
-          while (count > 0)
-          {
-	    *pui8 = bitvec_read_field(vector, readIndex, 8);
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = 0x%x | ", pDescr->sz , (unsigned)*pui8);
-            pui8++;
-            bit_offset += 8;
-            count--;
-          }
-        }
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_RECURSIVE_ARRAY:
-      { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
-         *  or more generally:                <list> ::= { <tag> <element> <list> | <EndTag> }
-         *  where <element> ::= bit(value)
-         *        <tag>     ::= 0 | 1
-         *        <EndTag>  ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
-         * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
-         * REMARK: recursive way to specify an array but an iterative implementation!
-         */
-        gint16 no_of_bits        = pDescr->i;
-        guint8  ElementCount = 0;
-
-        pui8  = pui8DATA(data, pDescr->offset);
-
-	while (existNextElement(vector, readIndex, Tag))
-        { /* tag control shows existence of next list elements */
-          LOGPC(DCSN1, LOGL_DEBUG, "%s = Exist | ", pDescr->sz);
-          bit_offset++;
-          remaining_bits_len--;
-
-          /* extract and store no_of_bits long element from bitstream */
-	  *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
-          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-          pui8++;
-          remaining_bits_len -= no_of_bits;
-          ElementCount++;
-
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-          bit_offset += no_of_bits;
-        }
-
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
-        /* existNextElement() returned FALSE, 1 bit consumed */
-        bit_offset++;
-        remaining_bits_len--;
-
-        /* Store the counted number of elements of the array */
-        *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_RECURSIVE_TARRAY:
-      { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
-         *  M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
-         * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE), (void_fn_t)ElementsOf(((_STRUCT*)0)->_MEMBER)}
-         */
-        gint16 nSizeElement = (gint16)(gint32)pDescr->value;
-        guint32 nSizeArray = (guint32)((uintptr_t)pDescr->aux_fn);
-        guint8  ElementCount = 0;
-        pui8  = pui8DATA(data, pDescr->offset);
-
-	while (existNextElement(vector, readIndex, Tag))
-        { /* tag control shows existence of next list elements */
-          LOGPC(DCSN1, LOGL_DEBUG, "%s = Exist | ", pDescr->sz);
-          /* existNextElement() returned TRUE, 1 bit consumed */
-          bit_offset++;
-          remaining_bits_len--;
-          ElementCount++;
-
-          if (ElementCount > nSizeArray)
-          {
-            LOGPC(DCSN1, LOGL_ERROR, "error: %s: too many elements (>%u) in recursive array. Increase its size! } |", pDescr->sz, nSizeArray);
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
-          }
-
-          { /* unpack the following data structure */
-            csnStream_t arT = *ar;
-            gint16      Status;
-            csnStreamInit(&arT, bit_offset, remaining_bits_len);
-	    Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
-
-            if (Status >= 0)
-            { /* successful completion */
-              pui8    += nSizeElement;  /* -> to next data element */
-              remaining_bits_len = arT.remaining_bits_len;
-              bit_offset         = arT.bit_offset;
-            }
-            else
-            { /* something went awry */
-              return Status;
-            }
-          }
-
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-        }
-
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
-
-        /* existNextElement() returned FALSE, 1 bit consumed */
-        remaining_bits_len--;
-        bit_offset++;
-
-        /* Store the counted number of elements of the array */
-        *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_RECURSIVE_TARRAY_2:
-      { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
-
-        Tag = REVERSED_TAG;
-
-        /* NO break -
-         * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
-         */
-      }
-      /* FALL THROUGH */
-      case CSN_RECURSIVE_TARRAY_1:
-      { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
-         * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
-         * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE), (void_fn_t)ElementsOf(((_STRUCT*)0)->_MEMBER)}
-         */
-        gint16      nSizeElement = (gint16)(gint32)pDescr->value;
-        guint32     nSizeArray = (guint32)((uintptr_t)pDescr->aux_fn);
-        guint8       ElementCount = 0;
-        csnStream_t arT          = *ar;
-        gboolean     EndOfList    = FALSE;
-        gint16      Status;
-        pui8  = pui8DATA(data, pDescr->offset);
-
-        do
-        { /* get data element */
-          ElementCount++;
-
-          if (ElementCount > nSizeArray)
-          {
-            LOGPC(DCSN1, LOGL_ERROR, "error: %s: too many elements (>%u) in recursive array. Increase its size! } |", pDescr->sz, nSizeArray);
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
-          }
-
-          LOGPC(DCSN1, LOGL_DEBUG, "%s { | ", pDescr->sz);
-
-          csnStreamInit(&arT, bit_offset, remaining_bits_len);
-	  Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
-
-          if (Status >= 0)
-          { /* successful completion */
-            pui8    += nSizeElement;  /* -> to next */
-            remaining_bits_len = arT.remaining_bits_len;
-            bit_offset         = arT.bit_offset;
-          }
-          else
-          { /* something went awry */
-            return Status;
-          }
-
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-          /* control of next element's tag */
-          LOGPC(DCSN1, LOGL_DEBUG, "%s } | ", pDescr->sz);
-	  EndOfList         = !(existNextElement(vector, readIndex, Tag));
-
-          bit_offset++;
-          remaining_bits_len--; /* 1 bit consumed (tag) */
-        } while (!EndOfList);
-
-
-        /* Store the count of the array */
-        *pui8DATA(data, pDescr->i) = ElementCount;
-        Tag = STANDARD_TAG; /* in case it was set to "reversed" */
-        pDescr++;
-        break;
-      }
-
-      case CSN_FIXED:
-      { /* Verify the fixed bits */
-        guint8  no_of_bits = (guint8) pDescr->i;
-        guint32 ui32;
-
-        if (no_of_bits <= 32)
-        {
-	  ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
-        }
-        else
-        {
-          return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
-        }
-        if (ui32 != (unsigned)(gint32)pDescr->offset)
-        {
-          return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
-        }
-
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)ui32);
-        remaining_bits_len   -= no_of_bits;
-        bit_offset += no_of_bits;
-        pDescr++;
-        break;
-      }
-
-      case CSN_CALLBACK:
-      {
-        guint16  no_of_bits;
-        DissectorCallbackFcn_t callback = (DissectorCallbackFcn_t)pDescr->aux_fn;
-        LOGPC(DCSN1, LOGL_DEBUG, "CSN_CALLBACK(%s) | ", pDescr->sz);
-        no_of_bits = callback(vector, readIndex, pvDATA(data, pDescr->i), pvDATA(data, pDescr->offset));
-        remaining_bits_len -= no_of_bits;
-        bit_offset += no_of_bits;
-        pDescr++;
-        break;
-      }
-
-      case CSN_TRAP_ERROR:
-      {
-        return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
-      }
-
-      case CSN_END:
-      {
-        ar->remaining_bits_len  = remaining_bits_len;
-        ar->bit_offset = bit_offset;
-        return remaining_bits_len;
-      }
-
-      default:
-      {
-        assert(0);
-      }
-
-
-    }
-
-  } while (remaining_bits_len >= 0);
-
-  return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-}
-
-
-
-
-gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector, unsigned *writeIndex, void* data)
-{
-  gint  remaining_bits_len = ar->remaining_bits_len;
-  gint  bit_offset         = ar->bit_offset;
-  guint8*  pui8;
-  guint16* pui16;
-  guint32* pui32;
-  guint64* pui64;
-  unsigned ib;
-
-  guint8 Tag = STANDARD_TAG;
-
-  if (remaining_bits_len < 0)
-  {
-    return ProcessError(writeIndex, __func__, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-  }
-
-  do
-  {
-    switch (pDescr->type)
-    {
-      case CSN_BIT:
-      {
-        if (remaining_bits_len > 0)
-        {
-          pui8  = pui8DATA(data, pDescr->offset);
-	  bitvec_write_field(vector, writeIndex, *pui8, 1);
-          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-          /* end add the bit value to protocol tree */
-        }
-        else if (pDescr->may_be_null)
-        {
-           LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
-        }
-        else
-        {
-          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-
-        pDescr++;
-        remaining_bits_len--;
-        bit_offset++;
-        break;
-      }
-
-      case CSN_NULL:
-      { /* Empty member! */
-        pDescr++;
-        break;
-      }
-
-      case CSN_UINT:
-      {
-        guint8 no_of_bits = (guint8) pDescr->i;
-
-        if (remaining_bits_len >= no_of_bits)
-        {
-          if (no_of_bits <= 8)
-          {
-            pui8      = pui8DATA(data, pDescr->offset);
-	    bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-          }
-          else if (no_of_bits <= 16)
-          {
-            pui16       = pui16DATA(data, pDescr->offset);
-	    bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
-          }
-          else if (no_of_bits <= 32)
-          {
-            pui32       = pui32DATA(data, pDescr->offset);
-	    bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
-          }
-          else
-          {
-            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
-          }
-
-          remaining_bits_len -= no_of_bits;
-          bit_offset += no_of_bits;
-        }
-        else if (pDescr->may_be_null)
-        {
-          LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
-        }
-        else
-        {
-          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_UINT_OFFSET:
-      {
-        guint8 no_of_bits = (guint8) pDescr->i;
-
-        if (remaining_bits_len >= no_of_bits)
-        {
-          if (no_of_bits <= 8)
-          {
-            pui8      = pui8DATA(data, pDescr->offset);
-	    bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
-          }
-          else if (no_of_bits <= 16)
-          {
-            pui16       = pui16DATA(data, pDescr->offset);
-	    bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
-          }
-          else if (no_of_bits <= 32)
-          {
-            pui32       = pui32DATA(data, pDescr->offset);
-	    bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
-          }
-          else
-          {
-            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
-          }
-        }
-        else
-        {
-          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-
-        remaining_bits_len -= no_of_bits;
-        bit_offset += no_of_bits;
-        pDescr++;
-        break;
-      }
-
-      case CSN_UINT_LH:
-      {
-        guint8 no_of_bits = (guint8) pDescr->i;
-
-        if (remaining_bits_len >= no_of_bits)
-        {
-          if (no_of_bits <= 8)
-          {
-            pui8      = pui8DATA(data, pDescr->offset);
-	    bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
-            // TODO : Change get_masked_bits8()
-            *writeIndex -= no_of_bits;
-            guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
-            *writeIndex -= no_of_bits;
-	    bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-
-          }
-          else
-          {/* Maybe we should support more than 8 bits ? */
-            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
-          }
-        }
-        else
-        {
-          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-
-        remaining_bits_len -= no_of_bits;
-        bit_offset += no_of_bits;
-        pDescr++;
-        break;
-      }
-
-      case CSN_UINT_ARRAY:
-      {
-        guint8  no_of_bits  = (guint8) pDescr->i;
-        guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
-
-        if (pDescr->value != 0)
-        { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
-          nCount = *pui16DATA(data, nCount);
-        }
-
-        if (remaining_bits_len >= (no_of_bits * nCount))
-        {
-          if (no_of_bits <= 8)
-          {
-            pui8 = pui8DATA(data, pDescr->offset);
-            do
-            {
-	      bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              pui8++;
-              remaining_bits_len -= no_of_bits;
-              bit_offset += no_of_bits;
-            } while (--nCount > 0);
-          }
-          else if (no_of_bits <= 16)
-          {
-            return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
-          }
-          else if (no_of_bits <= 32)
-          {
-            return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
-          }
-          else
-          {
-            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
-          }
-        }
-        else
-        {
-          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-        pDescr++;
-        break;
-      }
-
-      case CSN_VARIABLE_TARRAY_OFFSET:
-      case CSN_VARIABLE_TARRAY:
-      case CSN_TYPE_ARRAY:
-      {
-        gint16      Status;
-        csnStream_t arT    = *ar;
-        gint16      nCount = pDescr->i;
-        guint16     nSize  = (guint16)(gint32)pDescr->value;
-
-        pui8 = pui8DATA(data, pDescr->offset);
-        if (pDescr->type == CSN_VARIABLE_TARRAY)
-        { /* Count specified in field */
-          nCount = *pui8DATA(data, pDescr->i);
-        }
-        else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
-        { /* Count specified in field */
-          nCount = *pui8DATA(data, pDescr->i);
-	  /*  nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
-        }
-
-        while (nCount > 0)
-        { /* resulting array of length 0 is possible
-           * but no bits shall be read from bitstream
-           */
-
-          LOGPC(DCSN1, LOGL_DEBUG, "%s : | ", pDescr->sz);
-          csnStreamInit(&arT, bit_offset, remaining_bits_len);
-          Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
-          if (Status >= 0)
-          {
-            pui8    += nSize;
-            remaining_bits_len = arT.remaining_bits_len;
-            bit_offset         = arT.bit_offset;
-
-          }
-          else
-          {
-            return Status;
-          }
-          nCount--;
-        }
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_BITMAP:
-      { /* bitmap with given length. The result is left aligned! */
-        guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
-
-        if (no_of_bits > 0)
-        {
-          if (no_of_bits > remaining_bits_len)
-          {
-            return ProcessError(writeIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-          if (no_of_bits <= 32)
-          {
-            for(ib = 0; ib < 4; ib++)
-            {
-              pui8      = pui8DATA(data, pDescr->offset+ib);
-	      bitvec_write_field(vector, writeIndex, *pui8, 8);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
-            }
-          }
-          else if (no_of_bits <= 64)
-          {
-            for(ib = 0; ib < 8; ib++)
-            {
-              pui8      = pui8DATA(data, pDescr->offset+ib);
-	      bitvec_write_field(vector, writeIndex, *pui8, 8);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
-            }
-          }
-          else
-          {
-          	return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
-          }
-
-          remaining_bits_len -= no_of_bits;
-          bit_offset += no_of_bits;
-        }
-        /* bitmap was successfully extracted or it was empty */
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_TYPE:
-      {
-        gint16      Status;
-        csnStream_t arT = *ar;
-        LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
-        csnStreamInit(&arT, bit_offset, remaining_bits_len);
-        Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
-        LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
-        if (Status >= 0)
-        {
-
-          remaining_bits_len  = arT.remaining_bits_len;
-          bit_offset          = arT.bit_offset;
-          pDescr++;
-        }
-        else
-        {
-          /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr);  */
-          return Status;
-        }
-
-        break;
-      }
-
-      case CSN_CHOICE:
-      {
-        gint16 count = pDescr->i;
-        const CSN_ChoiceElement_t* pChoice = (const CSN_ChoiceElement_t*) pDescr->descr.ptr;
-
-        /* Make sure that the list of choice items is not empty */
-        if (!count)
-          return ProcessError(writeIndex, "csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
-        else if (count > 255) /* We can handle up to 256 (UCHAR_MAX) selectors */
-          return ProcessError(writeIndex, "csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
-
-        /* Make sure that choice index is not out of range */
-        pui8 = pui8DATA(data, pDescr->offset);
-        if (*pui8 >= count)
-          return ProcessError(writeIndex, "csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
-
-        pChoice += *pui8;
-        guint8 no_of_bits = pChoice->bits;
-        guint8 value = pChoice->value;
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
-	bitvec_write_field(vector, writeIndex, value, no_of_bits);
-
-        CSN_DESCR   descr[2];
-        gint16      Status;
-        csnStream_t arT = *ar;
-
-        descr[0]      = pChoice->descr;
-        memset(&descr[1], 0x00, sizeof(CSN_DESCR));
-        descr[1].type = CSN_END;
-        bit_offset += no_of_bits;
-        remaining_bits_len -= no_of_bits;
-
-        csnStreamInit(&arT, bit_offset, remaining_bits_len);
-        Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
-
-        if (Status >= 0)
-        {
-          remaining_bits_len = arT.remaining_bits_len;
-          bit_offset         = arT.bit_offset;
-        }
-        else
-        {
-          return Status;
-        }
-
-        pDescr++;
-        break;
-      }
-
-   case CSN_SERIALIZE:
-      {
-        StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
-        csnStream_t          arT       = *ar;
-        guint8 length_len              = pDescr->i;
-        gint16               Status = -1;
-        unsigned lengthIndex;
-
-        // store writeIndex for length value (7 bit)
-        lengthIndex = *writeIndex;
-        *writeIndex += length_len;
-        bit_offset += length_len;
-        remaining_bits_len -= length_len;
-        arT.direction = 0;
-        csnStreamInit(&arT, bit_offset, remaining_bits_len);
-        Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
-
-	bitvec_write_field(vector, &lengthIndex, *writeIndex - lengthIndex - length_len, length_len);
-        LOGPC(DCSN1, LOGL_DEBUG, "%s length = %u | ", pDescr->sz , (unsigned)(*writeIndex - lengthIndex));
-
-        if (Status >= 0)
-        {
-          remaining_bits_len = arT.remaining_bits_len;
-          bit_offset         = arT.bit_offset;
-          pDescr++;
-        }
-        else
-        {
-          // Has already been processed:
-          return Status;
-        }
-
-        break;
-      }
-
-      case CSN_UNION_LH:
-      case CSN_UNION:
-      {
-        gint16           Bits;
-        guint8           index;
-        gint16           count      = pDescr->i;
-        const CSN_DESCR* pDescrNext = pDescr;
-
-        pDescrNext += count + 1; /* now this is next after the union */
-        if ((count <= 0) || (count > 16))
-        {
-          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
-        }
-
-        /* Now get the bits to extract the index */
-        Bits = ixBitsTab[count];
-        index = 0;
-
-        /* Assign UnionType */
-        pui8  = pui8DATA(data, pDescr->offset);
-	//read index from data and write to vector
-	bitvec_write_field(vector, writeIndex, *pui8, Bits);
-
-	//decode index
-        *writeIndex -= Bits;
-
-        while (Bits > 0)
-        {
-          index <<= 1;
-
-          if (CSN_UNION_LH == pDescr->type)
-          {
-            index |= get_masked_bits8(vector, writeIndex, bit_offset, 1);
-          }
-          else
-          {
-	    index |= bitvec_read_field(vector, writeIndex, 1);
-          }
-
-          remaining_bits_len--;
-          bit_offset++;
-          Bits--;
-        }
-
-        *writeIndex -= Bits;
-	bitvec_write_field(vector, writeIndex, index, Bits);
-
-
-        /* script index to continue on, limited in case we do not have a power of 2 */
-        pDescr += (MIN(index + 1, count));
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)index);
-
-        switch (pDescr->type)
-        { /* get the right element of the union based on computed index */
-
-          case CSN_BIT:
-          {
-            pui8  = pui8DATA(data, pDescr->offset);
-	    bitvec_write_field(vector, writeIndex, *pui8, 1);
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-            remaining_bits_len--;
-            bit_offset++;
-            pDescr++;
-            break;
-          }
-
-          case CSN_NULL:
-          { /* Empty member! */
-            pDescr++;
-            break;
-          }
-
-          case CSN_UINT:
-          {
-            guint8 no_of_bits = (guint8) pDescr->i;
-            if (remaining_bits_len >= no_of_bits)
-            {
-              if (no_of_bits <= 8)
-              {
-                pui8      = pui8DATA(data, pDescr->offset);
-		bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              }
-              else if (no_of_bits <= 16)
-              {
-                pui16       = pui16DATA(data, pDescr->offset);
-		bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
-              }
-              else if (no_of_bits <= 32)
-              {
-                pui32       = pui32DATA(data, pDescr->offset);
-		bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
-              }
-              else
-              {
-                return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
-              }
-            }
-            else
-            {
-              return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
-            }
-
-            remaining_bits_len -= no_of_bits;
-            bit_offset += no_of_bits;
-            pDescr++;
-            break;
-          }
-
-          case CSN_UINT_OFFSET:
-          {
-            guint8 no_of_bits = (guint8) pDescr->i;
-
-            if (remaining_bits_len >= no_of_bits)
-            {
-              if (no_of_bits <= 8)
-              {
-                pui8      = pui8DATA(data, pDescr->offset);
-		bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
-              }
-              else if (no_of_bits <= 16)
-              {
-                pui16       = pui16DATA(data, pDescr->offset);
-		bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
-              }
-              else if (no_of_bits <= 32)
-              {
-                pui32       = pui32DATA(data, pDescr->offset);
-		bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
-              }
-              else
-              {
-                return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
-              }
-            }
-            else
-            {
-              return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-            }
-
-            remaining_bits_len -= no_of_bits;
-            bit_offset += no_of_bits;
-            pDescr++;
-            break;
-          }
-
-          case CSN_UINT_LH:
-          {
-            guint8 no_of_bits = (guint8) pDescr->i;
-
-            if (remaining_bits_len >= no_of_bits)
-            {
-              remaining_bits_len -= no_of_bits;
-              if (no_of_bits <= 8)
-              {
-                pui8      = pui8DATA(data, pDescr->offset);
-		bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
-                // TODO : Change get_masked_bits8()
-                *writeIndex -= no_of_bits;
-                guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
-                *writeIndex -= no_of_bits;
-		bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-
-              }
-              else
-              {/* Maybe we should support more than 8 bits ? */
-                return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
-              }
-            }
-            else
-            {
-              return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-            }
-
-            remaining_bits_len -= no_of_bits;
-            bit_offset += no_of_bits;
-            pDescr++;
-            break;
-          }
-
-          case CSN_UINT_ARRAY:
-          {
-            guint8  no_of_bits  = (guint8) pDescr->i;
-            guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
-
-            if (pDescr->value != 0)
-            { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
-              nCount = *pui16DATA(data, nCount);
-            }
-
-            if (remaining_bits_len >= (no_of_bits * nCount))
-            {
-              if (no_of_bits <= 8)
-              {
-                pui8 = pui8DATA(data, pDescr->offset);
-                do
-                {
-		  bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
-                  LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-                  pui8++;
-                  remaining_bits_len -= no_of_bits;
-                  bit_offset += no_of_bits;
-                } while (--nCount > 0);
-              }
-              else if (no_of_bits <= 16)
-              {
-                return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
-              }
-              else if (no_of_bits <= 32)
-              {
-                return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
-              }
-              else
-              {
-                return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
-              }
-            }
-            else
-            {
-              return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-            }
-            pDescr++;
-            break;
-          }
-
-          case CSN_VARIABLE_TARRAY_OFFSET:
-          case CSN_VARIABLE_TARRAY:
-          case CSN_TYPE_ARRAY:
-          {
-            gint16      Status;
-            csnStream_t arT    = *ar;
-            gint16      nCount = pDescr->i;
-            guint16     nSize  = (guint16)(gint32)pDescr->value;
-
-            pui8 = pui8DATA(data, pDescr->offset);
-            if (pDescr->type == CSN_VARIABLE_TARRAY)
-            { /* Count specified in field */
-              nCount = *pui8DATA(data, pDescr->i);
-            }
-            else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
-            { /* Count specified in field */
-              nCount = *pui8DATA(data, pDescr->i);
-              /*  nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
-            }
-
-            while (nCount > 0)
-            { /* resulting array of length 0 is possible
-               * but no bits shall be read from bitstream
-               */
-
-              LOGPC(DCSN1, LOGL_DEBUG, "%s : | ", pDescr->sz);
-              csnStreamInit(&arT, bit_offset, remaining_bits_len);
-              Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
-              if (Status >= 0)
-              {
-                pui8    += nSize;
-                remaining_bits_len = arT.remaining_bits_len;
-                bit_offset         = arT.bit_offset;
-              }
-              else
-              {
-                return Status;
-              }
-              nCount--;
-            }
-
-            pDescr++;
-            break;
-          }
-
-          case CSN_BITMAP:
-          { /* bitmap with given length. The result is left aligned! */
-            guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
-
-            if (no_of_bits > 0)
-            {
-              if (no_of_bits > remaining_bits_len)
-              {
-                return ProcessError(writeIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-              }
-
-              if (no_of_bits <= 32)
-              {
-                pui32 = pui32DATA(data, pDescr->offset);
-		bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
-              }
-              else if (no_of_bits <= 64)
-              {
-                pui64 = pui64DATA(data, pDescr->offset);
-		bitvec_write_field(vector, writeIndex, *pui64, no_of_bits);
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %lu | ", pDescr->sz , *pui64);
-              }
-              else
-              {
-              	return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
-              }
-
-              remaining_bits_len -= no_of_bits;
-              bit_offset += no_of_bits;
-            }
-            /* bitmap was successfully extracted or it was empty */
-
-            pDescr++;
-            break;
-          }
-
-          case CSN_TYPE:
-          {
-            gint16      Status;
-            csnStream_t arT = *ar;
-            LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
-            csnStreamInit(&arT, bit_offset, remaining_bits_len);
-            Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
-            LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
-            if (Status >= 0)
-            {
-              remaining_bits_len  = arT.remaining_bits_len;
-              bit_offset          = arT.bit_offset;
-              pDescr++;
-            }
-            else
-            {
-              /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr);  */
-              return Status;
-            }
-
-            break;
-          }
-
-          default:
-          { /* descriptions of union elements other than above are illegal */
-            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
-          }
-        }
-
-        pDescr = pDescrNext;
-        break;
-      }
-
-      case CSN_EXIST:
-      case CSN_EXIST_LH:
-      {
-        guint8 fExist;
-        unsigned exist = 0;
-        pui8  = pui8DATA(data, pDescr->offset);
-        exist = *pui8;
-	bitvec_write_field(vector, writeIndex, *pui8, 1);
-        writeIndex--;
-        if (CSN_EXIST_LH == pDescr->type)
-        {
-          fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
-        }
-        else
-        {
-	  fExist = bitvec_read_field(vector, writeIndex, 1);
-        }
-        writeIndex--;
-	bitvec_write_field(vector, writeIndex, fExist, 1);
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz, (unsigned)fExist);
-        remaining_bits_len--;
-        bit_offset++;
-        pDescr++;
-
-        if (!exist)
-        {
-          ar->remaining_bits_len  = remaining_bits_len;
-          ar->bit_offset          = bit_offset;
-          return remaining_bits_len;
-        }
-        break;
-      }
-
-      case CSN_NEXT_EXIST:
-      {
-        guint8 fExist;
-
-        pui8  = pui8DATA(data, pDescr->offset);
-
-        /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
-        if ((pDescr->may_be_null) && (remaining_bits_len == 0))
-        { /* no more bits to decode is fine here - end of message detected and allowed */
-
-          /* Skip i entries + this entry */
-          pDescr += pDescr->i + 1;
-
-          break;
-        }
-
-	bitvec_write_field(vector, writeIndex, *pui8, 1);
-        fExist = *pui8;
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-
-        remaining_bits_len--;
-        bit_offset++;
-
-        if (fExist == 0)
-        { /* Skip 'i' entries */
-          pDescr += pDescr->i;
-        }
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_NEXT_EXIST_LH:
-      {
-        guint8 fExist;
-        pui8  = pui8DATA(data, pDescr->offset);
-
-        /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
-        if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
-        { /* no more bits to decode is fine here - end of message detected and allowed */
-
-          /* skip 'i' entries + this entry */
-          pDescr += pDescr->i + 1;
-
-          /* set the data member to "not exist" */
-          //*pui8 = 0;
-          break;
-        }
-
-        /* the "regular" M_NEXT_EXIST_LH description element */
-	bitvec_write_field(vector, writeIndex, *pui8, 1);
-        writeIndex--;
-        fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
-        writeIndex--;
-	bitvec_write_field(vector, writeIndex, fExist, 1);
-        pui8++;
-
-        remaining_bits_len--;
-        bit_offset++;
-
-        if (fExist == 0)
-        { /* Skip 'i' entries */
-          pDescr += pDescr->i;
-        }
-        pDescr++;
-
-        break;
-      }
-
-      case CSN_VARIABLE_BITMAP_1:
-      { /* Bitmap from here and to the end of message */
-
-        //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
-
-        /*no break -
-         * with a length set we have a regular variable length bitmap so we continue */
-      }
-      /* FALL THROUGH */
-      case CSN_VARIABLE_BITMAP:
-      { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
-         * <N: bit (5)> <bitmap: bit(N + offset)>
-         * Bit array with length (in bits) specified in parameter (pDescr->descr)
-         * The result is right aligned!
-         */
-        gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
-
-        no_of_bits += pDescr->i; /* adjusted by offset */
-
-        if (no_of_bits > 0)
-        {
-
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-          { /* extract bits */
-            guint8* pui8 = pui8DATA(data, pDescr->offset);
-            gint16 nB1  = no_of_bits & 0x07;/* no_of_bits Mod 8 */
-
-            if (nB1 > 0)
-            { /* take care of the first byte - it will be right aligned */
-	      bitvec_write_field(vector, writeIndex, *pui8, nB1);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              pui8++;
-              no_of_bits  -= nB1;
-              bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
-              remaining_bits_len -= nB1;
-            }
-
-            /* remaining no_of_bits is a multiple of 8 or 0 */
-            while (no_of_bits > 0)
-            {
-	      bitvec_write_field(vector, writeIndex, *pui8, 8);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              pui8++;
-              no_of_bits -= 8;
-              remaining_bits_len -= 8;
-            }
-          }
-        }
-        pDescr++;
-        break;
-      }
-
-      case CSN_LEFT_ALIGNED_VAR_BMP_1:
-      { /* Bitmap from here and to the end of message */
-
-        //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
-
-        /* no break -
-         * with a length set we have a regular left aligned variable length bitmap so we continue
-         */
-      }
-      /* FALL THROUGH */
-      case CSN_LEFT_ALIGNED_VAR_BMP:
-      { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
-         * <N: bit (5)> <bitmap: bit(N + offset)>
-         * bit array with length (in bits) specified in parameter (pDescr->descr)
-         */
-
-        gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
-
-        no_of_bits += pDescr->i;/* size adjusted by offset */
-
-        if (no_of_bits > 0)
-        {
-          remaining_bits_len -= no_of_bits;
-
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-          { /* extract bits */
-            guint8* pui8 = pui8DATA(data, pDescr->offset);
-            gint16 nB1  = no_of_bits & 0x07;/* no_of_bits Mod 8 */
-
-            while (no_of_bits > 0)
-            {
-	      bitvec_write_field(vector, writeIndex, *pui8, 8);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              pui8++;
-              no_of_bits -= 8;
-            }
-            if (nB1 > 0)
-            {
-	      bitvec_write_field(vector, writeIndex, *pui8, nB1);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              pui8++;
-              no_of_bits  -= nB1;
-              bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
-            }
-          }
-
-        }
-
-        /* bitmap was successfully extracted or it was empty */
-        pDescr++;
-        break;
-      }
-
-      case CSN_PADDING_BITS:
-      { /* Padding from here and to the end of message */
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = ", pDescr->sz);
-        guint8 filler = 0x2b;
-        if (remaining_bits_len > 0)
-        {
-          while (remaining_bits_len > 0)
-          {
-            guint8 bits_to_handle = remaining_bits_len%8;
-            if (bits_to_handle > 0)
-            {
-              /* section 11 of 44.060
-               * The padding bits may be the 'null' string. Otherwise, the
-               * padding bits starts with bit '0', followed by 'spare padding'
-               * < padding bits > ::= { null | 0 < spare padding > ! < Ignore : 1 bit** = < no string > > } ;
-              */
-              guint8 fl = filler&(0xff>>(8-bits_to_handle + 1));
-	      bitvec_write_field(vector, writeIndex, fl, bits_to_handle);
-              LOGPC(DCSN1, LOGL_DEBUG, "%u|", fl);
-              remaining_bits_len -= bits_to_handle;
-              bit_offset += bits_to_handle;
-            }
-            else if (bits_to_handle == 0)
-            {
-	      bitvec_write_field(vector, writeIndex, filler, 8);
-              LOGPC(DCSN1, LOGL_DEBUG, "%u|", filler);
-              remaining_bits_len -= 8;
-              bit_offset += 8;
-            }
-          }
-        }
-        if (remaining_bits_len < 0)
-        {
-          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-
-        /* Padding was successfully extracted or it was empty */
-        pDescr++;
-        break;
-      }
-
-      case CSN_VARIABLE_ARRAY:
-      { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
-         * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
-         * Array with length specified in parameter:
-         *  <count: bit (x)>
-         *  <list: octet(count + offset)>
-         */
-        gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
-
-        count += pDescr->i; /* Adjusted by offset */
-
-        if (count > 0)
-        {
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-          pui8 = pui8DATA(data, pDescr->offset);
-
-          while (count > 0)
-          {
-	    bitvec_write_field(vector, writeIndex, *pui8, 8);
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = 0x%x | ", pDescr->sz , (unsigned)*pui8);
-            pui8++;
-            bit_offset += 8;
-            remaining_bits_len -= 8;
-            count--;
-          }
-        }
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_RECURSIVE_ARRAY:
-      { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
-         *  or more generally:                <list> ::= { <tag> <element> <list> | <EndTag> }
-         *  where <element> ::= bit(value)
-         *        <tag>     ::= 0 | 1
-         *        <EndTag>  ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
-         * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
-         * REMARK: recursive way to specify an array but an iterative implementation!
-         */
-        gint16 no_of_bits        = pDescr->i;
-        guint8  ElementCount = 0;
-        pui8  = pui8DATA(data, pDescr->offset);
-        ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
-        while (ElementCount > 0)
-        { /* tag control shows existence of next list elements */
-	  bitvec_write_field(vector, writeIndex, Tag, 1);
-          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
-          bit_offset++;
-          remaining_bits_len--;
-
-          /* extract and store no_of_bits long element from bitstream */
-	  bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
-          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-          pui8++;
-          ElementCount--;
-
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-          bit_offset += no_of_bits;
-          remaining_bits_len -= no_of_bits;
-        }
-
-	bitvec_write_field(vector, writeIndex, !Tag, 1);
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
-        bit_offset++;
-        remaining_bits_len--;
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_RECURSIVE_TARRAY:
-      { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
-         *  M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
-         * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
-         */
-        gint16 nSizeElement = (gint16)(gint32)pDescr->value;
-        guint8  ElementCount = 0;
-        pui8  = pui8DATA(data, pDescr->offset);
-        /* Store the counted number of elements of the array */
-        ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
-
-        while (ElementCount > 0)
-        { /* tag control shows existence of next list elements */
-	  bitvec_write_field(vector, writeIndex, Tag, 1);
-          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
-          bit_offset++;
-
-          remaining_bits_len--;
-          ElementCount--;
-
-          { /* unpack the following data structure */
-            csnStream_t arT = *ar;
-            gint16      Status;
-            csnStreamInit(&arT, bit_offset, remaining_bits_len);
-            Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
-
-            if (Status >= 0)
-            { /* successful completion */
-              pui8    += nSizeElement;  /* -> to next data element */
-              remaining_bits_len = arT.remaining_bits_len;
-              bit_offset         = arT.bit_offset;
-            }
-            else
-            { /* something went awry */
-              return Status;
-            }
-          }
-
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-        }
-
-	bitvec_write_field(vector, writeIndex, !Tag, 1);
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
-        bit_offset++;
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_RECURSIVE_TARRAY_2:
-      { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
-
-        Tag = REVERSED_TAG;
-
-        /* NO break -
-         * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
-         */
-      }
-      /* FALL THROUGH */
-      case CSN_RECURSIVE_TARRAY_1:
-      { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
-         * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
-         * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
-         */
-        gint16      nSizeElement = (gint16)(gint32)pDescr->value;
-        guint8      ElementCount = 0;
-        guint8      ElementNum   = 0;
-        csnStream_t arT          = *ar;
-        gint16      Status;
-
-        pui8  = pui8DATA(data, pDescr->offset);
-        /* Store the count of the array */
-        ElementCount = *pui8DATA(data, pDescr->i);
-        ElementNum = ElementCount;
-
-        while (ElementCount > 0)
-        { /* get data element */
-          if (ElementCount != ElementNum)
-          {
-	    bitvec_write_field(vector, writeIndex, Tag, 1);
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
-            bit_offset++;
-            remaining_bits_len--;
-          }
-          ElementCount--;
-          LOGPC(DCSN1, LOGL_DEBUG, "%s { | ", pDescr->sz);
-          csnStreamInit(&arT, bit_offset, remaining_bits_len);
-          Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
-          LOGPC(DCSN1, LOGL_DEBUG, "%s } | ", pDescr->sz);
-          if (Status >= 0)
-          { /* successful completion */
-            pui8    += nSizeElement;  /* -> to next */
-            remaining_bits_len = arT.remaining_bits_len;
-            bit_offset         = arT.bit_offset;
-          }
-          else
-          { /* something went awry */
-            return Status;
-          }
-
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-        }
-	bitvec_write_field(vector, writeIndex, !Tag, 1);
-        bit_offset++;
-        remaining_bits_len--;
-        Tag = STANDARD_TAG; /* in case it was set to "reversed" */
-        pDescr++;
-        break;
-      }
-
-      case CSN_FIXED:
-      { /* Verify the fixed bits */
-        guint8  no_of_bits = (guint8) pDescr->i;
-	bitvec_write_field(vector, writeIndex, pDescr->offset, no_of_bits);
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
-        remaining_bits_len   -= no_of_bits;
-        bit_offset += no_of_bits;
-        pDescr++;
-        break;
-      }
-
-      case CSN_CALLBACK:
-      {
-        guint16  no_of_bits;
-        DissectorCallbackFcn_t callback = (DissectorCallbackFcn_t)pDescr->aux_fn;
-        LOGPC(DCSN1, LOGL_DEBUG, "CSN_CALLBACK(%s) | ", pDescr->sz);
-        no_of_bits = callback(vector, writeIndex, pvDATA(data, pDescr->i), pvDATA(data, pDescr->offset));
-        remaining_bits_len -= no_of_bits;
-        bit_offset += no_of_bits;
-        pDescr++;
-        break;
-      }
-
-      case CSN_TRAP_ERROR:
-      {
-        return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
-      }
-
-      case CSN_END:
-      {
-        ar->remaining_bits_len  = remaining_bits_len;
-        ar->bit_offset = bit_offset;
-        return remaining_bits_len;
-      }
-
-      default:
-      {
-        assert(0);
-      }
-
-    }
-
-  } while (remaining_bits_len >= 0);
-
-  return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-}
diff --git a/src/csn1.h b/src/csn1.h
index 761293d..d470228 100644
--- a/src/csn1.h
+++ b/src/csn1.h
@@ -592,4 +592,18 @@
 
 #define CSNDESCR(_FuncType) CSNDESCR_##_FuncType
 
+#define pvDATA(_pv, _offset) ((void*) ((unsigned char*)_pv + _offset))
+#define pui8DATA(_pv, _offset) ((guint8*) pvDATA(_pv, _offset))
+#define pui16DATA(_pv, _offset) ((guint16*) pvDATA(_pv, _offset))
+#define pui32DATA(_pv, _offset) ((guint32*) pvDATA(_pv, _offset))
+#define pui64DATA(_pv, _offset) ((guint64*) pvDATA(_pv, _offset))
+/* used to tag existence of next element in variable length lists */
+#define STANDARD_TAG 1
+#define REVERSED_TAG 0
+
+gint16 ProcessError_impl(const char *file, int line, unsigned *readIndex,
+                                const char* sz, gint16 err, const CSN_DESCR* pDescr);
+#define ProcessError(readIndex, sz, err, pDescr) \
+        ProcessError_impl(__FILE__, __LINE__, readIndex, sz, err, pDescr)
+
 #endif /*_PACKET_CSN1_H_*/
diff --git a/src/csn1_dec.c b/src/csn1_dec.c
new file mode 100644
index 0000000..2d3f242
--- /dev/null
+++ b/src/csn1_dec.c
@@ -0,0 +1,1390 @@
+/* csn1_dec.c
+ * Routines for CSN1 dissection in wireshark.
+ *
+ * Copyright (C) 2011 Ivan Klyuchnikov
+ *
+ * By Vincent Helfre, based on original code by Jari Sassi
+ * with the gracious authorization of STE
+ * Copyright (c) 2011 ST-Ericsson
+ *
+ * $Id: packet-csn1.c 39140 2011-09-25 22:01:50Z wmeier $
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <assert.h>
+#include <string.h>
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+#include "csn1.h"
+#include <gprs_debug.h>
+
+#include <osmocom/core/logging.h>
+#include <osmocom/core/utils.h>
+
+extern const unsigned char ixBitsTab[];
+guint8 get_masked_bits8(struct bitvec *vector, unsigned *readIndex, gint bit_offset, const gint no_of_bits);
+
+/**
+ * ================================================================================================
+ * Return TRUE if tag in bit stream indicates existence of next list element,
+ * otherwise return FALSE.
+ * Will work for tag values equal to both 0 and 1.
+ * ================================================================================================
+ */
+
+static gboolean
+existNextElement(struct bitvec *vector, unsigned *readIndex, guint8 Tag)
+{
+  int res = bitvec_get_bit_pos(vector, (*readIndex)++);
+  if (Tag == STANDARD_TAG)
+  {
+    return (res > 0);
+  }
+  return (res == 0);
+}
+
+
+gint16
+csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector, unsigned *readIndex, void* data)
+{
+  gint  remaining_bits_len = ar->remaining_bits_len;
+  gint  bit_offset         = ar->bit_offset;
+  guint8*  pui8 = NULL;
+  guint16* pui16;
+  guint32* pui32;
+  guint64* pui64;
+  guint8 Tag = STANDARD_TAG;
+  unsigned ib;
+
+  if (remaining_bits_len < 0)
+  {
+    return ProcessError(readIndex, __func__, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+  }
+
+  do
+  {
+    switch (pDescr->type)
+    {
+      case CSN_BIT:
+      {
+        if (remaining_bits_len > 0)
+        {
+          pui8  = pui8DATA(data, pDescr->offset);
+	  *pui8 = bitvec_read_field(vector, readIndex, 1);
+          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+          /* end add the bit value to protocol tree */
+        }
+        else if (pDescr->may_be_null)
+        {
+           pui8  = pui8DATA(data, pDescr->offset);
+           *pui8 = 0;
+           LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
+        }
+        else
+        {
+          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+
+        pDescr++;
+        remaining_bits_len--;
+        bit_offset++;
+        break;
+      }
+
+      case CSN_NULL:
+      { /* Empty member! */
+        bit_offset += pDescr->i;
+        pDescr++;
+        break;
+      }
+
+      case CSN_UINT:
+      {
+        guint8 no_of_bits = (guint8) pDescr->i;
+
+        if (remaining_bits_len >= no_of_bits)
+        {
+          if (no_of_bits <= 8)
+          {
+	    guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
+            pui8      = pui8DATA(data, pDescr->offset);
+            *pui8     = ui8;
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+          }
+          else if (no_of_bits <= 16)
+          {
+	    guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
+            pui16       = pui16DATA(data, pDescr->offset);
+            *pui16      = ui16;
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
+          }
+          else if (no_of_bits <= 32)
+          {
+	    guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
+            pui32       = pui32DATA(data, pDescr->offset);
+            *pui32      = ui32;
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = 0x%08x | ", pDescr->sz , *pui32);
+          }
+          else
+          {
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
+          }
+          remaining_bits_len -= no_of_bits;
+          bit_offset += no_of_bits;
+        }
+        else if (pDescr->may_be_null)
+        {
+          if (no_of_bits <= 8)
+          {
+            pui8      = pui8DATA(data, pDescr->offset);
+            *pui8     = 0;
+          }
+          else if (no_of_bits <= 16)
+          {
+            pui16      = pui16DATA(data, pDescr->offset);
+            *pui16     = 0;
+          }
+          else if (no_of_bits <= 32)
+          {
+            pui32      = pui32DATA(data, pDescr->offset);
+            *pui32     = 0;
+          }
+          LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
+        }
+        else
+        {
+          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_UINT_OFFSET:
+      {
+        guint8 no_of_bits = (guint8) pDescr->i;
+
+        if (remaining_bits_len >= no_of_bits)
+        {
+          if (no_of_bits <= 8)
+          {
+	    guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
+            pui8      = pui8DATA(data, pDescr->offset);
+            *pui8     = ui8 + (guint8)pDescr->descr.value;
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+          }
+          else if (no_of_bits <= 16)
+          {
+	    guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
+            pui16       = pui16DATA(data, pDescr->offset);
+            *pui16      = ui16 + (guint16)pDescr->descr.value;
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
+          }
+          else if (no_of_bits <= 32)
+          {
+	    guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
+            pui32       = pui32DATA(data, pDescr->offset);
+            *pui32      = ui32 + (guint16)pDescr->descr.value;
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
+          }
+          else
+          {
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
+          }
+        }
+        else
+        {
+          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+
+        remaining_bits_len -= no_of_bits;
+        bit_offset += no_of_bits;
+        pDescr++;
+        break;
+      }
+
+      case CSN_UINT_LH:
+      {
+        guint8 no_of_bits = (guint8) pDescr->i;
+
+        if (remaining_bits_len >= no_of_bits)
+        {
+          if (no_of_bits <= 8)
+          {
+	    guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
+            pui8      = pui8DATA(data, pDescr->offset);
+            *pui8     = ui8;
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+          }
+          else
+          {/* Maybe we should support more than 8 bits ? */
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
+          }
+        }
+        else
+        {
+          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+
+        remaining_bits_len -= no_of_bits;
+        bit_offset += no_of_bits;
+        pDescr++;
+        break;
+      }
+
+      case CSN_UINT_ARRAY:
+      {
+        guint8  no_of_bits  = (guint8) pDescr->i;
+        guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
+
+        if (pDescr->value != 0)
+        { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
+          nCount = *pui16DATA(data, nCount);
+        }
+
+        if (remaining_bits_len >= (no_of_bits * nCount))
+        {
+          remaining_bits_len -= (no_of_bits*nCount);
+          if (no_of_bits <= 8)
+          {
+            pui8 = pui8DATA(data, pDescr->offset);
+            do
+            {
+	      *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              pui8++;
+              bit_offset += no_of_bits;
+            } while (--nCount > 0);
+          }
+          else if (no_of_bits <= 16)
+          {
+            return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
+          }
+          else if (no_of_bits <= 32)
+          {
+            return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
+          }
+          else
+          {
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
+          }
+        }
+        else
+        {
+          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+        pDescr++;
+        break;
+      }
+
+      case CSN_VARIABLE_TARRAY_OFFSET:
+      case CSN_VARIABLE_TARRAY:
+      case CSN_TYPE_ARRAY:
+      {
+        gint16      Status;
+        csnStream_t arT    = *ar;
+        gint16      nCount = pDescr->i;
+        guint16      nSize  = (guint16)(gint32)pDescr->value;
+
+        pui8 = pui8DATA(data, pDescr->offset);
+        if (pDescr->type == CSN_VARIABLE_TARRAY)
+        { /* Count specified in field */
+          nCount = *pui8DATA(data, pDescr->i);
+        }
+        else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
+        { /* Count specified in field */
+          nCount = *pui8DATA(data, pDescr->i);
+	  /*  nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
+        }
+
+        while (nCount > 0)
+        { /* resulting array of length 0 is possible
+           * but no bits shall be read from bitstream
+           */
+
+          LOGPC(DCSN1, LOGL_DEBUG, "%s | ", pDescr->sz);
+          csnStreamInit(&arT, bit_offset, remaining_bits_len);
+	  Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
+          if (Status >= 0)
+          {
+            pui8    += nSize;
+            remaining_bits_len = arT.remaining_bits_len;
+            bit_offset         = arT.bit_offset;
+          }
+          else
+          {
+            return Status;
+          }
+          nCount--;
+        }
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_BITMAP:
+      { /* bitmap with given length. The result is left aligned! */
+        guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
+
+        if (no_of_bits > 0)
+        {
+          if (no_of_bits > remaining_bits_len)
+          {
+            return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+          if (no_of_bits <= 32)
+          {
+            for(ib = 0; ib < 4; ib++)
+            {
+	      guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
+              pui8      = pui8DATA(data, pDescr->offset+ib);
+              *pui8      = ui8;
+               LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
+            }
+          }
+          else if (no_of_bits <= 64)
+          {
+            for(ib = 0; ib < 8; ib++)
+            {
+	      guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
+              pui8      = pui8DATA(data, pDescr->offset+ib);
+              *pui8      = ui8;
+               LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
+            }
+          }
+          else
+          {
+          	return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
+          }
+
+          remaining_bits_len -= no_of_bits;
+          bit_offset += no_of_bits;
+        }
+        /* bitmap was successfully extracted or it was empty */
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_TYPE:
+      {
+        gint16      Status;
+        csnStream_t arT = *ar;
+        LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
+        csnStreamInit(&arT, bit_offset, remaining_bits_len);
+	Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
+        LOGPC(DCSN1, LOGL_DEBUG, ": End %s | ", pDescr->sz);
+        if (Status >= 0)
+        {
+          remaining_bits_len  = arT.remaining_bits_len;
+          bit_offset          = arT.bit_offset;
+          pDescr++;
+        }
+        else
+        {
+          /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr);  */
+          return Status;
+        }
+
+        break;
+      }
+
+      case CSN_CHOICE:
+      {
+        gint16 count = pDescr->i;
+        guint8 i     = 0;
+        CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
+
+        /* Make sure that the list of choice items is not empty */
+        if (!count)
+          return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
+        else if (count > 255) /* We can handle up to 256 (UCHAR_MAX) selectors */
+          return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
+
+        while (count > 0)
+        {
+          guint8 no_of_bits = pChoice->bits;
+	  guint8 value = bitvec_read_field(vector, readIndex, no_of_bits);
+          if (value == pChoice->value)
+          {
+            CSN_DESCR   descr[2];
+            gint16      Status;
+            csnStream_t arT = *ar;
+
+            descr[0]      = pChoice->descr;
+            memset(&descr[1], 0x00, sizeof(CSN_DESCR));
+            descr[1].type = CSN_END;
+            pui8          = pui8DATA(data, pDescr->offset);
+            *pui8         = i;
+            LOGPC(DCSN1, LOGL_DEBUG, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
+            if (!pChoice->keep_bits) {
+              bit_offset += no_of_bits;
+              remaining_bits_len -= no_of_bits;
+            }
+
+            csnStreamInit(&arT, bit_offset, remaining_bits_len);
+	    Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
+
+            if (Status >= 0)
+            {
+              remaining_bits_len = arT.remaining_bits_len;
+              bit_offset         = arT.bit_offset;
+            }
+            else
+            {
+              return Status;
+            }
+            break;
+          }
+
+          *readIndex -= no_of_bits;
+          count--;
+          pChoice++;
+          i++;
+        }
+
+        /* Neither of the choice items matched => unknown value */
+        if (!count)
+          return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_SERIALIZE:
+      {
+        StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
+        csnStream_t          arT       = *ar;
+        guint8 length_len              = pDescr->i;
+        gint16               Status    = -1;
+
+	guint8 length = bitvec_read_field(vector, readIndex, length_len);
+
+        LOGPC(DCSN1, LOGL_DEBUG, "%s length = %u | ", pDescr->sz , length);
+        bit_offset += length_len;
+        remaining_bits_len -= length_len;
+
+        csnStreamInit(&arT, bit_offset, length > 0 ? length : remaining_bits_len);
+        arT.direction = 1;
+        LOGPC(DCSN1, LOGL_DEBUG, "offset = %u | ", pDescr->offset);
+	Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
+
+        if (Status >= 0)
+        {
+          if (length > 0) {
+            remaining_bits_len -= length;
+            bit_offset         += length;
+          } else {
+            remaining_bits_len = arT.remaining_bits_len;
+            bit_offset         = arT.bit_offset;
+          }
+
+          /* Skip bits not handled by serialize(), if any */
+          if (Status > 0) {
+            LOGPC(DCSN1, LOGL_DEBUG, "skipped = %d | ", Status);
+            *readIndex += Status;
+          }
+
+          pDescr++;
+        }
+        else
+        {
+          /* Has already been processed: */
+          return Status;
+        }
+
+        break;
+      }
+
+      case CSN_UNION_LH:
+      case CSN_UNION:
+      {
+        gint16           Bits;
+        guint8           index;
+        gint16           count      = pDescr->i;
+        const CSN_DESCR* pDescrNext = pDescr;
+
+        pDescrNext += count + 1; /* now this is next after the union */
+        if ((count <= 0) || (count > 16))
+        {
+          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
+        }
+
+        /* Now get the bits to extract the index */
+        Bits = ixBitsTab[count];
+        index = 0;
+
+        while (Bits > 0)
+        {
+          index <<= 1;
+
+          if (CSN_UNION_LH == pDescr->type)
+          {
+            index |= get_masked_bits8(vector, readIndex, bit_offset, 1);
+          }
+          else
+          {
+	    index |= bitvec_read_field(vector, readIndex, 1);
+          }
+          remaining_bits_len--;
+          bit_offset++;
+          Bits--;
+        }
+
+        /* Assign UnionType */
+        pui8  = pui8DATA(data, pDescr->offset);
+        *pui8 = index;
+
+
+        /* script index to continue on, limited in case we do not have a power of 2 */
+        pDescr += (MIN(index + 1, count));
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+
+        switch (pDescr->type)
+        { /* get the right element of the union based on computed index */
+
+          case CSN_BIT:
+          {
+            pui8  = pui8DATA(data, pDescr->offset);
+            *pui8 = 0x00;
+	    if (bitvec_read_field(vector, readIndex, 1) > 0)
+            {
+              *pui8 = 0x01;
+            }
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+            remaining_bits_len -= 1;
+            bit_offset++;
+            pDescr++;
+            break;
+          }
+
+          case CSN_NULL:
+          { /* Empty member! */
+            bit_offset += pDescr->i;
+            pDescr++;
+            break;
+          }
+
+          case CSN_UINT:
+          {
+            guint8 no_of_bits = (guint8) pDescr->i;
+            if (remaining_bits_len >= no_of_bits)
+            {
+              if (no_of_bits <= 8)
+              {
+		guint8 ui8 = bitvec_read_field(vector, readIndex,  no_of_bits);
+                pui8       = pui8DATA(data, pDescr->offset);
+                *pui8      = ui8;
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              }
+              else if (no_of_bits <= 16)
+              {
+		guint16 ui16 = bitvec_read_field(vector, readIndex,  no_of_bits);
+                pui16        = pui16DATA(data, pDescr->offset);
+                *pui16       = ui16;
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
+              }
+              else if (no_of_bits <= 32)
+              {
+		guint32 ui32 = bitvec_read_field(vector, readIndex,  no_of_bits);
+                pui32       = pui32DATA(data, pDescr->offset);
+                *pui32      = ui32;
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
+              }
+              else
+              {
+                return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
+              }
+            }
+            else
+            {
+              return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
+            }
+
+            remaining_bits_len -= no_of_bits;
+            bit_offset += no_of_bits;
+            pDescr++;
+            break;
+          }
+
+          case CSN_UINT_OFFSET:
+          {
+            guint8 no_of_bits = (guint8) pDescr->i;
+
+            if (remaining_bits_len >= no_of_bits)
+            {
+              if (no_of_bits <= 8)
+              {
+		guint8 ui8 = bitvec_read_field(vector, readIndex,  no_of_bits);
+                pui8      = pui8DATA(data, pDescr->offset);
+                *pui8     = ui8 + (guint8)pDescr->descr.value;
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              }
+              else if (no_of_bits <= 16)
+              {
+		guint16 ui16 = bitvec_read_field(vector, readIndex,  no_of_bits);
+                pui16       = pui16DATA(data, pDescr->offset);
+                *pui16      = ui16 + (guint16)pDescr->descr.value;
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
+              }
+              else if (no_of_bits <= 32)
+              {
+		guint32 ui32 = bitvec_read_field(vector, readIndex,  no_of_bits);
+                pui32       = pui32DATA(data, pDescr->offset);
+                *pui32      = ui32 + (guint16)pDescr->descr.value;
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
+              }
+              else
+              {
+                return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
+              }
+            }
+            else
+            {
+              return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+            }
+
+            remaining_bits_len -= no_of_bits;
+            bit_offset += no_of_bits;
+            pDescr++;
+            break;
+          }
+
+          case CSN_UINT_LH:
+          {
+            guint8 no_of_bits = (guint8) pDescr->i;
+
+            if (remaining_bits_len >= no_of_bits)
+            {
+              if (no_of_bits <= 8)
+              {
+		guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
+                pui8      = pui8DATA(data, pDescr->offset);
+                *pui8     = ui8;
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              }
+              else
+              { /* Maybe we should support more than 8 bits ? */
+                return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
+              }
+            }
+            else
+            {
+              return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+            }
+
+            remaining_bits_len -= no_of_bits;
+            bit_offset += no_of_bits;
+            pDescr++;
+            break;
+          }
+
+          case CSN_UINT_ARRAY:
+          {
+            guint8  no_of_bits  = (guint8) pDescr->i;
+            guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
+
+            if (pDescr->value != 0)
+            { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
+              nCount = *pui16DATA(data, nCount);
+            }
+
+            if (remaining_bits_len >= (no_of_bits * nCount))
+            {
+              remaining_bits_len -= (no_of_bits * nCount);
+              if (no_of_bits <= 8)
+              {
+                pui8 = pui8DATA(data, pDescr->offset);
+
+                while (nCount > 0)
+                {
+		  *pui8 = bitvec_read_field(vector, readIndex,  no_of_bits);
+                  LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+                  pui8++;
+                  bit_offset += no_of_bits;
+                  nCount--;
+                }
+              }
+              else if (no_of_bits <= 16)
+              {
+                pui16 = pui16DATA(data, pDescr->offset);
+
+                while (nCount > 0)
+                {
+		 *pui16 = bitvec_read_field(vector, readIndex,  no_of_bits);
+                  LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
+                  pui16++;
+                  bit_offset += no_of_bits;
+                  nCount--;
+                }
+              }
+              else if (no_of_bits <= 32)
+              { /* not supported */
+                return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
+              }
+              else
+              {
+                return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
+              }
+            }
+            else
+            {
+              return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+            }
+
+            pDescr++;
+            break;
+          }
+
+          case CSN_VARIABLE_TARRAY_OFFSET:
+          case CSN_VARIABLE_TARRAY:
+          case CSN_TYPE_ARRAY:
+          {
+            gint16      Status;
+            csnStream_t arT    = *ar;
+            guint16      nCount = (guint16) pDescr->i;
+            guint16      nSize  = (guint16)(guint32)pDescr->value;
+
+            pui8  = pui8DATA(data, pDescr->offset);
+
+            if (CSN_VARIABLE_TARRAY == pDescr->type)
+            { /* Count specified in field */
+              nCount = *pui8DATA(data, pDescr->i);
+            }
+            else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
+            { /* Count specified in field */
+              nCount = *pui8DATA(data, pDescr->i);
+              nCount--; /* Offset 1 */
+            }
+
+            while (nCount--)    /* Changed to handle length = 0.  */
+            {
+              LOGPC(DCSN1, LOGL_DEBUG, "%s | ", pDescr->sz);
+              csnStreamInit(&arT, bit_offset, remaining_bits_len);
+	      Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
+              if (Status >= 0)
+              {
+                pui8    += nSize;
+                remaining_bits_len = arT.remaining_bits_len;
+                bit_offset         = arT.bit_offset;
+              }
+              else
+              {
+                return Status;
+              }
+            }
+
+            pDescr++;
+            break;
+          }
+
+          case CSN_BITMAP:
+          { /* bitmap with given length. The result is left aligned! */
+            guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
+
+            if (no_of_bits > 0)
+            {
+              if (no_of_bits > remaining_bits_len)
+              {
+                return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+              }
+
+              if (no_of_bits <= 32)
+              {
+		guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
+                pui32       = pui32DATA(data, pDescr->offset);
+                *pui32      = ui32;
+              }
+              else if (no_of_bits <= 64)
+              {
+		guint64 ui64 = bitvec_read_field(vector, readIndex, no_of_bits);
+                pui64       = pui64DATA(data, pDescr->offset);
+                *pui64      = ui64;
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %lu | ", pDescr->sz , *pui64);
+              }
+              else
+              {
+              	return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
+              }
+
+              remaining_bits_len -= no_of_bits;
+              bit_offset += no_of_bits;
+            }
+            /* bitmap was successfully extracted or it was empty */
+
+            pDescr++;
+            break;
+          }
+
+          case CSN_TYPE:
+          {
+            gint16      Status;
+            csnStream_t arT = *ar;
+            LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
+            csnStreamInit(&arT, bit_offset, remaining_bits_len);
+	    Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
+            LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
+            if (Status >= 0)
+            {
+              remaining_bits_len = arT.remaining_bits_len;
+              bit_offset         = arT.bit_offset;
+              pDescr++;
+            }
+            else
+            { /* return error code Has already been processed:  */
+              return Status;
+            }
+
+            break;
+          }
+
+          default:
+          { /* descriptions of union elements other than above are illegal */
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
+          }
+        }
+
+        pDescr = pDescrNext;
+        break;
+      }
+
+      case CSN_EXIST:
+      case CSN_EXIST_LH:
+      {
+        guint8 fExist;
+
+        pui8  = pui8DATA(data, pDescr->offset);
+
+        if (CSN_EXIST_LH == pDescr->type)
+        {
+	  fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
+        }
+        else
+        {
+	  fExist = bitvec_read_field(vector, readIndex, 1);
+        }
+
+        *pui8 = fExist;
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+        pDescr++;
+        bit_offset++;
+        remaining_bits_len -= 1;
+
+        if (!fExist)
+        {
+          ar->remaining_bits_len  = remaining_bits_len;
+          ar->bit_offset          = bit_offset;
+          return remaining_bits_len;
+        }
+
+        break;
+      }
+
+      case CSN_NEXT_EXIST:
+      {
+        guint8 fExist;
+
+        pui8  = pui8DATA(data, pDescr->offset);
+
+        /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
+        if ((pDescr->may_be_null) && (remaining_bits_len == 0))
+        { /* no more bits to decode is fine here - end of message detected and allowed */
+
+          /* Skip i entries + this entry */
+          pDescr += pDescr->i + 1;
+
+          /* Set the data member to "not exist" */
+          *pui8 = 0;
+          break;
+        }
+
+        /* the "regular" M_NEXT_EXIST description element */
+
+        fExist = 0x00;
+	if (bitvec_read_field(vector, readIndex, 1))
+        {
+          fExist = 0x01;
+        }
+
+        *pui8     = fExist;
+        remaining_bits_len -= 1;
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+        ++bit_offset;
+
+        if (fExist == 0)
+        { /* Skip 'i' entries */
+          pDescr += pDescr->i;
+        }
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_NEXT_EXIST_LH:
+      {
+        guint8 fExist;
+        pui8  = pui8DATA(data, pDescr->offset);
+
+        /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
+        if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
+        { /* no more bits to decode is fine here - end of message detected and allowed */
+
+          /* skip 'i' entries + this entry */
+          pDescr += pDescr->i + 1;
+
+          /* set the data member to "not exist" */
+          *pui8 = 0;
+          break;
+        }
+
+        /* the "regular" M_NEXT_EXIST_LH description element */
+        fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)fExist);
+        *pui8++   = fExist;
+        remaining_bits_len -= 1;
+
+        bit_offset++;
+
+        if (fExist == 0)
+        { /* Skip 'i' entries */
+          pDescr += pDescr->i;
+        }
+        pDescr++;
+
+        break;
+      }
+
+      case CSN_VARIABLE_BITMAP_1:
+      { /* Bitmap from here and to the end of message */
+
+        *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
+
+        /*no break -
+         * with a length set we have a regular variable length bitmap so we continue */
+      }
+      /* FALL THROUGH */
+      case CSN_VARIABLE_BITMAP:
+      { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
+         * <N: bit (5)> <bitmap: bit(N + offset)>
+         * Bit array with length (in bits) specified in parameter (pDescr->descr)
+         * The result is right aligned!
+         */
+        gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
+
+        no_of_bits += pDescr->i; /* adjusted by offset */
+
+        if (no_of_bits > 0)
+        {
+          remaining_bits_len -= no_of_bits;
+
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+          { /* extract bits */
+            guint8* pui8 = pui8DATA(data, pDescr->offset);
+            gint16 nB1  = no_of_bits & 0x07;/* no_of_bits Mod 8 */
+
+            if (nB1 > 0)
+            { /* take care of the first byte - it will be right aligned */
+	      *pui8 = bitvec_read_field(vector, readIndex, nB1);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              pui8++;
+              no_of_bits  -= nB1;
+              bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
+            }
+
+            /* remaining no_of_bits is a multiple of 8 or 0 */
+            while (no_of_bits > 0)
+            {
+	      *pui8 = bitvec_read_field(vector, readIndex, 8);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              pui8++;
+              no_of_bits -= 8;
+            }
+          }
+        }
+        pDescr++;
+        break;
+      }
+
+      case CSN_LEFT_ALIGNED_VAR_BMP_1:
+      { /* Bitmap from here and to the end of message */
+
+        *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
+
+        /* no break -
+         * with a length set we have a regular left aligned variable length bitmap so we continue
+         */
+      }
+      /* FALL THROUGH */
+      case CSN_LEFT_ALIGNED_VAR_BMP:
+      { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
+         * <N: bit (5)> <bitmap: bit(N + offset)>
+         * bit array with length (in bits) specified in parameter (pDescr->descr)
+         */
+        gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
+
+        no_of_bits += pDescr->i;/* size adjusted by offset */
+
+        if (no_of_bits > 0)
+        {
+          remaining_bits_len -= no_of_bits;
+
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+          { /* extract bits */
+            guint8* pui8 = pui8DATA(data, pDescr->offset);
+
+            while (no_of_bits >= 8)
+            {
+	      *pui8 = bitvec_read_field(vector, readIndex, 8);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              pui8++;
+              no_of_bits -= 8;
+            }
+            if (no_of_bits > 0)
+            {
+	      *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              pui8++;
+              bit_offset += no_of_bits;
+              no_of_bits = 0;
+            }
+          }
+        }
+
+        /* bitmap was successfully extracted or it was empty */
+        pDescr++;
+        break;
+      }
+
+      case CSN_PADDING_BITS:
+      { /* Padding from here and to the end of message */
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = ", pDescr->sz);
+        if (remaining_bits_len > 0)
+        {
+          while (remaining_bits_len > 0)
+          {
+            guint bits_to_handle = remaining_bits_len%8;
+            if (bits_to_handle > 0)
+            {
+              LOGPC(DCSN1, LOGL_DEBUG, "%d|", bitvec_get_uint(vector, bits_to_handle));
+              remaining_bits_len -= bits_to_handle;
+              bit_offset += bits_to_handle;
+            }
+            else if (bits_to_handle == 0)
+            {
+              LOGPC(DCSN1, LOGL_DEBUG, "%d|", bitvec_get_uint(vector, 8));
+              remaining_bits_len -= 8;
+              bit_offset += 8;
+            }
+          }
+        }
+        if (remaining_bits_len < 0)
+        {
+          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+
+        /* Padding was successfully extracted or it was empty */
+        pDescr++;
+        break;
+      }
+
+      case CSN_VARIABLE_ARRAY:
+      { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
+         * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
+         * Array with length specified in parameter:
+         *  <count: bit (x)>
+         *  <list: octet(count + offset)>
+         */
+        gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
+
+        count += pDescr->i; /* Adjusted by offset */
+
+        if (count > 0)
+        {
+          remaining_bits_len -= count * 8;
+
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+          pui8 = pui8DATA(data, pDescr->offset);
+
+          while (count > 0)
+          {
+	    *pui8 = bitvec_read_field(vector, readIndex, 8);
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = 0x%x | ", pDescr->sz , (unsigned)*pui8);
+            pui8++;
+            bit_offset += 8;
+            count--;
+          }
+        }
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_RECURSIVE_ARRAY:
+      { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
+         *  or more generally:                <list> ::= { <tag> <element> <list> | <EndTag> }
+         *  where <element> ::= bit(value)
+         *        <tag>     ::= 0 | 1
+         *        <EndTag>  ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
+         * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
+         * REMARK: recursive way to specify an array but an iterative implementation!
+         */
+        gint16 no_of_bits        = pDescr->i;
+        guint8  ElementCount = 0;
+
+        pui8  = pui8DATA(data, pDescr->offset);
+
+	while (existNextElement(vector, readIndex, Tag))
+        { /* tag control shows existence of next list elements */
+          LOGPC(DCSN1, LOGL_DEBUG, "%s = Exist | ", pDescr->sz);
+          bit_offset++;
+          remaining_bits_len--;
+
+          /* extract and store no_of_bits long element from bitstream */
+	  *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
+          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+          pui8++;
+          remaining_bits_len -= no_of_bits;
+          ElementCount++;
+
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+          bit_offset += no_of_bits;
+        }
+
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
+        /* existNextElement() returned FALSE, 1 bit consumed */
+        bit_offset++;
+        remaining_bits_len--;
+
+        /* Store the counted number of elements of the array */
+        *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_RECURSIVE_TARRAY:
+      { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
+         *  M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
+         * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE), (void_fn_t)ElementsOf(((_STRUCT*)0)->_MEMBER)}
+         */
+        gint16 nSizeElement = (gint16)(gint32)pDescr->value;
+        guint32 nSizeArray = (guint32)((uintptr_t)pDescr->aux_fn);
+        guint8  ElementCount = 0;
+        pui8  = pui8DATA(data, pDescr->offset);
+
+	while (existNextElement(vector, readIndex, Tag))
+        { /* tag control shows existence of next list elements */
+          LOGPC(DCSN1, LOGL_DEBUG, "%s = Exist | ", pDescr->sz);
+          /* existNextElement() returned TRUE, 1 bit consumed */
+          bit_offset++;
+          remaining_bits_len--;
+          ElementCount++;
+
+          if (ElementCount > nSizeArray)
+          {
+            LOGPC(DCSN1, LOGL_ERROR, "error: %s: too many elements (>%u) in recursive array. Increase its size! } |", pDescr->sz, nSizeArray);
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
+          }
+
+          { /* unpack the following data structure */
+            csnStream_t arT = *ar;
+            gint16      Status;
+            csnStreamInit(&arT, bit_offset, remaining_bits_len);
+	    Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
+
+            if (Status >= 0)
+            { /* successful completion */
+              pui8    += nSizeElement;  /* -> to next data element */
+              remaining_bits_len = arT.remaining_bits_len;
+              bit_offset         = arT.bit_offset;
+            }
+            else
+            { /* something went awry */
+              return Status;
+            }
+          }
+
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+        }
+
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
+
+        /* existNextElement() returned FALSE, 1 bit consumed */
+        remaining_bits_len--;
+        bit_offset++;
+
+        /* Store the counted number of elements of the array */
+        *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_RECURSIVE_TARRAY_2:
+      { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
+
+        Tag = REVERSED_TAG;
+
+        /* NO break -
+         * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
+         */
+      }
+      /* FALL THROUGH */
+      case CSN_RECURSIVE_TARRAY_1:
+      { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
+         * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
+         * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE), (void_fn_t)ElementsOf(((_STRUCT*)0)->_MEMBER)}
+         */
+        gint16      nSizeElement = (gint16)(gint32)pDescr->value;
+        guint32     nSizeArray = (guint32)((uintptr_t)pDescr->aux_fn);
+        guint8       ElementCount = 0;
+        csnStream_t arT          = *ar;
+        gboolean     EndOfList    = FALSE;
+        gint16      Status;
+        pui8  = pui8DATA(data, pDescr->offset);
+
+        do
+        { /* get data element */
+          ElementCount++;
+
+          if (ElementCount > nSizeArray)
+          {
+            LOGPC(DCSN1, LOGL_ERROR, "error: %s: too many elements (>%u) in recursive array. Increase its size! } |", pDescr->sz, nSizeArray);
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
+          }
+
+          LOGPC(DCSN1, LOGL_DEBUG, "%s { | ", pDescr->sz);
+
+          csnStreamInit(&arT, bit_offset, remaining_bits_len);
+	  Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
+
+          if (Status >= 0)
+          { /* successful completion */
+            pui8    += nSizeElement;  /* -> to next */
+            remaining_bits_len = arT.remaining_bits_len;
+            bit_offset         = arT.bit_offset;
+          }
+          else
+          { /* something went awry */
+            return Status;
+          }
+
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+          /* control of next element's tag */
+          LOGPC(DCSN1, LOGL_DEBUG, "%s } | ", pDescr->sz);
+	  EndOfList         = !(existNextElement(vector, readIndex, Tag));
+
+          bit_offset++;
+          remaining_bits_len--; /* 1 bit consumed (tag) */
+        } while (!EndOfList);
+
+
+        /* Store the count of the array */
+        *pui8DATA(data, pDescr->i) = ElementCount;
+        Tag = STANDARD_TAG; /* in case it was set to "reversed" */
+        pDescr++;
+        break;
+      }
+
+      case CSN_FIXED:
+      { /* Verify the fixed bits */
+        guint8  no_of_bits = (guint8) pDescr->i;
+        guint32 ui32;
+
+        if (no_of_bits <= 32)
+        {
+	  ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
+        }
+        else
+        {
+          return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
+        }
+        if (ui32 != (unsigned)(gint32)pDescr->offset)
+        {
+          return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
+        }
+
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)ui32);
+        remaining_bits_len   -= no_of_bits;
+        bit_offset += no_of_bits;
+        pDescr++;
+        break;
+      }
+
+      case CSN_CALLBACK:
+      {
+        guint16  no_of_bits;
+        DissectorCallbackFcn_t callback = (DissectorCallbackFcn_t)pDescr->aux_fn;
+        LOGPC(DCSN1, LOGL_DEBUG, "CSN_CALLBACK(%s) | ", pDescr->sz);
+        no_of_bits = callback(vector, readIndex, pvDATA(data, pDescr->i), pvDATA(data, pDescr->offset));
+        remaining_bits_len -= no_of_bits;
+        bit_offset += no_of_bits;
+        pDescr++;
+        break;
+      }
+
+      case CSN_TRAP_ERROR:
+      {
+        return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
+      }
+
+      case CSN_END:
+      {
+        ar->remaining_bits_len  = remaining_bits_len;
+        ar->bit_offset = bit_offset;
+        return remaining_bits_len;
+      }
+
+      default:
+      {
+        assert(0);
+      }
+
+
+    }
+
+  } while (remaining_bits_len >= 0);
+
+  return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+}
diff --git a/src/csn1_enc.c b/src/csn1_enc.c
new file mode 100644
index 0000000..5518d06
--- /dev/null
+++ b/src/csn1_enc.c
@@ -0,0 +1,1305 @@
+/* csn1_enc.c
+ * Routines for CSN1 dissection in wireshark.
+ *
+ * Copyright (C) 2011 Ivan Klyuchnikov
+ *
+ * By Vincent Helfre, based on original code by Jari Sassi
+ * with the gracious authorization of STE
+ * Copyright (c) 2011 ST-Ericsson
+ *
+ * $Id: packet-csn1.c 39140 2011-09-25 22:01:50Z wmeier $
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <assert.h>
+#include <string.h>
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+#include "csn1.h"
+#include <gprs_debug.h>
+
+#include <osmocom/core/logging.h>
+#include <osmocom/core/utils.h>
+
+extern const unsigned char ixBitsTab[];
+guint8 get_masked_bits8(struct bitvec *vector, unsigned *readIndex, gint bit_offset, const gint no_of_bits);
+
+/**
+ * ================================================================================================
+ * set initial/start values in help data structure used for packing/unpacking operation
+ * ================================================================================================
+ */
+
+gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector, unsigned *writeIndex, void* data)
+{
+  gint  remaining_bits_len = ar->remaining_bits_len;
+  gint  bit_offset         = ar->bit_offset;
+  guint8*  pui8;
+  guint16* pui16;
+  guint32* pui32;
+  guint64* pui64;
+  unsigned ib;
+
+  guint8 Tag = STANDARD_TAG;
+
+  if (remaining_bits_len < 0)
+  {
+    return ProcessError(writeIndex, __func__, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+  }
+
+  do
+  {
+    switch (pDescr->type)
+    {
+      case CSN_BIT:
+      {
+        if (remaining_bits_len > 0)
+        {
+          pui8  = pui8DATA(data, pDescr->offset);
+	  bitvec_write_field(vector, writeIndex, *pui8, 1);
+          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+          /* end add the bit value to protocol tree */
+        }
+        else if (pDescr->may_be_null)
+        {
+           LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
+        }
+        else
+        {
+          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+
+        pDescr++;
+        remaining_bits_len--;
+        bit_offset++;
+        break;
+      }
+
+      case CSN_NULL:
+      { /* Empty member! */
+        pDescr++;
+        break;
+      }
+
+      case CSN_UINT:
+      {
+        guint8 no_of_bits = (guint8) pDescr->i;
+
+        if (remaining_bits_len >= no_of_bits)
+        {
+          if (no_of_bits <= 8)
+          {
+            pui8      = pui8DATA(data, pDescr->offset);
+	    bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+          }
+          else if (no_of_bits <= 16)
+          {
+            pui16       = pui16DATA(data, pDescr->offset);
+	    bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
+          }
+          else if (no_of_bits <= 32)
+          {
+            pui32       = pui32DATA(data, pDescr->offset);
+	    bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
+          }
+          else
+          {
+            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
+          }
+
+          remaining_bits_len -= no_of_bits;
+          bit_offset += no_of_bits;
+        }
+        else if (pDescr->may_be_null)
+        {
+          LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
+        }
+        else
+        {
+          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_UINT_OFFSET:
+      {
+        guint8 no_of_bits = (guint8) pDescr->i;
+
+        if (remaining_bits_len >= no_of_bits)
+        {
+          if (no_of_bits <= 8)
+          {
+            pui8      = pui8DATA(data, pDescr->offset);
+	    bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
+          }
+          else if (no_of_bits <= 16)
+          {
+            pui16       = pui16DATA(data, pDescr->offset);
+	    bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
+          }
+          else if (no_of_bits <= 32)
+          {
+            pui32       = pui32DATA(data, pDescr->offset);
+	    bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
+          }
+          else
+          {
+            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
+          }
+        }
+        else
+        {
+          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+
+        remaining_bits_len -= no_of_bits;
+        bit_offset += no_of_bits;
+        pDescr++;
+        break;
+      }
+
+      case CSN_UINT_LH:
+      {
+        guint8 no_of_bits = (guint8) pDescr->i;
+
+        if (remaining_bits_len >= no_of_bits)
+        {
+          if (no_of_bits <= 8)
+          {
+            pui8      = pui8DATA(data, pDescr->offset);
+	    bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
+            // TODO : Change get_masked_bits8()
+            *writeIndex -= no_of_bits;
+            guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
+            *writeIndex -= no_of_bits;
+	    bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+
+          }
+          else
+          {/* Maybe we should support more than 8 bits ? */
+            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
+          }
+        }
+        else
+        {
+          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+
+        remaining_bits_len -= no_of_bits;
+        bit_offset += no_of_bits;
+        pDescr++;
+        break;
+      }
+
+      case CSN_UINT_ARRAY:
+      {
+        guint8  no_of_bits  = (guint8) pDescr->i;
+        guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
+
+        if (pDescr->value != 0)
+        { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
+          nCount = *pui16DATA(data, nCount);
+        }
+
+        if (remaining_bits_len >= (no_of_bits * nCount))
+        {
+          if (no_of_bits <= 8)
+          {
+            pui8 = pui8DATA(data, pDescr->offset);
+            do
+            {
+	      bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              pui8++;
+              remaining_bits_len -= no_of_bits;
+              bit_offset += no_of_bits;
+            } while (--nCount > 0);
+          }
+          else if (no_of_bits <= 16)
+          {
+            return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
+          }
+          else if (no_of_bits <= 32)
+          {
+            return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
+          }
+          else
+          {
+            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
+          }
+        }
+        else
+        {
+          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+        pDescr++;
+        break;
+      }
+
+      case CSN_VARIABLE_TARRAY_OFFSET:
+      case CSN_VARIABLE_TARRAY:
+      case CSN_TYPE_ARRAY:
+      {
+        gint16      Status;
+        csnStream_t arT    = *ar;
+        gint16      nCount = pDescr->i;
+        guint16     nSize  = (guint16)(gint32)pDescr->value;
+
+        pui8 = pui8DATA(data, pDescr->offset);
+        if (pDescr->type == CSN_VARIABLE_TARRAY)
+        { /* Count specified in field */
+          nCount = *pui8DATA(data, pDescr->i);
+        }
+        else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
+        { /* Count specified in field */
+          nCount = *pui8DATA(data, pDescr->i);
+	  /*  nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
+        }
+
+        while (nCount > 0)
+        { /* resulting array of length 0 is possible
+           * but no bits shall be read from bitstream
+           */
+
+          LOGPC(DCSN1, LOGL_DEBUG, "%s : | ", pDescr->sz);
+          csnStreamInit(&arT, bit_offset, remaining_bits_len);
+          Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
+          if (Status >= 0)
+          {
+            pui8    += nSize;
+            remaining_bits_len = arT.remaining_bits_len;
+            bit_offset         = arT.bit_offset;
+
+          }
+          else
+          {
+            return Status;
+          }
+          nCount--;
+        }
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_BITMAP:
+      { /* bitmap with given length. The result is left aligned! */
+        guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
+
+        if (no_of_bits > 0)
+        {
+          if (no_of_bits > remaining_bits_len)
+          {
+            return ProcessError(writeIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+          if (no_of_bits <= 32)
+          {
+            for(ib = 0; ib < 4; ib++)
+            {
+              pui8      = pui8DATA(data, pDescr->offset+ib);
+	      bitvec_write_field(vector, writeIndex, *pui8, 8);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
+            }
+          }
+          else if (no_of_bits <= 64)
+          {
+            for(ib = 0; ib < 8; ib++)
+            {
+              pui8      = pui8DATA(data, pDescr->offset+ib);
+	      bitvec_write_field(vector, writeIndex, *pui8, 8);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
+            }
+          }
+          else
+          {
+          	return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
+          }
+
+          remaining_bits_len -= no_of_bits;
+          bit_offset += no_of_bits;
+        }
+        /* bitmap was successfully extracted or it was empty */
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_TYPE:
+      {
+        gint16      Status;
+        csnStream_t arT = *ar;
+        LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
+        csnStreamInit(&arT, bit_offset, remaining_bits_len);
+        Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
+        LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
+        if (Status >= 0)
+        {
+
+          remaining_bits_len  = arT.remaining_bits_len;
+          bit_offset          = arT.bit_offset;
+          pDescr++;
+        }
+        else
+        {
+          /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr);  */
+          return Status;
+        }
+
+        break;
+      }
+
+      case CSN_CHOICE:
+      {
+        gint16 count = pDescr->i;
+        const CSN_ChoiceElement_t* pChoice = (const CSN_ChoiceElement_t*) pDescr->descr.ptr;
+
+        /* Make sure that the list of choice items is not empty */
+        if (!count)
+          return ProcessError(writeIndex, "csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
+        else if (count > 255) /* We can handle up to 256 (UCHAR_MAX) selectors */
+          return ProcessError(writeIndex, "csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
+
+        /* Make sure that choice index is not out of range */
+        pui8 = pui8DATA(data, pDescr->offset);
+        if (*pui8 >= count)
+          return ProcessError(writeIndex, "csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
+
+        pChoice += *pui8;
+        guint8 no_of_bits = pChoice->bits;
+        guint8 value = pChoice->value;
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
+	bitvec_write_field(vector, writeIndex, value, no_of_bits);
+
+        CSN_DESCR   descr[2];
+        gint16      Status;
+        csnStream_t arT = *ar;
+
+        descr[0]      = pChoice->descr;
+        memset(&descr[1], 0x00, sizeof(CSN_DESCR));
+        descr[1].type = CSN_END;
+        bit_offset += no_of_bits;
+        remaining_bits_len -= no_of_bits;
+
+        csnStreamInit(&arT, bit_offset, remaining_bits_len);
+        Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
+
+        if (Status >= 0)
+        {
+          remaining_bits_len = arT.remaining_bits_len;
+          bit_offset         = arT.bit_offset;
+        }
+        else
+        {
+          return Status;
+        }
+
+        pDescr++;
+        break;
+      }
+
+   case CSN_SERIALIZE:
+      {
+        StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
+        csnStream_t          arT       = *ar;
+        guint8 length_len              = pDescr->i;
+        gint16               Status = -1;
+        unsigned lengthIndex;
+
+        // store writeIndex for length value (7 bit)
+        lengthIndex = *writeIndex;
+        *writeIndex += length_len;
+        bit_offset += length_len;
+        remaining_bits_len -= length_len;
+        arT.direction = 0;
+        csnStreamInit(&arT, bit_offset, remaining_bits_len);
+        Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
+
+	bitvec_write_field(vector, &lengthIndex, *writeIndex - lengthIndex - length_len, length_len);
+        LOGPC(DCSN1, LOGL_DEBUG, "%s length = %u | ", pDescr->sz , (unsigned)(*writeIndex - lengthIndex));
+
+        if (Status >= 0)
+        {
+          remaining_bits_len = arT.remaining_bits_len;
+          bit_offset         = arT.bit_offset;
+          pDescr++;
+        }
+        else
+        {
+          // Has already been processed:
+          return Status;
+        }
+
+        break;
+      }
+
+      case CSN_UNION_LH:
+      case CSN_UNION:
+      {
+        gint16           Bits;
+        guint8           index;
+        gint16           count      = pDescr->i;
+        const CSN_DESCR* pDescrNext = pDescr;
+
+        pDescrNext += count + 1; /* now this is next after the union */
+        if ((count <= 0) || (count > 16))
+        {
+          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
+        }
+
+        /* Now get the bits to extract the index */
+        Bits = ixBitsTab[count];
+        index = 0;
+
+        /* Assign UnionType */
+        pui8  = pui8DATA(data, pDescr->offset);
+	//read index from data and write to vector
+	bitvec_write_field(vector, writeIndex, *pui8, Bits);
+
+	//decode index
+        *writeIndex -= Bits;
+
+        while (Bits > 0)
+        {
+          index <<= 1;
+
+          if (CSN_UNION_LH == pDescr->type)
+          {
+            index |= get_masked_bits8(vector, writeIndex, bit_offset, 1);
+          }
+          else
+          {
+	    index |= bitvec_read_field(vector, writeIndex, 1);
+          }
+
+          remaining_bits_len--;
+          bit_offset++;
+          Bits--;
+        }
+
+        *writeIndex -= Bits;
+	bitvec_write_field(vector, writeIndex, index, Bits);
+
+
+        /* script index to continue on, limited in case we do not have a power of 2 */
+        pDescr += (MIN(index + 1, count));
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)index);
+
+        switch (pDescr->type)
+        { /* get the right element of the union based on computed index */
+
+          case CSN_BIT:
+          {
+            pui8  = pui8DATA(data, pDescr->offset);
+	    bitvec_write_field(vector, writeIndex, *pui8, 1);
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+            remaining_bits_len--;
+            bit_offset++;
+            pDescr++;
+            break;
+          }
+
+          case CSN_NULL:
+          { /* Empty member! */
+            pDescr++;
+            break;
+          }
+
+          case CSN_UINT:
+          {
+            guint8 no_of_bits = (guint8) pDescr->i;
+            if (remaining_bits_len >= no_of_bits)
+            {
+              if (no_of_bits <= 8)
+              {
+                pui8      = pui8DATA(data, pDescr->offset);
+		bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              }
+              else if (no_of_bits <= 16)
+              {
+                pui16       = pui16DATA(data, pDescr->offset);
+		bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
+              }
+              else if (no_of_bits <= 32)
+              {
+                pui32       = pui32DATA(data, pDescr->offset);
+		bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
+              }
+              else
+              {
+                return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
+              }
+            }
+            else
+            {
+              return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
+            }
+
+            remaining_bits_len -= no_of_bits;
+            bit_offset += no_of_bits;
+            pDescr++;
+            break;
+          }
+
+          case CSN_UINT_OFFSET:
+          {
+            guint8 no_of_bits = (guint8) pDescr->i;
+
+            if (remaining_bits_len >= no_of_bits)
+            {
+              if (no_of_bits <= 8)
+              {
+                pui8      = pui8DATA(data, pDescr->offset);
+		bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
+              }
+              else if (no_of_bits <= 16)
+              {
+                pui16       = pui16DATA(data, pDescr->offset);
+		bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
+              }
+              else if (no_of_bits <= 32)
+              {
+                pui32       = pui32DATA(data, pDescr->offset);
+		bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
+              }
+              else
+              {
+                return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
+              }
+            }
+            else
+            {
+              return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+            }
+
+            remaining_bits_len -= no_of_bits;
+            bit_offset += no_of_bits;
+            pDescr++;
+            break;
+          }
+
+          case CSN_UINT_LH:
+          {
+            guint8 no_of_bits = (guint8) pDescr->i;
+
+            if (remaining_bits_len >= no_of_bits)
+            {
+              remaining_bits_len -= no_of_bits;
+              if (no_of_bits <= 8)
+              {
+                pui8      = pui8DATA(data, pDescr->offset);
+		bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
+                // TODO : Change get_masked_bits8()
+                *writeIndex -= no_of_bits;
+                guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
+                *writeIndex -= no_of_bits;
+		bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+
+              }
+              else
+              {/* Maybe we should support more than 8 bits ? */
+                return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
+              }
+            }
+            else
+            {
+              return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+            }
+
+            remaining_bits_len -= no_of_bits;
+            bit_offset += no_of_bits;
+            pDescr++;
+            break;
+          }
+
+          case CSN_UINT_ARRAY:
+          {
+            guint8  no_of_bits  = (guint8) pDescr->i;
+            guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
+
+            if (pDescr->value != 0)
+            { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
+              nCount = *pui16DATA(data, nCount);
+            }
+
+            if (remaining_bits_len >= (no_of_bits * nCount))
+            {
+              if (no_of_bits <= 8)
+              {
+                pui8 = pui8DATA(data, pDescr->offset);
+                do
+                {
+		  bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
+                  LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+                  pui8++;
+                  remaining_bits_len -= no_of_bits;
+                  bit_offset += no_of_bits;
+                } while (--nCount > 0);
+              }
+              else if (no_of_bits <= 16)
+              {
+                return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
+              }
+              else if (no_of_bits <= 32)
+              {
+                return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
+              }
+              else
+              {
+                return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
+              }
+            }
+            else
+            {
+              return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+            }
+            pDescr++;
+            break;
+          }
+
+          case CSN_VARIABLE_TARRAY_OFFSET:
+          case CSN_VARIABLE_TARRAY:
+          case CSN_TYPE_ARRAY:
+          {
+            gint16      Status;
+            csnStream_t arT    = *ar;
+            gint16      nCount = pDescr->i;
+            guint16     nSize  = (guint16)(gint32)pDescr->value;
+
+            pui8 = pui8DATA(data, pDescr->offset);
+            if (pDescr->type == CSN_VARIABLE_TARRAY)
+            { /* Count specified in field */
+              nCount = *pui8DATA(data, pDescr->i);
+            }
+            else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
+            { /* Count specified in field */
+              nCount = *pui8DATA(data, pDescr->i);
+              /*  nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
+            }
+
+            while (nCount > 0)
+            { /* resulting array of length 0 is possible
+               * but no bits shall be read from bitstream
+               */
+
+              LOGPC(DCSN1, LOGL_DEBUG, "%s : | ", pDescr->sz);
+              csnStreamInit(&arT, bit_offset, remaining_bits_len);
+              Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
+              if (Status >= 0)
+              {
+                pui8    += nSize;
+                remaining_bits_len = arT.remaining_bits_len;
+                bit_offset         = arT.bit_offset;
+              }
+              else
+              {
+                return Status;
+              }
+              nCount--;
+            }
+
+            pDescr++;
+            break;
+          }
+
+          case CSN_BITMAP:
+          { /* bitmap with given length. The result is left aligned! */
+            guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
+
+            if (no_of_bits > 0)
+            {
+              if (no_of_bits > remaining_bits_len)
+              {
+                return ProcessError(writeIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+              }
+
+              if (no_of_bits <= 32)
+              {
+                pui32 = pui32DATA(data, pDescr->offset);
+		bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
+              }
+              else if (no_of_bits <= 64)
+              {
+                pui64 = pui64DATA(data, pDescr->offset);
+		bitvec_write_field(vector, writeIndex, *pui64, no_of_bits);
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %lu | ", pDescr->sz , *pui64);
+              }
+              else
+              {
+              	return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
+              }
+
+              remaining_bits_len -= no_of_bits;
+              bit_offset += no_of_bits;
+            }
+            /* bitmap was successfully extracted or it was empty */
+
+            pDescr++;
+            break;
+          }
+
+          case CSN_TYPE:
+          {
+            gint16      Status;
+            csnStream_t arT = *ar;
+            LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
+            csnStreamInit(&arT, bit_offset, remaining_bits_len);
+            Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
+            LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
+            if (Status >= 0)
+            {
+              remaining_bits_len  = arT.remaining_bits_len;
+              bit_offset          = arT.bit_offset;
+              pDescr++;
+            }
+            else
+            {
+              /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr);  */
+              return Status;
+            }
+
+            break;
+          }
+
+          default:
+          { /* descriptions of union elements other than above are illegal */
+            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
+          }
+        }
+
+        pDescr = pDescrNext;
+        break;
+      }
+
+      case CSN_EXIST:
+      case CSN_EXIST_LH:
+      {
+        guint8 fExist;
+        unsigned exist = 0;
+        pui8  = pui8DATA(data, pDescr->offset);
+        exist = *pui8;
+	bitvec_write_field(vector, writeIndex, *pui8, 1);
+        writeIndex--;
+        if (CSN_EXIST_LH == pDescr->type)
+        {
+          fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
+        }
+        else
+        {
+	  fExist = bitvec_read_field(vector, writeIndex, 1);
+        }
+        writeIndex--;
+	bitvec_write_field(vector, writeIndex, fExist, 1);
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz, (unsigned)fExist);
+        remaining_bits_len--;
+        bit_offset++;
+        pDescr++;
+
+        if (!exist)
+        {
+          ar->remaining_bits_len  = remaining_bits_len;
+          ar->bit_offset          = bit_offset;
+          return remaining_bits_len;
+        }
+        break;
+      }
+
+      case CSN_NEXT_EXIST:
+      {
+        guint8 fExist;
+
+        pui8  = pui8DATA(data, pDescr->offset);
+
+        /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
+        if ((pDescr->may_be_null) && (remaining_bits_len == 0))
+        { /* no more bits to decode is fine here - end of message detected and allowed */
+
+          /* Skip i entries + this entry */
+          pDescr += pDescr->i + 1;
+
+          break;
+        }
+
+	bitvec_write_field(vector, writeIndex, *pui8, 1);
+        fExist = *pui8;
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+
+        remaining_bits_len--;
+        bit_offset++;
+
+        if (fExist == 0)
+        { /* Skip 'i' entries */
+          pDescr += pDescr->i;
+        }
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_NEXT_EXIST_LH:
+      {
+        guint8 fExist;
+        pui8  = pui8DATA(data, pDescr->offset);
+
+        /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
+        if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
+        { /* no more bits to decode is fine here - end of message detected and allowed */
+
+          /* skip 'i' entries + this entry */
+          pDescr += pDescr->i + 1;
+
+          /* set the data member to "not exist" */
+          //*pui8 = 0;
+          break;
+        }
+
+        /* the "regular" M_NEXT_EXIST_LH description element */
+	bitvec_write_field(vector, writeIndex, *pui8, 1);
+        writeIndex--;
+        fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
+        writeIndex--;
+	bitvec_write_field(vector, writeIndex, fExist, 1);
+        pui8++;
+
+        remaining_bits_len--;
+        bit_offset++;
+
+        if (fExist == 0)
+        { /* Skip 'i' entries */
+          pDescr += pDescr->i;
+        }
+        pDescr++;
+
+        break;
+      }
+
+      case CSN_VARIABLE_BITMAP_1:
+      { /* Bitmap from here and to the end of message */
+
+        //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
+
+        /*no break -
+         * with a length set we have a regular variable length bitmap so we continue */
+      }
+      /* FALL THROUGH */
+      case CSN_VARIABLE_BITMAP:
+      { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
+         * <N: bit (5)> <bitmap: bit(N + offset)>
+         * Bit array with length (in bits) specified in parameter (pDescr->descr)
+         * The result is right aligned!
+         */
+        gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
+
+        no_of_bits += pDescr->i; /* adjusted by offset */
+
+        if (no_of_bits > 0)
+        {
+
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+          { /* extract bits */
+            guint8* pui8 = pui8DATA(data, pDescr->offset);
+            gint16 nB1  = no_of_bits & 0x07;/* no_of_bits Mod 8 */
+
+            if (nB1 > 0)
+            { /* take care of the first byte - it will be right aligned */
+	      bitvec_write_field(vector, writeIndex, *pui8, nB1);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              pui8++;
+              no_of_bits  -= nB1;
+              bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
+              remaining_bits_len -= nB1;
+            }
+
+            /* remaining no_of_bits is a multiple of 8 or 0 */
+            while (no_of_bits > 0)
+            {
+	      bitvec_write_field(vector, writeIndex, *pui8, 8);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              pui8++;
+              no_of_bits -= 8;
+              remaining_bits_len -= 8;
+            }
+          }
+        }
+        pDescr++;
+        break;
+      }
+
+      case CSN_LEFT_ALIGNED_VAR_BMP_1:
+      { /* Bitmap from here and to the end of message */
+
+        //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
+
+        /* no break -
+         * with a length set we have a regular left aligned variable length bitmap so we continue
+         */
+      }
+      /* FALL THROUGH */
+      case CSN_LEFT_ALIGNED_VAR_BMP:
+      { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
+         * <N: bit (5)> <bitmap: bit(N + offset)>
+         * bit array with length (in bits) specified in parameter (pDescr->descr)
+         */
+
+        gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
+
+        no_of_bits += pDescr->i;/* size adjusted by offset */
+
+        if (no_of_bits > 0)
+        {
+          remaining_bits_len -= no_of_bits;
+
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+          { /* extract bits */
+            guint8* pui8 = pui8DATA(data, pDescr->offset);
+            gint16 nB1  = no_of_bits & 0x07;/* no_of_bits Mod 8 */
+
+            while (no_of_bits > 0)
+            {
+	      bitvec_write_field(vector, writeIndex, *pui8, 8);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              pui8++;
+              no_of_bits -= 8;
+            }
+            if (nB1 > 0)
+            {
+	      bitvec_write_field(vector, writeIndex, *pui8, nB1);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              pui8++;
+              no_of_bits  -= nB1;
+              bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
+            }
+          }
+
+        }
+
+        /* bitmap was successfully extracted or it was empty */
+        pDescr++;
+        break;
+      }
+
+      case CSN_PADDING_BITS:
+      { /* Padding from here and to the end of message */
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = ", pDescr->sz);
+        guint8 filler = 0x2b;
+        if (remaining_bits_len > 0)
+        {
+          while (remaining_bits_len > 0)
+          {
+            guint8 bits_to_handle = remaining_bits_len%8;
+            if (bits_to_handle > 0)
+            {
+              /* section 11 of 44.060
+               * The padding bits may be the 'null' string. Otherwise, the
+               * padding bits starts with bit '0', followed by 'spare padding'
+               * < padding bits > ::= { null | 0 < spare padding > ! < Ignore : 1 bit** = < no string > > } ;
+              */
+              guint8 fl = filler&(0xff>>(8-bits_to_handle + 1));
+	      bitvec_write_field(vector, writeIndex, fl, bits_to_handle);
+              LOGPC(DCSN1, LOGL_DEBUG, "%u|", fl);
+              remaining_bits_len -= bits_to_handle;
+              bit_offset += bits_to_handle;
+            }
+            else if (bits_to_handle == 0)
+            {
+	      bitvec_write_field(vector, writeIndex, filler, 8);
+              LOGPC(DCSN1, LOGL_DEBUG, "%u|", filler);
+              remaining_bits_len -= 8;
+              bit_offset += 8;
+            }
+          }
+        }
+        if (remaining_bits_len < 0)
+        {
+          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+
+        /* Padding was successfully extracted or it was empty */
+        pDescr++;
+        break;
+      }
+
+      case CSN_VARIABLE_ARRAY:
+      { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
+         * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
+         * Array with length specified in parameter:
+         *  <count: bit (x)>
+         *  <list: octet(count + offset)>
+         */
+        gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
+
+        count += pDescr->i; /* Adjusted by offset */
+
+        if (count > 0)
+        {
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+          pui8 = pui8DATA(data, pDescr->offset);
+
+          while (count > 0)
+          {
+	    bitvec_write_field(vector, writeIndex, *pui8, 8);
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = 0x%x | ", pDescr->sz , (unsigned)*pui8);
+            pui8++;
+            bit_offset += 8;
+            remaining_bits_len -= 8;
+            count--;
+          }
+        }
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_RECURSIVE_ARRAY:
+      { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
+         *  or more generally:                <list> ::= { <tag> <element> <list> | <EndTag> }
+         *  where <element> ::= bit(value)
+         *        <tag>     ::= 0 | 1
+         *        <EndTag>  ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
+         * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
+         * REMARK: recursive way to specify an array but an iterative implementation!
+         */
+        gint16 no_of_bits        = pDescr->i;
+        guint8  ElementCount = 0;
+        pui8  = pui8DATA(data, pDescr->offset);
+        ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
+        while (ElementCount > 0)
+        { /* tag control shows existence of next list elements */
+	  bitvec_write_field(vector, writeIndex, Tag, 1);
+          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
+          bit_offset++;
+          remaining_bits_len--;
+
+          /* extract and store no_of_bits long element from bitstream */
+	  bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
+          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+          pui8++;
+          ElementCount--;
+
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+          bit_offset += no_of_bits;
+          remaining_bits_len -= no_of_bits;
+        }
+
+	bitvec_write_field(vector, writeIndex, !Tag, 1);
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
+        bit_offset++;
+        remaining_bits_len--;
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_RECURSIVE_TARRAY:
+      { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
+         *  M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
+         * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
+         */
+        gint16 nSizeElement = (gint16)(gint32)pDescr->value;
+        guint8  ElementCount = 0;
+        pui8  = pui8DATA(data, pDescr->offset);
+        /* Store the counted number of elements of the array */
+        ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
+
+        while (ElementCount > 0)
+        { /* tag control shows existence of next list elements */
+	  bitvec_write_field(vector, writeIndex, Tag, 1);
+          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
+          bit_offset++;
+
+          remaining_bits_len--;
+          ElementCount--;
+
+          { /* unpack the following data structure */
+            csnStream_t arT = *ar;
+            gint16      Status;
+            csnStreamInit(&arT, bit_offset, remaining_bits_len);
+            Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
+
+            if (Status >= 0)
+            { /* successful completion */
+              pui8    += nSizeElement;  /* -> to next data element */
+              remaining_bits_len = arT.remaining_bits_len;
+              bit_offset         = arT.bit_offset;
+            }
+            else
+            { /* something went awry */
+              return Status;
+            }
+          }
+
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+        }
+
+	bitvec_write_field(vector, writeIndex, !Tag, 1);
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
+        bit_offset++;
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_RECURSIVE_TARRAY_2:
+      { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
+
+        Tag = REVERSED_TAG;
+
+        /* NO break -
+         * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
+         */
+      }
+      /* FALL THROUGH */
+      case CSN_RECURSIVE_TARRAY_1:
+      { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
+         * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
+         * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
+         */
+        gint16      nSizeElement = (gint16)(gint32)pDescr->value;
+        guint8      ElementCount = 0;
+        guint8      ElementNum   = 0;
+        csnStream_t arT          = *ar;
+        gint16      Status;
+
+        pui8  = pui8DATA(data, pDescr->offset);
+        /* Store the count of the array */
+        ElementCount = *pui8DATA(data, pDescr->i);
+        ElementNum = ElementCount;
+
+        while (ElementCount > 0)
+        { /* get data element */
+          if (ElementCount != ElementNum)
+          {
+	    bitvec_write_field(vector, writeIndex, Tag, 1);
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
+            bit_offset++;
+            remaining_bits_len--;
+          }
+          ElementCount--;
+          LOGPC(DCSN1, LOGL_DEBUG, "%s { | ", pDescr->sz);
+          csnStreamInit(&arT, bit_offset, remaining_bits_len);
+          Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
+          LOGPC(DCSN1, LOGL_DEBUG, "%s } | ", pDescr->sz);
+          if (Status >= 0)
+          { /* successful completion */
+            pui8    += nSizeElement;  /* -> to next */
+            remaining_bits_len = arT.remaining_bits_len;
+            bit_offset         = arT.bit_offset;
+          }
+          else
+          { /* something went awry */
+            return Status;
+          }
+
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+        }
+	bitvec_write_field(vector, writeIndex, !Tag, 1);
+        bit_offset++;
+        remaining_bits_len--;
+        Tag = STANDARD_TAG; /* in case it was set to "reversed" */
+        pDescr++;
+        break;
+      }
+
+      case CSN_FIXED:
+      { /* Verify the fixed bits */
+        guint8  no_of_bits = (guint8) pDescr->i;
+	bitvec_write_field(vector, writeIndex, pDescr->offset, no_of_bits);
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
+        remaining_bits_len   -= no_of_bits;
+        bit_offset += no_of_bits;
+        pDescr++;
+        break;
+      }
+
+      case CSN_CALLBACK:
+      {
+        guint16  no_of_bits;
+        DissectorCallbackFcn_t callback = (DissectorCallbackFcn_t)pDescr->aux_fn;
+        LOGPC(DCSN1, LOGL_DEBUG, "CSN_CALLBACK(%s) | ", pDescr->sz);
+        no_of_bits = callback(vector, writeIndex, pvDATA(data, pDescr->i), pvDATA(data, pDescr->offset));
+        remaining_bits_len -= no_of_bits;
+        bit_offset += no_of_bits;
+        pDescr++;
+        break;
+      }
+
+      case CSN_TRAP_ERROR:
+      {
+        return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
+      }
+
+      case CSN_END:
+      {
+        ar->remaining_bits_len  = remaining_bits_len;
+        ar->bit_offset = bit_offset;
+        return remaining_bits_len;
+      }
+
+      default:
+      {
+        assert(0);
+      }
+
+    }
+
+  } while (remaining_bits_len >= 0);
+
+  return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+}
