diff --git a/compiler2/Type.cc b/compiler2/Type.cc
index 977e28b041599064022f9d07a79ca3bd210ed754..5224e67cd8d52efe683e14375734aec560cf624a 100644
--- a/compiler2/Type.cc
+++ b/compiler2/Type.cc
@@ -3608,8 +3608,28 @@ namespace Common {
         switch (typetype) {
           case T_BOOL:
           case T_INT_A:
-            // TODO: add more types as they are implemented in
-            // the enc/decoding
+          case T_ENUM_A:
+          case T_BSTR_A:
+          case T_OSTR:
+          case T_REAL:
+          case T_NULL:
+          case T_IA5STRING:
+          case T_VISIBLESTRING:
+          case T_NUMERICSTRING:
+          case T_PRINTABLESTRING:
+          case T_BMPSTRING:
+          case T_UNIVERSALSTRING: 
+          case T_UTF8STRING:
+          case T_TELETEXSTRING:
+          case T_VIDEOTEXSTRING:
+          case T_GRAPHICSTRING:
+          case T_GENERALSTRING:
+          case T_OID:
+          case T_ROID:
+          case T_SEQ_A:
+          case T_EMBEDDED_PDV:
+          case T_SEQOF:
+          case T_EXTERNAL:
             return true;
           default:
             return false;
diff --git a/compiler2/Type_chk.cc b/compiler2/Type_chk.cc
index 5ed4470fea0ecf081a01abbe7452955c402c48d3..0bad3de588170cb3ed9ac552f680eab2c8c4bd79 100644
--- a/compiler2/Type_chk.cc
+++ b/compiler2/Type_chk.cc
@@ -2995,65 +2995,113 @@ void Type::chk_xer() { // XERSTUFF semantic check
 }
 
 void Type::chk_oer() {
-  //if (!is_asn1()) return;
   if (oerattrib == NULL) {
     oerattrib = new OerAST();
   }
-  switch (typetype) {
-    case T_BOOL:
-      break;
+  Type* t = get_type_refd_last();
+  switch (t->typetype) {
     case T_INT_A: {
-      if (is_constrained()) {
-        if (get_sub_type()->is_integer_subtype_notempty()) {
-          Location loc;
-          int_limit_t upper = get_sub_type()->get_int_limit(true, &loc);
-          int_limit_t lower = get_sub_type()->get_int_limit(false, &loc);
-          bool lower_inf = lower.get_type() != int_limit_t::NUMBER;
-          bool upper_inf = upper.get_type() != int_limit_t::NUMBER;
-          if (lower_inf || upper_inf) {
-            oerattrib->signed_ = lower_inf;
-            oerattrib->bytes = -1;
+      if (t->is_constrained() && t->get_sub_type()->is_subtype_notempty()) {
+        Location loc;
+        int_limit_t upper = t->get_sub_type()->get_int_limit(true, &loc);
+        int_limit_t lower = t->get_sub_type()->get_int_limit(false, &loc);
+        bool lower_inf = lower.get_type() != int_limit_t::NUMBER;
+        bool upper_inf = upper.get_type() != int_limit_t::NUMBER;
+        if (lower_inf || upper_inf) {
+          oerattrib->signed_ = lower_inf;
+          oerattrib->bytes = -1;
+        } else {
+          int_val_t low = lower.get_value();
+          int_val_t up  = upper.get_value();
+          if (low < 0) {
+            oerattrib->signed_ = true;
+            if (low >= -128 && up <= 127) {
+              oerattrib->bytes = 1;
+            } else if (low >= -32768 && up <= 32767) {
+              oerattrib->bytes = 2;
+            } else if (low >= -2147483648LL && up <= 2147483647) {
+              oerattrib->bytes = 4;
+            } else if ((low+1) >= -9223372036854775807LL && up <= 9223372036854775807LL) {
+              oerattrib->bytes = 8;
+            } else {
+              oerattrib->bytes = -1;
+            }
           } else {
-            int_val_t low = lower.get_value();
-            int_val_t up  = upper.get_value();
-            if (low < 0) {
-              oerattrib->signed_ = true;
-              if (low >= -128 && up <= 127) {
-                oerattrib->bytes = 1;
-              } else if (low >= -32768 && up <= 32767) {
-                oerattrib->bytes = 2;
-              } else if (low >= -2147483648LL && up <= 2147483647) {
-                oerattrib->bytes = 4;
-              } else if ((low+1) >= -9223372036854775807LL && up <= 9223372036854775807LL) {
-                oerattrib->bytes = 8;
-              } else {
-                oerattrib->bytes = -1;
-              }
+            static int_val_t uns_8_byte("18446744073709551615", NULL);
+            oerattrib->signed_ = false;
+            if (up <= 255) {
+              oerattrib->bytes = 1;
+            } else if (up <= 65535) {
+              oerattrib->bytes = 2;
+            } else if (up <= 4294967295LL) {
+              oerattrib->bytes = 4;
+            } else if (up <= uns_8_byte) {
+              oerattrib->bytes = 8;
             } else {
-              static int_val_t uns_8_byte("18446744073709551615", NULL);
-              oerattrib->signed_ = false;
-              if (up <= 255) {
-                oerattrib->bytes = 1;
-              } else if (up <= 65535) {
-                oerattrib->bytes = 2;
-              } else if (up <= 4294967295LL) {
-                oerattrib->bytes = 4;
-              } else if (up <= uns_8_byte) {
-                oerattrib->bytes = 8;
-              } else {
-                oerattrib->bytes = -1;
-              }
+              oerattrib->bytes = -1;
             }
           }
-        } else {
-          oerattrib->signed_ = true;
-          oerattrib->bytes = -1;
         }
       } else {
         oerattrib->signed_ = true;
         oerattrib->bytes = -1;
       }
       break; }
+    case T_BSTR_A:
+    case T_OSTR:
+    case T_IA5STRING:
+    case T_VISIBLESTRING:
+    case T_NUMERICSTRING:
+    case T_PRINTABLESTRING:
+    case T_BMPSTRING:
+    case T_UNIVERSALSTRING:
+    case T_TELETEXSTRING:
+    case T_VIDEOTEXSTRING:
+    case T_GRAPHICSTRING:
+    case T_GENERALSTRING: {
+      if (t->is_constrained() && t->get_sub_type()->is_subtype_notempty()) {
+        Location loc;
+        int_limit_t upper = t->get_sub_type()->get_int_limit(true, &loc);
+        int_limit_t lower = t->get_sub_type()->get_int_limit(false, &loc);
+        bool lower_inf = lower.get_type() != int_limit_t::NUMBER;
+        bool upper_inf = upper.get_type() != int_limit_t::NUMBER;
+        if (!lower_inf && !upper_inf) {
+          int_val_t low = lower.get_value();
+          int_val_t up  = upper.get_value();
+          if (low == up) {
+            oerattrib->length = up.get_val();
+            if (typetype == T_BMPSTRING) {
+              oerattrib->length *= 2;
+            } else if (typetype == T_UNIVERSALSTRING) {
+              oerattrib->length *= 4;
+            }
+          }
+        }
+      }
+      break; }
+    case T_SEQ_A: {
+      // extendable is always false. Probably a bug with is_extendable()
+      if (t->get_sub_type()) {
+        oerattrib->extendable = t->get_sub_type()->is_extendable();
+      }
+      for (size_t i = 0; i < t->get_nof_comps(); i++) {
+        t->get_comp_byIndex(i)->get_type()->chk();
+      }
+      break; }
+    case T_SEQOF: {
+      t->get_ofType()->chk();
+      break;
+    }
+    case T_BOOL:
+    case T_ENUM_A:
+    case T_UTF8STRING:
+    case T_REAL:
+    case T_NULL:
+    case T_OID:
+    case T_ROID:
+    case T_EMBEDDED_PDV:
+    case T_EXTERNAL:
+      break;
     default:
       break;
   }
diff --git a/compiler2/Type_codegen.cc b/compiler2/Type_codegen.cc
index b4a443e5d52893d04b7b5240882aa055f3e657ca..ac2b27cb67362012c029ab46eabfbd3713cb2471 100644
--- a/compiler2/Type_codegen.cc
+++ b/compiler2/Type_codegen.cc
@@ -1087,14 +1087,16 @@ void Type::generate_code_oerdescriptor(output_struct *target)
   
   if (NULL == oerattrib) {
     target->source.global_vars = mputprintf(target->source.global_vars,
-      "const TTCN_OERdescriptor_t %s_oer_ = { -1, FALSE };\n"
+      "const TTCN_OERdescriptor_t %s_oer_ = { -1, FALSE, -1, FALSE };\n"
       , get_genname_own().c_str());
   } else {
     target->source.global_vars = mputprintf(target->source.global_vars,
-      "const TTCN_OERdescriptor_t %s_oer_ = { %i, %s };\n"
+      "const TTCN_OERdescriptor_t %s_oer_ = { %i, %s, %i, %s };\n"
       , get_genname_own().c_str() 
       , oerattrib->bytes
-      , oerattrib->signed_ ? "TRUE" : "FALSE");
+      , oerattrib->signed_ ? "TRUE" : "FALSE"
+      , oerattrib->length
+      , oerattrib->extendable ? "TRUE" : "FALSE");
   }
   
 }
diff --git a/compiler2/encdec.c b/compiler2/encdec.c
index 6cf924bfa75dc9f478af334527ad3bbd7c4278d5..a46403366449568a53f7368e79c79700c921b943 100644
--- a/compiler2/encdec.c
+++ b/compiler2/encdec.c
@@ -83,6 +83,11 @@ void def_encdec(const char *p_classname,
       "int JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&) const;\n"
       "int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean);\n");
   }
+  if(oer) {
+    def = mputprintf(def,
+      "int OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const;\n"
+      "int OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, OER_struct&);\n");
+  }
 
   src=mputprintf(src,
      "void %s::encode(const TTCN_Typedescriptor_t& p_td,"
@@ -143,6 +148,14 @@ void def_encdec(const char *p_classname,
      "    JSON_encode(p_td, tok);\n"
      "    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());\n"
      "    break;}\n"
+     "  case TTCN_EncDec::CT_OER: {\n"
+     "    TTCN_EncDec_ErrorContext ec("
+     "\"While OER-encoding type '%%s': \", p_td.name);\n"
+     "    if(!p_td.oer)\n"
+     "      TTCN_EncDec_ErrorContext::error_internal\n"
+     "        (\"No OER descriptor available for type '%%s'.\", p_td.name);\n"
+     "    OER_encode(p_td, p_buf);\n"
+     "    break;}\n"
      "  default:\n"
      "    TTCN_error(\"Unknown coding method requested to encode"
      " type '%%s'\", p_td.name);\n"
@@ -248,6 +261,15 @@ void def_encdec(const char *p_classname,
      " message was received\", p_td.name);\n"
      "    p_buf.set_pos(tok.get_buf_pos());\n"
      "    break;}\n"
+     "  case TTCN_EncDec::CT_OER: {\n"
+     "    TTCN_EncDec_ErrorContext ec(\"While OER-decoding type '%%s': \","
+     " p_td.name);\n"
+     "    if(!p_td.oer)\n"
+     "      TTCN_EncDec_ErrorContext::error_internal\n"
+     "        (\"No OER descriptor available for type '%%s'.\", p_td.name);\n"
+    "     OER_struct p_oer;\n"
+     "    OER_decode(p_td, p_buf, p_oer);\n"
+     "    break;}\n"
      "  default:\n"
      "    TTCN_error(\"Unknown coding method requested to decode"
      " type '%%s'\", p_td.name);\n"
diff --git a/compiler2/enum.c b/compiler2/enum.c
index ac4e280cd5618d6c135aab884d2d8c3a7d7427ab..1eabf5a5b9cca516719ed04221e7dc798d311814 100644
--- a/compiler2/enum.c
+++ b/compiler2/enum.c
@@ -869,6 +869,63 @@ void defEnumClass(const enum_def *edef, output_struct *output)
       "}\n\n"
       , name, unknown_value, enum_type, unbound_value, unbound_value);
   }
+  
+  if (oer_needed) {
+    // OER encode
+    src = mputprintf(src,
+      "int %s::OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf) const\n"
+      "{\n"
+      "  if (enum_value == %s) {\n"
+      "    TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,\n"
+      "      \"Encoding an unbound value of enumerated type %s.\");\n"
+      "    return -1;\n"
+      "  }\n\n"
+      "  if (enum_value >= 0 && enum_value < 128) {\n"
+      "    char c = enum_value;\n"
+      "    p_buf.put_c(c);\n"
+      "    p_buf.increase_pos(1);\n"
+      "  } else {\n"
+      // This case is the same as encoding a not restricted integer except
+      // the first bit is set to 1 before decoding
+      "    INTEGER intval(enum_value);\n"
+      "    TTCN_Buffer buf;\n"
+      "    intval.OER_encode(INTEGER_descr_, buf);\n"
+      "    unsigned char* uc = const_cast<unsigned char*>(buf.get_data());\n"
+      "    *uc |= 1 << 7;\n"
+      "    p_buf.put_buf(buf);\n"
+      "  }\n"
+      "  return 0;\n"
+      "}\n\n"
+      , name, unbound_value, dispname);
+    
+    // OER decode
+    src = mputprintf(src,
+      "int %s::OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf, OER_struct& p_oer)\n"
+      "{\n"
+      "  const unsigned char* uc = p_buf.get_read_data();\n"
+      "  if (!(uc[0] & 0x80)) {\n"
+      "    if (is_valid_enum(uc[0])) {"
+      "       enum_value = static_cast<%s>(uc[0]);\n"
+      "    } else {\n"
+      "      enum_value = %s;\n"
+      "    }\n"
+      "  } else {\n"
+      // This case is the same as decoding a not restricted integer except
+      // the first bit is set to 0
+      "    unsigned char* uc2 = const_cast<unsigned char*>(p_buf.get_read_data());\n"
+      "    uc2[0] &= ~0x80;\n"
+      "    INTEGER intval;\n"
+      "    intval.OER_decode(INTEGER_descr_, p_buf, p_oer);\n"
+      "    if (is_valid_enum(intval.get_val().get_val())) {\n"
+      "      enum_value = static_cast<%s>(intval.get_val().get_val());\n"
+      "    } else {\n"
+      "      enum_value = %s;\n"
+      "    }\n"
+      "  }\n"
+      "  return 0;\n"
+      "}\n\n"
+      , name, enum_type, unknown_value, enum_type, unknown_value);
+  }
   /* end of class */
   def = mputstr(def, "};\n\n");
 
diff --git a/compiler2/record.c b/compiler2/record.c
index 3c82e6eb469c77ea6bc56ae35fd8afcc3f9d5dcd..d15ddc1002aea46190e1df7969c9886031a0e9f4 100644
--- a/compiler2/record.c
+++ b/compiler2/record.c
@@ -4652,6 +4652,142 @@ void defRecordClass1(const struct_def *sdef, output_struct *output)
     src = mputstr(src, "}\n\n");
   }
   
+  if (oer_needed) {
+    // OER encode, RT1
+    src = mputprintf(src,
+      "int %s::OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf) const\n"
+      "{\n"
+      "  if (!is_bound()) {\n" 
+      "  TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,\n"
+      "    \"Encoding an unbound %s value.\");\n"
+      "  return -1;\n"
+      "  }\n", name, sdef->kind == SET ? "set" : "record");
+    size_t opt_elements = 0;
+    for (i = 0; i < sdef->nElements; i++) {
+      if (sdef->elements[i].isOptional || sdef->elements[i].isDefault) {
+        opt_elements++;
+      }
+    }
+    int needed_bytes = opt_elements / 8 + 1;
+
+    if (opt_elements != 0) {
+      src = mputprintf(src,
+        "  unsigned char c[%i] = {0};\n"
+        , needed_bytes);
+    }
+    int ind = 0;
+    int pos = 8;
+    for (i = 0; i < sdef->nElements; i++) {
+      if (sdef->elements[i].isOptional || sdef->elements[i].isDefault) {
+        pos--;
+        src = mputprintf(src,
+          "  if (field_%s.is_present()) {\n"
+          "    c[%i] += 1 << %i;\n"
+          "  }\n"
+          , sdef->elements[i].name, ind, pos);
+        if (pos == 0) {
+          pos = 8;
+          ind++;
+        }
+      }
+    }
+    if (opt_elements != 0) {
+      src = mputprintf(src,
+        "  p_buf.put_s(%i, c);\n"
+        , needed_bytes);
+    }
+    for (i = 0; i < sdef->nElements; i++) {
+      if (sdef->elements[i].isOptional || sdef->elements[i].isDefault) {
+        src = mputprintf(src,
+          "  if (field_%s.is_present())\n  "
+          , sdef->elements[i].name);
+      }
+      src = mputprintf(src,
+        "  field_%s.OER_encode(%s_descr_, p_buf);\n"
+        , sdef->elements[i].name, sdef->elements[i].typedescrname);
+    }
+    src = mputstr(src,
+      "  return 0;\n"
+      "}\n\n");
+    
+    // OER decode, RT1
+    src = mputprintf(src,
+      "int %s::OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf, OER_struct& p_oer)\n"
+      "{\n", name);
+    if (opt_elements != 0) {
+      src = mputprintf(src, 
+        "  const unsigned char* uc = p_buf.get_read_data();\n"
+        "  p_buf.increase_pos(%i);\n"
+        , needed_bytes);
+    }
+    ind = 0;
+    pos = 8;
+    for (i = 0; i < sdef->nElements; i++) {
+      if (sdef->elements[i].isOptional || sdef->elements[i].isDefault) {
+        pos--;
+          src = mputprintf(src,
+            "  if (uc[%i] & (1 << %i))\n"
+            "    field_%s.OER_decode(%s_descr_, p_buf, p_oer);\n"
+            , ind, pos, sdef->elements[i].name
+            , sdef->elements[i].typedescrname);
+          if (sdef->elements[i].isOptional) {
+            src = mputprintf(src, " else\n"
+              "    field_%s = OMIT_VALUE;\n"
+              , sdef->elements[i].name);
+          }
+        if (pos == 0) {
+          ind++;
+          pos = 8;
+        }
+      } else {
+        src = mputprintf(src,
+          "  field_%s.OER_decode(%s_descr_, p_buf, p_oer);\n"
+          , sdef->elements[i].name
+          , sdef->elements[i].typedescrname);
+      }
+    }
+    if (sdef->has_opentypes) {
+      src = mputstr(src,
+        "  TTCN_EncDec_ErrorContext ec_1(\"While decoding opentypes: \");"
+        "  TTCN_Type_list p_typelist;\n"
+        "  OER_decode_opentypes(p_typelist, p_buf, p_oer);\n");
+    }
+    src = mputstr(src, 
+      "  return 0;\n"
+      "}\n\n");
+  }
+  
+  if(sdef->has_opentypes) {
+    /* OER_decode_opentypes() */
+    def=mputstr
+      (def,
+       "void OER_decode_opentypes(TTCN_Type_list& p_typelist, TTCN_Buffer& p_buf, OER_struct& p_oer);\n");
+    src=mputprintf
+      (src,
+       "void %s::OER_decode_opentypes(TTCN_Type_list& p_typelist, TTCN_Buffer& p_buf, OER_struct& p_oer)\n"
+       "{\n"
+       "  p_typelist.push(this);\n"
+       "  TTCN_EncDec_ErrorContext ec_0(\"Component '\");\n"
+       "  TTCN_EncDec_ErrorContext ec_1;\n"
+       , name
+       );
+    for(i=0; i<sdef->nElements; i++) {
+      src=mputprintf
+        (src,
+         "  ec_1.set_msg(\"%s': \");\n"
+         "  field_%s.OER_decode_opentypes(p_typelist, p_buf, p_oer);\n"
+         , sdef->elements[i].dispname
+         , sdef->elements[i].name
+         );
+    } /* for i */
+    src=mputstr
+      (src,
+       "  p_typelist.pop();\n"
+       "}\n"
+       "\n"
+       );
+    } /* if sdef->has_opentypes */
+  
   /* end of class definition */
   def = mputstr(def, "};\n\n");
 
@@ -6183,6 +6319,30 @@ static void defEmptyRecordClass(const struct_def *sdef,
       "}\n\n"
       , name);
   }
+    
+  if (oer_needed) {
+    // OER encode, RT1
+    src = mputprintf(src,
+      "int %s::OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const\n"
+      "{\n"
+      "  if (!is_bound()) {\n"
+      "    TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,\n"
+      "      \"Encoding an unbound value of type %s.\");\n"
+      "    return -1;\n"
+      "  }\n\n"
+      "  return 0;\n"
+      "}\n\n"
+      , name, dispname);
+    
+    // OER decode, RT1
+    src = mputprintf(src,
+      "int %s::OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, OER_struct&)\n"
+      "{\n"
+      "  bound_flag = TRUE;\n"
+      "  return 0;\n"
+      "}\n\n"
+      , name);
+  }
 
     /* closing class definition */
     def = mputstr(def, "};\n\n");
diff --git a/compiler2/record_of.c b/compiler2/record_of.c
index 2979cb8dff8f3aa09a1f84192e8e56a5798f5f48..ef490901aab14ad0757dde353be68906d1cd6fa7 100644
--- a/compiler2/record_of.c
+++ b/compiler2/record_of.c
@@ -1637,6 +1637,61 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output)
       "}\n\n"
       , name, type, type, type);
   }
+  if (oer_needed) {
+    // OER encode, RT1
+    src = mputprintf(src,
+      "int %s::OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const\n"
+      "{\n"
+      "  if (!is_bound()) {\n"
+      "    TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,\n"
+      "      \"Encoding an unbound value of type %s.\");\n"
+      "    return -1;\n"
+      "  }\n\n"
+      "  encode_oer_length(val_ptr->n_elements, p_buf, TRUE);\n"
+      "  for (int i = 0; i < val_ptr->n_elements; ++i) {\n"
+      "    (*this)[i].OER_encode(*p_td.oftype_descr, p_buf);\n"
+      "  }\n"
+      "  return 0;\n"
+      "}\n\n"
+      , name, dispname);
+    
+    // OER decode, RT1
+    src = mputprintf(src,
+      "int %s::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, OER_struct& p_oer)\n"
+      "{\n"
+      "  size_t nof_elem = decode_oer_length(p_buf, TRUE);\n"
+      "  set_size(nof_elem);\n"
+      "  for (size_t i = 0; i < nof_elem; i++) {\n"
+      "    (*this)[i].OER_decode(*p_td.oftype_descr, p_buf, p_oer);\n"
+      "  }\n"
+      "  return 0;\n"
+      "}\n\n"
+      , name);
+    
+    if(sdef->has_opentypes) {
+      /* OER_decode_opentypes() */
+      def=mputstr
+        (def,
+         "void OER_decode_opentypes(TTCN_Type_list& p_typelist, TTCN_Buffer& p_buf, OER_struct& p_oer);\n");
+      src=mputprintf
+        (src,
+         "void %s::OER_decode_opentypes(TTCN_Type_list& p_typelist, TTCN_Buffer& p_buf, OER_struct& p_oer)\n"
+         "{\n"
+         "  p_typelist.push(this);\n"
+         "  TTCN_EncDec_ErrorContext ec_0(\"Component #\");\n"
+         "  TTCN_EncDec_ErrorContext ec_1;\n"
+         "  for(int elem_i=0; elem_i<n_elements; elem_i++) {\n"
+         "    ec_1.set_msg(\"%%d: \", elem_i);\n"
+         "    value_elements[elem_i].OER_decode_opentypes(p_typelist,"
+         " p_buf, p_oer);\n"
+         "  }\n"
+         "  p_typelist.pop();\n"
+         "}\n"
+         "\n"
+         , name
+         );
+    }
+  }
   /* end of class */
   def = mputstr(def, "};\n\n");
 
@@ -3088,6 +3143,61 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct
       "}\n\n"
       , name, type);
   }
+  if (oer_needed) {
+    // OER encode, RT1, mem. alloc. optimised
+    src = mputprintf(src,
+      "int %s::OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const\n"
+      "{\n"
+      "  if (!is_bound()) {\n"
+      "    TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,\n"
+      "      \"Encoding an unbound value of type %s.\");\n"
+      "    return -1;\n"
+      "  }\n\n"
+      "  encode_oer_length(n_elements, p_buf, TRUE);\n"
+      "  for (int i = 0; i < n_elements; ++i) {\n"
+      "    value_elements[i].OER_encode(*p_td.oftype_descr, p_buf);\n"
+      "  }\n"
+      "  return 0;\n"
+      "}\n\n"
+      , name, dispname);
+    
+    // OER decode, RT1, mem. alloc. optimised
+    src = mputprintf(src,
+      "int %s::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, OER_struct& p_oer)\n"
+      "{\n"
+      "  size_t nof_elem = decode_oer_length(p_buf, TRUE);\n"
+      "  set_size(nof_elem);\n"
+      "  for (size_t i = 0; i < nof_elem; i++) {\n"
+      "    (*this)[i].OER_decode(*p_td.oftype_descr, p_buf, p_oer);\n"
+      "  }\n"
+      "  return 0;\n"
+      "}\n\n"
+      , name);
+    
+    if(sdef->has_opentypes) {
+      /* OER_decode_opentypes() */
+      def=mputstr
+        (def,
+         "void OER_decode_opentypes(TTCN_Type_list& p_typelist, TTCN_Buffer& p_buf, OER_struct& p_oer);\n");
+      src=mputprintf
+        (src,
+         "void %s::OER_decode_opentypes(TTCN_Type_list& p_typelist, TTCN_Buffer& p_buf, OER_struct& p_oer)\n"
+         "{\n"
+         "  p_typelist.push(this);\n"
+         "  TTCN_EncDec_ErrorContext ec_0(\"Component #\");\n"
+         "  TTCN_EncDec_ErrorContext ec_1;\n"
+         "  for(int elem_i=0; elem_i<n_elements; elem_i++) {\n"
+         "    ec_1.set_msg(\"%%d: \", elem_i);\n"
+         "    value_elements[elem_i].OER_decode_opentypes(p_typelist,"
+         " p_buf, p_oer);\n"
+         "  }\n"
+         "  p_typelist.pop();\n"
+         "}\n"
+         "\n"
+         , name
+         );
+    }
+  }
   /* end of class */
   def = mputstr(def, "};\n\n");
 
diff --git a/compiler2/subtype.hh b/compiler2/subtype.hh
index 37d259193d508b1b84a5ac588262c5cfd8fd0394..a18ed840aa7b2541eb5a0c1ad7b6521e2cd083fe 100644
--- a/compiler2/subtype.hh
+++ b/compiler2/subtype.hh
@@ -218,8 +218,19 @@ public:
   bool is_length_compatible(const SubtypeConstraint *p_st) const;
   bool is_upper_limit_infinity() const;
   bool is_lower_limit_infinity() const;
-  bool is_integer_subtype_notempty() const
-    { return subtype==ST_INTEGER && integer_st && !integer_st->is_empty(); }
+  bool is_subtype_notempty() const
+    { size_limit_t sl;
+      return (subtype==ST_INTEGER && integer_st && !integer_st->is_empty()) ||
+      (subtype==ST_BITSTRING && bitstring_st && !bitstring_st->is_empty()) ||
+      (subtype==ST_HEXSTRING && hexstring_st && !hexstring_st->is_empty()) ||
+      (subtype==ST_OCTETSTRING && octetstring_st && !octetstring_st->is_empty()) ||
+      (subtype==ST_CHARSTRING && charstring_st && 
+        charstring_st->get_size_limit(false, sl) == TTRUE &&
+        charstring_st->get_size_limit(true, sl) == TTRUE) ||
+      (subtype==ST_UNIVERSAL_CHARSTRING && universal_charstring_st &&
+        universal_charstring_st->get_size_limit(false, sl) == TTRUE &&
+        universal_charstring_st->get_size_limit(true, sl) == TTRUE);
+    }
 };
 
 /**
diff --git a/compiler2/ttcn3/OerAST.cc b/compiler2/ttcn3/OerAST.cc
index d9c3d2c332cea5160ba802454b903ef7c99a56aa..a4a754150c1b9d096655d4a59219d72fd2a7171e 100644
--- a/compiler2/ttcn3/OerAST.cc
+++ b/compiler2/ttcn3/OerAST.cc
@@ -12,10 +12,13 @@
 #include "OerAST.hh"
 
 OerAST::OerAST() :
-  bytes(0),
-  signed_(false)
+  bytes(-1),
+  signed_(false),
+  length(-1),
+  extendable(false)
 {}
 
 bool OerAST::empty() const {
-  return bytes == 0 && signed_ == false;
+  return bytes == -1 && signed_ == false && length == -1 &&
+    extendable == false;
 }
diff --git a/compiler2/ttcn3/OerAST.hh b/compiler2/ttcn3/OerAST.hh
index 97bc58c55c5190ac15aad173fd7fc23b7b5e18dd..eb047006fb8429fdad40358af1543f13ab8240fa 100644
--- a/compiler2/ttcn3/OerAST.hh
+++ b/compiler2/ttcn3/OerAST.hh
@@ -16,6 +16,8 @@ class OerAST {
 public:
   int bytes;
   bool signed_;
+  int length;
+  bool extendable;
   
   OerAST();
   bool empty() const;
diff --git a/compiler2/union.c b/compiler2/union.c
index a61dec8f90223d10fe39fe39ec637f2838f3ee2a..831af099abf18bdd3bd49eda075f191e832c6397 100644
--- a/compiler2/union.c
+++ b/compiler2/union.c
@@ -2368,6 +2368,191 @@ void defUnionClass(struct_def const *sdef, output_struct *output)
     }
   }
 
+  if (oer_needed) {
+    // OER encode
+    src = mputprintf(src,
+      "int %s::OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf) const\n"
+      "{\n", name);
+    src = mputstr(src, "  switch(union_selection) {\n");
+    for (i = 0; i < sdef->nElements; ++i) {
+      src = mputprintf(src, "  case %s_%s:\n", selection_prefix, sdef->elements[i].name);
+      if (sdef->has_opentypes == FALSE) {
+        src = mputprintf(src,
+          "    encode_oer_tag(*%s_descr_.ber, p_buf);\n"
+          "    field_%s->OER_encode(%s_descr_, p_buf);\n"
+          "    break;\n"
+          , sdef->elements[i].typedescrname, sdef->elements[i].name, sdef->elements[i].typedescrname);
+      } else {
+        src = mputprintf(src,
+          "    {\n"
+          "    TTCN_Buffer buf;\n"
+          "    field_%s->OER_encode(%s_descr_, buf);\n"
+          "    encode_oer_length(buf.get_len(), p_buf, FALSE);\n"
+          "    p_buf.put_buf(buf);\n"
+          "    break; }\n"
+          , sdef->elements[i].name, sdef->elements[i].typedescrname);
+      }
+    }
+    src = mputprintf(src, 
+      "  default:\n"
+      "    TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, \n"
+      "      \"Encoding an unbound value of type %s.\");\n"
+      "    return -1;\n"
+      "  }\n\n"
+      , dispname);
+    src = mputstr(src,
+      "  return 0;\n"
+      "}\n");
+    
+    if (use_runtime_2) {
+      // OER encode for negative testing
+      def = mputstr(def,
+        "int OER_encode_negtest(const Erroneous_descriptor_t*, "
+        "const TTCN_Typedescriptor_t&, TTCN_Buffer&) const;\n");
+     //todo
+    }
+    // OER decode
+    src = mputprintf(src,
+      "int %s::OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf, OER_struct& p_oer)\n"
+      "{\n", name);
+    if (sdef->ot == NULL) {
+      src = mputstr(src, 
+        "  const ASN_Tag_t& descr = decode_oer_tag(p_buf);\n");
+      for (i = 0; i < sdef->nElements; ++i) {
+        src = mputprintf(src,
+          "  if (%s_descr_.ber->tags[%s_descr_.ber->n_tags-1].tagclass == descr.tagclass &&\n"
+          "      %s_descr_.ber->tags[%s_descr_.ber->n_tags-1].tagnumber == descr.tagnumber) {\n"
+          "    %s%s().OER_decode(%s_descr_, p_buf, p_oer);\n"
+          "  } else \n"
+          , sdef->elements[i].typedescrname, sdef->elements[i].typedescrname, sdef->elements[i].typedescrname
+          , sdef->elements[i].typedescrname, at_field, sdef->elements[i].name, sdef->elements[i].typedescrname);
+      }
+      src = mputprintf(src,
+      "{\n"
+      "    TTCN_error(\"Cannot find matching tag for type %s\");\n"
+      "}\n", name);
+    } else {
+      src = mputstr(src,
+        "  size_t pos = decode_oer_length(p_buf, FALSE);\n"
+        "  size_t prev_pos = p_buf.get_pos();\n"
+        "  p_buf.increase_pos(pos);\n"
+        "  p_oer.opentype_poses.push_back(prev_pos);\n"
+        );
+    }
+    src = mputstr(src, "  return 0;\n}\n");
+      
+    if (sdef->ot || sdef->has_opentypes) { /* theoretically, these are
+                                             mutually exlusive */
+      /* OER_decode_opentypes() */
+      def = mputstr(def, "void OER_decode_opentypes("
+	  "TTCN_Type_list& p_typelist, TTCN_Buffer& p_buf, OER_struct& p_oer);\n");
+      src = mputprintf(src, "void %s::OER_decode_opentypes("
+	  "TTCN_Type_list& p_typelist, TTCN_Buffer& p_buf, OER_struct& p_oer)\n"
+	"{\n", name);
+      if (sdef->ot) {
+	AtNotationList_t *anl = &sdef->ot->anl;
+	OpentypeAlternativeList_t *oal = &sdef->ot->oal;
+        src = mputprintf(src,
+	  "  if (union_selection != %s) return;\n"
+	  "  TTCN_EncDec_ErrorContext ec_0(\"While decoding open type '%s': "
+	    "\");\n", unbound_value, dispname);
+        if (oal->nElements > 0) {
+	  size_t oal_i, anl_i;
+	  char *s2;
+          /* variable declarations - the referenced components */
+          for (anl_i = 0; anl_i < anl->nElements; anl_i++) {
+            AtNotation_t *an = anl->elements + anl_i;
+            src = mputprintf(src, "  const %s& f_%lu = static_cast<const %s*>"
+	      "(p_typelist.get_nth(%lu))->%s;\n", an->type_name,
+              (unsigned long) (anl_i + 1), an->parent_typename,
+	      (unsigned long) an->parent_level, an->sourcecode);
+          } /* for anl_i */
+          src = mputstr(src, "  {\n"
+	    "    TTCN_EncDec_ErrorContext ec_1(\"Alternative '\");\n"
+	    "    TTCN_EncDec_ErrorContext ec_2;\n");
+          s2 = mprintf("%*s", (int)(anl->nElements + 2) * 2, "");
+          for (oal_i = 0; oal_i < oal->nElements; oal_i++) {
+	    size_t if_level;
+	    OpentypeAlternative_t *oa = oal->elements + oal_i;
+            if (oal_i > 0) {
+              for (if_level = 0; if_level < anl->nElements; if_level++)
+                if (oa->const_valuenames[if_level]) break;
+              for (i = anl->nElements; i > if_level; i--)
+                src = mputprintf(src, "%*s}\n", (int)(i + 1) * 2, "");
+            } /* if oal_i */
+            else if_level = 0;
+            for (anl_i = if_level; anl_i < anl->nElements; anl_i++) {
+	      src = mputprintf(src, "%*s%sif (f_%lu == %s) {\n",
+		(int)(anl_i + 2) * 2, "",
+		oal_i && anl_i <= if_level ? "else " : "",
+                (unsigned long) (anl_i + 1), oa->const_valuenames[anl_i]);
+            } /* for anl_i */
+	    src = mputprintf(src, "%sunion_selection = %s_%s;\n"
+	      "%sfield_%s = new %s;\n"
+	      "%sec_2.set_msg(\"%s': \");\n"
+        "size_t pos = p_buf.get_pos();\n"
+        "p_buf.set_pos(p_oer.opentype_poses.at(0));\n"
+        "p_oer.opentype_poses.erase_at(0);\n"
+        "OER_struct tmp_oer;\n"
+	      "%sfield_%s->OER_decode(%s_descr_, p_buf, tmp_oer);\n"
+        "p_buf.set_pos(pos);\n",
+	      s2, selection_prefix, oa->alt, s2, oa->alt, oa->alt_typename, s2,
+	      oa->alt_dispname, s2, oa->alt, oa->alt_typedescrname);
+          } /* for oal_i */
+          Free(s2);
+          if (oal->nElements > 0)
+            for (i = anl->nElements; i > 0; i--)
+              src = mputprintf(src, "%*s}\n", (int)(i+1)*2, "");
+          src = mputprintf(src, "  }\n"
+	    "  if (union_selection == %s) {\n"
+	    "    ec_0.error(TTCN_EncDec::ET_DEC_OPENTYPE, \"Cannot decode "
+	      "open type: broken component relation constraint.\");\n"
+	    "    if (TTCN_EncDec::get_error_behavior("
+	      "TTCN_EncDec::ET_DEC_OPENTYPE) != TTCN_EncDec::EB_IGNORE) {\n"
+	    "      TTCN_Logger::log_str(TTCN_WARNING, \"The value%s of"
+	    " constraining component%s:\");\n", unbound_value,
+	    anl->nElements > 1 ? "s" : "", anl->nElements > 1 ? "s" : "");
+          for (anl_i = 0; anl_i < anl->nElements; anl_i++) {
+            AtNotation_t *an = anl->elements + anl_i;
+            src = mputprintf(src,
+	      "      TTCN_Logger::begin_event(TTCN_WARNING);\n"
+	      "      TTCN_Logger::log_event_str(\"Component '%s': \");\n"
+	      "      f_%lu.log();\n"
+	      "      TTCN_Logger::end_event();\n", an->dispname,
+              (unsigned long) (anl_i + 1));
+          } /* for anl_i */
+          src = mputstr(src, "    }\n"
+	    "  }\n");
+        } /* if oal->nElements>0 */
+        else {
+          src = mputstr(src, "  ec_0.error(TTCN_EncDec::ET_DEC_OPENTYPE, "
+	      "\"Cannot decode open type: the constraining object set is "
+	      "empty.\");\n");
+        } /* oal->nElements==0 */
+      } /* if sdef->ot */
+      else { /* if !sdef->ot (but has_opentypes) */
+        src = mputstr(src,
+	  "  p_typelist.push(this);\n"
+	  "  TTCN_EncDec_ErrorContext ec_0(\"Alternative '\");\n"
+	  "  TTCN_EncDec_ErrorContext ec_1;\n"
+	  "  switch (union_selection) {\n");
+        for (i = 0; i < sdef->nElements; i++) {
+          src = mputprintf(src, "  case %s_%s:\n"
+	    "    ec_1.set_msg(\"%s': \");\n"
+	    "    field_%s->OER_decode_opentypes(p_typelist, p_buf, p_oer);\n"
+	    "    break;\n", selection_prefix, sdef->elements[i].name,
+	    sdef->elements[i].dispname, sdef->elements[i].name);
+        } /* for i */
+        src = mputstr(src, "  default:\n"
+	  "    break;\n"
+	  "  }\n"
+	  "  p_typelist.pop();\n");
+      } /* if has opentypes */
+      src = mputstr(src, "}\n"
+	"\n");
+    } /* if sdef->ot || sdef->has_opentypes */
+  }
+
   /* end of class definition */
   def = mputstr(def, "};\n\n");
 
diff --git a/core/ASN_EmbeddedPDV.cc b/core/ASN_EmbeddedPDV.cc
index e5bb066adb6ba234a8868428cb4524cee3163714..7e262a7dbc2b865db32800446d255374a214b788 100644
--- a/core/ASN_EmbeddedPDV.cc
+++ b/core/ASN_EmbeddedPDV.cc
@@ -30,6 +30,7 @@
 #include "ASN_EmbeddedPDV.hh"
 
 #include "../common/dbgnew.hh"
+#include "OER.hh"
 
 /*
 
@@ -881,6 +882,68 @@ int EMBEDDED_PDV_identification::XER_decode(const XERdescriptor_t& p_td,
   return 1;
 }
 
+int EMBEDDED_PDV_identification::OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const {
+  switch (union_selection) {
+  case ALT_syntaxes:
+    p_buf.put_c(128); // tag
+    field_syntaxes->OER_encode(p_td, p_buf);
+    break;
+  case ALT_syntax:
+    p_buf.put_c(129);
+    field_syntax->OER_encode(OBJID_descr_, p_buf);
+    break;
+  case ALT_presentation__context__id:
+    p_buf.put_c(130);
+    field_presentation__context__id->OER_encode(INTEGER_descr_, p_buf);
+    break;
+  case ALT_context__negotiation:
+    p_buf.put_c(131);
+    field_context__negotiation->OER_encode(p_td, p_buf);
+    break;
+  case ALT_transfer__syntax:
+    p_buf.put_c(132);
+    field_transfer__syntax->OER_encode(OBJID_descr_, p_buf);
+    break;
+  case ALT_fixed:
+    p_buf.put_c(133);
+    field_fixed->OER_encode(p_td, p_buf);
+    break;
+  default:
+    TTCN_EncDec_ErrorContext::error_internal("Unknown selection.");
+    break;
+  }
+  return 0;
+}
+
+int EMBEDDED_PDV_identification::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, OER_struct& p_oer) {
+  const unsigned char* uc = p_buf.get_read_data();
+  p_buf.increase_pos(1);
+  switch (uc[0]) {
+  case 128:
+    syntaxes().OER_decode(p_td, p_buf, p_oer);
+    break;
+  case 129:
+    syntax().OER_decode(OBJID_descr_, p_buf, p_oer);
+    break;
+  case 130:
+    presentation__context__id().OER_decode(INTEGER_descr_, p_buf, p_oer);
+    break;
+  case 131:
+    context__negotiation().OER_decode(p_td, p_buf, p_oer);
+    break;
+  case 132:
+    transfer__syntax().OER_decode(OBJID_descr_, p_buf, p_oer);
+    break;
+  case 133:
+    fixed().OER_decode(p_td, p_buf, p_oer);
+    break;
+  default:
+    TTCN_EncDec_ErrorContext::error_internal("Unknown selection.");
+    break;
+  }
+  return 0;
+}
+
 /******************** EMBEDDED_PDV_identification_template ********************/
 
 void EMBEDDED_PDV_identification_template::clean_up()
@@ -1827,6 +1890,18 @@ int EMBEDDED_PDV_identification_syntaxes::XER_decode(const XERdescriptor_t& /*p_
   return 0; // TODO maybe return proper value
 }
 
+int EMBEDDED_PDV_identification_syntaxes::OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf) const {
+  field_abstract.OER_encode(OBJID_descr_, p_buf);
+  field_transfer.OER_encode(OBJID_descr_, p_buf);
+  return 0;
+}
+
+int EMBEDDED_PDV_identification_syntaxes::OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf, OER_struct& p_oer) {
+  field_abstract.OER_decode(OBJID_descr_, p_buf, p_oer);
+  field_transfer.OER_decode(OBJID_descr_, p_buf, p_oer);
+  return 0;
+}
+
 /******************** EMBEDDED_PDV_identification_syntaxes_template ********************/
 
 struct EMBEDDED_PDV_identification_syntaxes_template::single_value_struct {
@@ -2571,6 +2646,18 @@ int EMBEDDED_PDV_identification_context__negotiation::XER_decode(
   return 0; // TODO sensible return value
 }
 
+int EMBEDDED_PDV_identification_context__negotiation::OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf) const {
+  field_presentation__context__id.OER_encode(INTEGER_descr_, p_buf);
+  field_transfer__syntax         .OER_encode(OBJID_descr_, p_buf);
+  return 0;
+}
+
+int EMBEDDED_PDV_identification_context__negotiation::OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf, OER_struct& p_oer) {
+  field_presentation__context__id.OER_decode(INTEGER_descr_, p_buf, p_oer);
+  field_transfer__syntax         .OER_decode(OBJID_descr_, p_buf, p_oer);
+  return 0;
+}
+
 struct EMBEDDED_PDV_identification_context__negotiation_template::single_value_struct {
   INTEGER_template field_presentation__context__id;
   OBJID_template field_transfer__syntax;
@@ -3273,6 +3360,12 @@ void EMBEDDED_PDV::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
     TTCN_EncDec_ErrorContext::error_internal
       ("No JSON descriptor available for type '%s'.", p_td.name);
     break;}
+  case TTCN_EncDec::CT_OER: {
+    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_encode(p_td, p_buf);
+    break;}
   default:
     TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
   }
@@ -3321,6 +3414,13 @@ void EMBEDDED_PDV::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
     TTCN_EncDec_ErrorContext::error_internal
       ("No JSON descriptor available for type '%s'.", p_td.name);
     break;}
+  case TTCN_EncDec::CT_OER: {
+      TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_struct p_oer;
+    OER_decode(p_td, p_buf, p_oer);
+    break;}
   default:
     TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
   }
@@ -3445,6 +3545,23 @@ int EMBEDDED_PDV::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
   return 1;
 }
 
+int EMBEDDED_PDV::OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const {
+  if(!is_bound()) {
+    TTCN_EncDec_ErrorContext::error
+      (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
+  }
+  field_identification.OER_encode(p_td, p_buf);
+  encode_oer_length(field_data__value.lengthof(), p_buf, FALSE);
+  p_buf.put_os(field_data__value);
+  return 0;
+}
+
+int EMBEDDED_PDV::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, OER_struct& p_oer) {
+  field_identification.OER_decode(p_td, p_buf, p_oer);
+  field_data__value.OER_decode(OCTETSTRING_descr_, p_buf, p_oer);
+  return 0;
+}
+
 struct EMBEDDED_PDV_template::single_value_struct {
   EMBEDDED_PDV_identification_template field_identification;
   UNIVERSAL_CHARSTRING_template field_data__value__descriptor;
diff --git a/core/ASN_EmbeddedPDV.hh b/core/ASN_EmbeddedPDV.hh
index 456ff2c860a2cbec2d4e8898a112efb2c9f21133..1e2ead679a95d464892aacba4502476ff5cfcc07 100644
--- a/core/ASN_EmbeddedPDV.hh
+++ b/core/ASN_EmbeddedPDV.hh
@@ -102,6 +102,8 @@ public:
                  TTCN_Buffer& p_buf, unsigned int flavor, unsigned int flavor2, int indent, embed_values_enc_struct_t*) const;
   int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
                  unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*);
+  int OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer&) const;
+  int OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer&, OER_struct&);
 private:
   boolean BER_decode_set_selection(const ASN_BER_TLV_t& p_tlv);
 public:
@@ -224,6 +226,8 @@ public:
   boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, unsigned L_form);
   int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, unsigned int, int, embed_values_enc_struct_t*) const;
   int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, unsigned int, embed_values_dec_struct_t*);
+  int OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer&) const;
+  int OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer&, OER_struct&);
 };
 
 class EMBEDDED_PDV_identification_syntaxes_template : public Base_Template {
@@ -331,6 +335,8 @@ public:
   boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, unsigned L_form);
   int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, unsigned int, int, embed_values_enc_struct_t*) const;
   int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, unsigned int, embed_values_dec_struct_t*);
+  int OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const;
+  int OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, OER_struct&);
 };
 
 class EMBEDDED_PDV_identification_context__negotiation_template : public Base_Template {
@@ -444,6 +450,8 @@ public:
   boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, unsigned L_form);
   int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, unsigned int, int, embed_values_enc_struct_t*) const;
   int XER_decode(const XERdescriptor_t&, XmlReaderWrap&, unsigned int, unsigned int, embed_values_dec_struct_t*);
+  int OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const;
+  int OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, OER_struct&);
 };
 
 class EMBEDDED_PDV_template : public Base_Template {
diff --git a/core/ASN_External.cc b/core/ASN_External.cc
index be83c7c082badb1682c29bcf4daeff52d0f712ee..abe554dba9b2234dc1464d3122fdcd10774c73bb 100644
--- a/core/ASN_External.cc
+++ b/core/ASN_External.cc
@@ -40,6 +40,7 @@
 #include "Addfunc.hh"
 
 #include "../common/dbgnew.hh"
+#include "OER.hh"
 
 /*
  * This type is used to BER encode/decode the EXTERNAL type.
@@ -120,6 +121,8 @@ namespace { /* anonymous namespace */
                    TTCN_Buffer& p_buf, unsigned int flavor, unsigned int flavor2, int indent, embed_values_enc_struct_t*) const;
     int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
                    unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*);
+    int OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const;
+    int OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, OER_struct& p_oer);
   private:
     boolean BER_decode_set_selection(const ASN_BER_TLV_t& p_tlv);
   public:
@@ -178,6 +181,8 @@ namespace { /* anonymous namespace */
                    TTCN_Buffer& p_buf, unsigned int flavor, unsigned int flavor2, int indent, embed_values_enc_struct_t*) const;
     int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
                    unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*);
+    int OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const;
+    int OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, OER_struct& p_oer);
   };
 
   /** Transform the information from the visible format to the encoding format
@@ -505,6 +510,48 @@ namespace { /* anonymous namespace */
     bail:
     return 0; // FIXME return value
   }
+  
+  int EXTERNALtransfer_encoding::OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf) const {
+    switch (union_selection) {
+    case ALT_single__ASN1__type:
+      encode_oer_tag(*EXTERNALtransfer_encoding_single__ASN1__type_descr_.ber, p_buf);
+      field_single__ASN1__type->OER_encode(BITSTRING_descr_, p_buf);
+      break;
+    case ALT_octet__aligned:
+      encode_oer_tag(*EXTERNALtransfer_encoding_octet__aligned_descr_.ber, p_buf);
+      field_octet__aligned    ->OER_encode(OCTETSTRING_descr_, p_buf);
+      break;
+    case ALT_arbitrary:
+      field_arbitrary         ->OER_encode(BITSTRING_descr_, p_buf);
+      break;
+    case UNBOUND_VALUE:
+      TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
+        "Encoding an unbound value");
+      break;
+    default:
+      TTCN_EncDec_ErrorContext::error_internal("Unknown selection.");
+      // TODO something at all ?
+      break;
+    }
+    return 0;
+  }
+  
+  int EXTERNALtransfer_encoding::OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf, OER_struct& p_oer) {
+    const ASN_Tag_t& tag = decode_oer_tag(p_buf);
+    if (tag.tagclass == EXTERNALtransfer_encoding_single__ASN1__type_ber_.tags[0].tagclass &&
+        tag.tagnumber == EXTERNALtransfer_encoding_single__ASN1__type_ber_.tags[0].tagnumber) {
+      single__ASN1__type().OER_decode(BITSTRING_descr_, p_buf, p_oer);
+    } else if (tag.tagclass == EXTERNALtransfer_encoding_octet__aligned_ber_.tags[0].tagclass &&
+               tag.tagnumber == EXTERNALtransfer_encoding_octet__aligned_ber_.tags[0].tagnumber) {
+      octet__aligned().OER_decode(OCTETSTRING_descr_, p_buf, p_oer);
+    } else if (tag.tagclass == EXTERNALtransfer_encoding_arbitrary_ber_.tags[0].tagclass &&
+               tag.tagnumber == EXTERNALtransfer_encoding_arbitrary_ber_.tags[0].tagnumber) {
+      arbitrary().OER_decode(BITSTRING_descr_, p_buf, p_oer);
+    } else {
+      TTCN_EncDec_ErrorContext::error_internal("Unknown selection.");
+    }
+    return 0;
+  }
 
   /******************** EXTERNALtransfer class ********************/
 
@@ -630,6 +677,48 @@ namespace { /* anonymous namespace */
     }
     return 1; // decode successful
   }
+  
+  int EXTERNALtransfer::OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const {
+    char c = 0;
+    if (field_direct__reference.is_present()) {
+      c += 1 << 7;
+    }
+    if (field_indirect__reference.is_present()) {
+      c += 1 << 6;
+    }
+    if (field_data__value__descriptor.is_present()) {
+      c += 1 << 5;
+    }
+    p_buf.put_c(c);
+    field_direct__reference      .OER_encode(OBJID_descr_, p_buf);
+    field_indirect__reference    .OER_encode(INTEGER_descr_, p_buf);
+    field_data__value__descriptor.OER_encode(ObjectDescriptor_descr_, p_buf);
+    field_encoding               .OER_encode(p_td, p_buf);
+    return 0;
+  }
+  
+  int EXTERNALtransfer::OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf, OER_struct& p_oer) {
+    const unsigned char* uc = p_buf.get_read_data();
+    p_buf.increase_pos(1);
+    if ((uc[0] >> 7) & 1) {
+      field_direct__reference.OER_decode(OBJID_descr_, p_buf, p_oer);
+    } else {
+      field_direct__reference = OMIT_VALUE;
+    }
+    if ((uc[0] >> 6) & 1) {
+      field_indirect__reference.OER_decode(INTEGER_descr_, p_buf, p_oer);
+    } else {
+      field_indirect__reference = OMIT_VALUE;
+    }
+    if ((uc[0] >> 5) & 1) {
+      field_data__value__descriptor.OER_decode(ObjectDescriptor_descr_, p_buf, p_oer);
+    } else {
+      field_data__value__descriptor = OMIT_VALUE;
+    }
+    field_encoding.OER_decode(OCTETSTRING_descr_, p_buf, p_oer);
+    return 0;
+  }
+  
 } // end of anonymous namespace
 
 /*
@@ -736,6 +825,24 @@ int EXTERNAL::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
   return 1; // decode successful
 }
 
+int EXTERNAL::OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const {
+  if(!is_bound()) {
+    TTCN_EncDec_ErrorContext::error
+      (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
+  }
+  EXTERNALtransfer xfer;
+  xfer.load(*this);
+  return xfer.OER_encode(p_td, p_buf);
+  return 0;
+}
+
+int EXTERNAL::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, OER_struct& p_oer) {
+  EXTERNALtransfer xfer;
+  xfer.OER_decode(p_td, p_buf, p_oer);
+  transfer(&xfer);
+  return 0;
+}
+
 /* generated stuff */
 
 void EXTERNAL_identification::clean_up()
@@ -3468,6 +3575,12 @@ void EXTERNAL::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTC
     TTCN_EncDec_ErrorContext::error_internal
       ("No JSON descriptor available for type '%s'.", p_td.name);
     break;}
+  case TTCN_EncDec::CT_OER: {
+    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_encode(p_td, p_buf);
+    break;}
   default:
     TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
   }
@@ -3516,6 +3629,13 @@ void EXTERNAL::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTC
     TTCN_EncDec_ErrorContext::error_internal
       ("No JSON descriptor available for type '%s'.", p_td.name);
     break;}
+  case TTCN_EncDec::CT_OER: {
+      TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_struct p_oer;
+    OER_decode(p_td, p_buf, p_oer);
+    break;}
   default:
     TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
   }
diff --git a/core/ASN_External.hh b/core/ASN_External.hh
index 6542606b81ad1dfca7bd11904e342688bd5d24f1..37d05732c38ec6c591a36543ab15e7eb7efdd4fd 100644
--- a/core/ASN_External.hh
+++ b/core/ASN_External.hh
@@ -29,6 +29,7 @@
 #include "Objid.hh"
 #include "Octetstring.hh"
 #include "Universal_charstring.hh"
+#include "TEXT.hh"
 
 class EXTERNAL_identification;
 class EXTERNAL_identification_template;
@@ -425,6 +426,8 @@ public:
                  TTCN_Buffer& p_buf, unsigned int flavor, unsigned int flavor2, int indent, embed_values_enc_struct_t*) const;
   int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
                  unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*);
+  int OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const;
+  int OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, OER_struct& p_oer);
 };
 
 class EXTERNAL_template : public Base_Template {
diff --git a/core/ASN_Null.cc b/core/ASN_Null.cc
index 831638a96b66e2900f81428fb8cc5950e7921510..62b334d63538d356247a31c9d4c04bab20aa63fb 100644
--- a/core/ASN_Null.cc
+++ b/core/ASN_Null.cc
@@ -29,6 +29,7 @@
 #include "Logger.hh"
 #include "Encdec.hh"
 #include "BER.hh"
+#include "OER.hh"
 
 #include "../common/dbgnew.hh"
 
@@ -147,6 +148,12 @@ void ASN_NULL::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
     JSON_encode(p_td, tok);
     p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
     break;}
+  case TTCN_EncDec::CT_OER: {
+    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_encode(p_td, p_buf);
+    break;}
   case TTCN_EncDec::CT_RAW:
   default:
     TTCN_error("Unknown coding method requested to encode type '%s'",
@@ -196,6 +203,13 @@ void ASN_NULL::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
                , p_td.name);
     p_buf.set_pos(tok.get_buf_pos());
     break;}
+  case TTCN_EncDec::CT_OER: {
+      TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_struct p_oer;
+    OER_decode(p_td, p_buf, p_oer);
+    break;}
   case TTCN_EncDec::CT_RAW:
   default:
     TTCN_error("Unknown coding method requested to decode type '%s'",
@@ -319,6 +333,20 @@ int ASN_NULL::JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok, b
   return (int)dec_len;
 }
 
+int ASN_NULL::OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const {
+  if (!is_bound()) {
+    TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
+      "Encoding an unbound ASN.1 NULL value.");
+    return -1;
+  }
+  return 0;
+}
+
+int ASN_NULL::OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, OER_struct&) {
+  bound_flag = TRUE;
+  return 0;
+}
+
 boolean operator==(asn_null_type, const ASN_NULL& other_value)
 {
   if (!other_value.is_bound()) TTCN_error("The right operand of comparison "
diff --git a/core/ASN_Null.hh b/core/ASN_Null.hh
index 733dbd2c760237a14b17f6088176f2e3e0c43673..3f68f318081251be78d633b5f7eac1c9c9e5fae2 100644
--- a/core/ASN_Null.hh
+++ b/core/ASN_Null.hh
@@ -94,6 +94,14 @@ public:
   /** Decodes accordingly to the JSON decoding rules.
     * Returns the length of the encoded data. */
   int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean);
+  
+  /** Encodes accordingly to the OER encoding rules.
+    * Returns the length of the encoded data. */
+  int OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const;
+  
+  /** Decodes accordingly to the OER decoding rules.
+    * Returns the length of the encoded data. */
+  int OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, OER_struct&);
 };
 
 extern boolean operator==(asn_null_type par_value, const ASN_NULL& other_value);
diff --git a/core/Basetype.cc b/core/Basetype.cc
index 936015d3cae01a8f1cc918d527c27809fca817e6..342983d2570a61762ed0ed6008786208f2b92efa 100644
--- a/core/Basetype.cc
+++ b/core/Basetype.cc
@@ -192,7 +192,8 @@ void Base_Type::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
     TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
     if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
       "No OER descriptor available for type '%s'.", p_td.name);
-    OER_decode(p_td, p_buf);
+    OER_struct p_oer;
+    OER_decode(p_td, p_buf, p_oer);
     break;}
   default:
     TTCN_error("Unknown coding method requested to decode type '%s'",
@@ -1039,7 +1040,7 @@ int Base_Type::OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer&) const
   return 0;
 }
 
-int Base_Type::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer&) 
+int Base_Type::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer&, OER_struct&) 
 {
   TTCN_error("OER decoding requested for type '%s' which has no"
              " OER decoding method.", p_td.name);
@@ -1140,25 +1141,25 @@ const TTCN_Typedescriptor_t BOOLEAN_descr_={"BOOLEAN", &BOOLEAN_ber_,
   &BOOLEAN_raw_, &BOOLEAN_text_, &BOOLEAN_xer_, &BOOLEAN_json_, &BOOLEAN_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE};
 
 const TTCN_Typedescriptor_t INTEGER_descr_={"INTEGER", &INTEGER_ber_,
-  &INTEGER_raw_, &INTEGER_text_, &INTEGER_xer_, &INTEGER_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
+  &INTEGER_raw_, &INTEGER_text_, &INTEGER_xer_, &INTEGER_json_, &INTEGER_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE};
 
 const TTCN_Typedescriptor_t FLOAT_descr_={"REAL", &FLOAT_ber_, &FLOAT_raw_,
-  NULL, &FLOAT_xer_, &FLOAT_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
+  NULL, &FLOAT_xer_, &FLOAT_json_, &FLOAT_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE};
 
 const TTCN_Typedescriptor_t VERDICTTYPE_descr_={"verdicttype", NULL, NULL,
   NULL, &VERDICTTYPE_xer_, &VERDICTTYPE_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
 
 const TTCN_Typedescriptor_t OBJID_descr_={"OBJECT IDENTIFIER", &OBJID_ber_,
-  NULL, NULL, &OBJID_xer_, &OBJID_json_, NULL, NULL, TTCN_Typedescriptor_t::OBJID};
+  NULL, NULL, &OBJID_xer_, &OBJID_json_, &OBJID_oer_, NULL, TTCN_Typedescriptor_t::OBJID};
 
 const TTCN_Typedescriptor_t BITSTRING_descr_={"BIT STRING", &BITSTRING_ber_,
-  &BITSTRING_raw_, NULL, &BITSTRING_xer_, &BITSTRING_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
+  &BITSTRING_raw_, NULL, &BITSTRING_xer_, &BITSTRING_json_, &BITSTRING_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE};
 
 const TTCN_Typedescriptor_t HEXSTRING_descr_={"hexstring", NULL,
   &HEXSTRING_raw_, NULL, &HEXSTRING_xer_, &HEXSTRING_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
 
 const TTCN_Typedescriptor_t OCTETSTRING_descr_={"OCTET STRING",
-  &OCTETSTRING_ber_, &OCTETSTRING_raw_, &OCTETSTRING_text_, &OCTETSTRING_xer_, &OCTETSTRING_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
+  &OCTETSTRING_ber_, &OCTETSTRING_raw_, &OCTETSTRING_text_, &OCTETSTRING_xer_, &OCTETSTRING_json_, &OCTETSTRING_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE};
 
 const TTCN_Typedescriptor_t CHARSTRING_descr_={"charstring", NULL,
   &CHARSTRING_raw_, &CHARSTRING_text_, &CHARSTRING_xer_, &CHARSTRING_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
@@ -1173,44 +1174,44 @@ const TTCN_Typedescriptor_t DEFAULT_descr_={"default", NULL, NULL, NULL,
   NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
 
 const TTCN_Typedescriptor_t ASN_NULL_descr_={"NULL", &ASN_NULL_ber_, NULL,
-  NULL, &ASN_NULL_xer_, &ASN_NULL_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
+  NULL, &ASN_NULL_xer_, &ASN_NULL_json_, &ASN_NULL_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE};
 
 const TTCN_Typedescriptor_t ASN_ANY_descr_={"ANY", &ASN_ANY_ber_, NULL,
   NULL, NULL, &ASN_ANY_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
 
 const TTCN_Typedescriptor_t EXTERNAL_descr_={"EXTERNAL", &EXTERNAL_ber_, NULL,
-  NULL, &EXTERNAL_xer_, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
+  NULL, &EXTERNAL_xer_, NULL, &EXTERNAL_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE};
 
 const TTCN_Typedescriptor_t EMBEDDED_PDV_descr_={"EMBEDDED PDV",
-  &EMBEDDED_PDV_ber_, NULL, NULL, &EMBEDDED_PDV_xer_, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
+  &EMBEDDED_PDV_ber_, NULL, NULL, &EMBEDDED_PDV_xer_, NULL, &EMBEDDED_PDV_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE};
 
 const TTCN_Typedescriptor_t CHARACTER_STRING_descr_={"CHARACTER STRING",
   &CHARACTER_STRING_ber_, NULL, NULL, &CHARACTER_STRING_xer_, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
 
 const TTCN_Typedescriptor_t ObjectDescriptor_descr_={"ObjectDescriptor",
-  &ObjectDescriptor_ber_, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::GRAPHICSTRING};
+  &ObjectDescriptor_ber_, NULL, NULL, NULL, NULL, &ObjectDescriptor_oer_, NULL, TTCN_Typedescriptor_t::GRAPHICSTRING};
 
 const TTCN_Typedescriptor_t UTF8String_descr_={"UTF8String", &UTF8String_ber_,
-  NULL, NULL, &UTF8String_xer_, &UTF8String_json_, NULL, NULL, TTCN_Typedescriptor_t::UTF8STRING};
+  NULL, NULL, &UTF8String_xer_, &UTF8String_json_, &UTF8String_oer_, NULL, TTCN_Typedescriptor_t::UTF8STRING};
 
 const TTCN_Typedescriptor_t ASN_ROID_descr_={"RELATIVE-OID", &ASN_ROID_ber_,
-  NULL, NULL, &ASN_ROID_xer_, &ASN_ROID_json_, NULL, NULL, TTCN_Typedescriptor_t::ROID};
+  NULL, NULL, &ASN_ROID_xer_, &ASN_ROID_json_, &ASN_ROID_oer_, NULL, TTCN_Typedescriptor_t::ROID};
 
 const TTCN_Typedescriptor_t NumericString_descr_={"NumericString",
-  &NumericString_ber_, NULL, NULL, &NumericString_xer_, &NumericString_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
+  &NumericString_ber_, NULL, NULL, &NumericString_xer_, &NumericString_json_, &NumericString_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE};
 
 const TTCN_Typedescriptor_t PrintableString_descr_={"PrintableString",
-  &PrintableString_ber_, NULL, NULL, &PrintableString_xer_, &PrintableString_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
+  &PrintableString_ber_, NULL, NULL, &PrintableString_xer_, &PrintableString_json_, &PrintableString_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE};
 
 const TTCN_Typedescriptor_t TeletexString_descr_={"TeletexString",
-  &TeletexString_ber_, NULL, NULL, &TeletexString_xer_, &TeletexString_json_, NULL, NULL, TTCN_Typedescriptor_t::TELETEXSTRING};
+  &TeletexString_ber_, NULL, NULL, &TeletexString_xer_, &TeletexString_json_, &TeletexString_oer_, NULL, TTCN_Typedescriptor_t::TELETEXSTRING};
 const TTCN_Typedescriptor_t& T61String_descr_=TeletexString_descr_;
 
 const TTCN_Typedescriptor_t VideotexString_descr_={"VideotexString",
-  &VideotexString_ber_, NULL, NULL, &VideotexString_xer_, &VideotexString_json_, NULL, NULL, TTCN_Typedescriptor_t::VIDEOTEXSTRING};
+  &VideotexString_ber_, NULL, NULL, &VideotexString_xer_, &VideotexString_json_, &VideotexString_oer_, NULL, TTCN_Typedescriptor_t::VIDEOTEXSTRING};
 
 const TTCN_Typedescriptor_t IA5String_descr_={"IA5String", &IA5String_ber_,
-  NULL, NULL, &IA5String_xer_, &IA5String_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
+  NULL, NULL, &IA5String_xer_, &IA5String_json_, &IA5String_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE};
 
 const TTCN_Typedescriptor_t ASN_GeneralizedTime_descr_={"GeneralizedTime",
   &ASN_GeneralizedTime_ber_, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
@@ -1219,19 +1220,19 @@ const TTCN_Typedescriptor_t ASN_UTCTime_descr_={"UTCTime", &ASN_UTCTime_ber_,
   NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
 
 const TTCN_Typedescriptor_t GraphicString_descr_={"GraphicString",
-  &GraphicString_ber_, NULL, NULL, &GraphicString_xer_, &GraphicString_json_, NULL, NULL, TTCN_Typedescriptor_t::GRAPHICSTRING};
+  &GraphicString_ber_, NULL, NULL, &GraphicString_xer_, &GraphicString_json_, &GraphicString_oer_, NULL, TTCN_Typedescriptor_t::GRAPHICSTRING};
 
 const TTCN_Typedescriptor_t VisibleString_descr_={"VisibleString",
-  &VisibleString_ber_, NULL, NULL, &VisibleString_xer_, &VisibleString_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
+  &VisibleString_ber_, NULL, NULL, &VisibleString_xer_, &VisibleString_json_, &VisibleString_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE};
 const TTCN_Typedescriptor_t& ISO646String_descr_=VisibleString_descr_;
 
 const TTCN_Typedescriptor_t GeneralString_descr_={"GeneralString",
-  &GeneralString_ber_, NULL, NULL, &GeneralString_xer_, &GeneralString_json_, NULL, NULL, TTCN_Typedescriptor_t::GENERALSTRING};
+  &GeneralString_ber_, NULL, NULL, &GeneralString_xer_, &GeneralString_json_, &GeneralString_oer_, NULL, TTCN_Typedescriptor_t::GENERALSTRING};
 
 const TTCN_Typedescriptor_t UniversalString_descr_={"UniversalString",
-  &UniversalString_ber_, NULL, NULL, &UniversalString_xer_, &UniversalString_json_, NULL, NULL, TTCN_Typedescriptor_t::UNIVERSALSTRING};
+  &UniversalString_ber_, NULL, NULL, &UniversalString_xer_, &UniversalString_json_, &UniversalString_oer_, NULL, TTCN_Typedescriptor_t::UNIVERSALSTRING};
 
 const TTCN_Typedescriptor_t BMPString_descr_={"BMPString", &BMPString_ber_,
-  NULL, NULL, &BMPString_xer_, &BMPString_json_, NULL, NULL, TTCN_Typedescriptor_t::BMPSTRING};
+  NULL, NULL, &BMPString_xer_, &BMPString_json_, &BMPString_oer_, NULL, TTCN_Typedescriptor_t::BMPSTRING};
 
 
diff --git a/core/Basetype.hh b/core/Basetype.hh
index a79714098468db99f8659542ec865c6e9bf3e9d1..204027954bbe4d7163e3de87d4aee098987fd0be 100644
--- a/core/Basetype.hh
+++ b/core/Basetype.hh
@@ -49,6 +49,7 @@ class Module_Param;
 class Module_Param_Name;
 struct embed_values_enc_struct_t;
 struct embed_values_dec_struct_t;
+struct OER_struct;
 
 /** @brief Type descriptor
  *
@@ -396,6 +397,7 @@ public:
   virtual int encode_raw(TTCN_Buffer& p_buf) const;
   virtual int RAW_encode_negtest_raw(RAW_enc_tree& p_myleaf) const;
   virtual int JSON_encode_negtest_raw(JSON_Tokenizer&) const;
+  virtual int OER_encode_negtest_raw(JSON_Tokenizer&) const; //TODO
 #endif
 
   /** Examines whether this message corresponds the tags in the
@@ -620,7 +622,21 @@ public:
   
   /** Decode OER.
    * @note Basetype::OER_decode throws an error. */
-  VIRTUAL_IF_RUNTIME_2 int OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf);
+  VIRTUAL_IF_RUNTIME_2 int OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, OER_struct& p_oer);
+  
+   VIRTUAL_IF_RUNTIME_2 void OER_decode_opentypes(
+    TTCN_Type_list& /*p_typelist*/, TTCN_Buffer& /*p_buf*/, OER_struct& /*p_oer*/) {}
+   
+   #ifdef TITAN_RUNTIME_2
+  /** Encode with OER encoding negative test.
+    * @return the length of the encoding
+    * @param p_err_descr erroneous type descriptor
+    * @param p_td type descriptor
+    * @param p_tok JSON tokenizer for the encoded data
+    * @note Basetype::JSON_encode_negtest throws an error. */
+  virtual int OER_encode_negtest(const Erroneous_descriptor_t* p_err_descr, const TTCN_Typedescriptor_t& p_td,
+          TTCN_Buffer& p_buf) const;
+#endif
   
   /** not a component by default (components will return true) */
   inline boolean is_component() { return FALSE; }
@@ -850,6 +866,22 @@ public:
   /** Decodes accordingly to the JSON encoding rules.
     * Returns the length of the decoded data. */
   int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean);
+  
+  /** Encodes accordingly to the OER encoding rules.
+    * Returns the length of the encoded data. */
+  int OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const;
+  
+  /** Negative testing for the OER encoder
+    * Encodes this value according to the OER encoding rules, but with the
+    * modifications (errors) specified in the erroneous descriptor parameter. */
+  int OER_encode_negtest(const Erroneous_descriptor_t*, const TTCN_Typedescriptor_t&, TTCN_Buffer&) const;
+  
+  /** Decodes accordingly to the OER encoding rules.
+    * Returns the length of the decoded data. */
+  int OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, OER_struct&);
+  
+  virtual void OER_decode_opentypes(
+    TTCN_Type_list& /*p_typelist*/, TTCN_Buffer& /*p_buf*/, OER_struct& /*p_oer*/);
 
   /** @returns \c true  if this is a set-of type,
    *           \c false if this is a record-of type */
@@ -997,6 +1029,21 @@ public:
   /** Decodes accordingly to the JSON encoding rules.
     * Returns the length of the decoded data. */
   int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean);
+  
+  /** Encodes accordingly to the JSON encoding rules.
+    * Returns the length of the encoded data. */
+  int OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const;
+  
+  /** Negative testing for the OER encoder
+    * Encodes this value according to the OER encoding rules, but with the
+    * modifications (errors) specified in the erroneous descriptor parameter. */
+  int OER_encode_negtest(const Erroneous_descriptor_t*, const TTCN_Typedescriptor_t&, TTCN_Buffer&) const;
+  
+  /** Decodes accordingly to the OER encoding rules.
+    * Returns the length of the decoded data. */
+  int OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, OER_struct&);
+  
+  virtual void OER_decode_opentypes(TTCN_Type_list& p_typelist, TTCN_Buffer& p_buf, OER_struct& p_oer);
 
   void set_err_descr(Erroneous_descriptor_t* p_err_descr) { err_descr=p_err_descr; }
   Erroneous_descriptor_t* get_err_descr() const { return err_descr; }
@@ -1061,6 +1108,14 @@ public:
   /** Decodes accordingly to the JSON encoding rules.
     * Returns the length of the decoded data. */
   virtual int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean);
+  
+  /** Encodes accordingly to the OER encoding rules.
+    * Returns the length of the encoded data. */
+  virtual int OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const;
+  
+  /** Decodes accordingly to the OER encoding rules.
+    * Returns the length of the decoded data. */
+  virtual int OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, OER_struct&);
 };
 
 struct Enum_Type : public Base_Type {
diff --git a/core/Bitstring.cc b/core/Bitstring.cc
index 0c9d4b13e47ca2ced292547e17b2608b2d0544bc..219289b91bf063837c20f5addaa670565a9476b8 100644
--- a/core/Bitstring.cc
+++ b/core/Bitstring.cc
@@ -36,6 +36,7 @@
 #include "Optional.hh"
 
 #include "../common/dbgnew.hh"
+#include "OER.hh"
 
 // bitstring value class
 
@@ -692,6 +693,12 @@ void BITSTRING::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
     JSON_encode(p_td, tok);
     p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
     break;}
+  case TTCN_EncDec::CT_OER: {
+    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_encode(p_td, p_buf);
+    break;}
   default:
     TTCN_error("Unknown coding method requested to encode type '%s'",
                p_td.name);
@@ -760,6 +767,13 @@ void BITSTRING::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
                , p_td.name);
     p_buf.set_pos(tok.get_buf_pos());
     break;}
+  case TTCN_EncDec::CT_OER: {
+    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_struct p_oer;
+    OER_decode(p_td, p_buf, p_oer);
+    break;}
   default:
     TTCN_error("Unknown coding method requested to decode type '%s'",
                p_td.name);
@@ -1265,6 +1279,65 @@ int BITSTRING::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_
   return (int)dec_len;
 }
 
+int BITSTRING::OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const {
+  if (!is_bound()) {
+    TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
+      "Encoding an unbound bitstring value.");
+    return -1;
+  }
+  if (p_td.oer->length == -1) {
+    size_t bytes = 1 + val_ptr->n_bits / 8;
+    int rem = (val_ptr->n_bits % 8);
+    if (rem != 0) {
+      bytes++;
+    }
+    encode_oer_length(bytes, p_buf, FALSE);
+    p_buf.put_c(rem == 0 ? 0 : 8 - rem);
+  }
+  char c = 0;
+  int pos = 8;
+  for (int i = 0; i < val_ptr->n_bits; i++) {
+    pos--;
+    c += get_bit(i) << pos;
+    if (pos == 0) {
+      p_buf.put_c(c);
+      c = 0;
+      pos = 8;
+    }
+  }
+  if (pos != 8) {
+    p_buf.put_c(c);
+  }
+  return 0;
+}
+
+int BITSTRING::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, OER_struct&) {
+  
+  size_t bytes;
+  if (p_td.oer->length == -1) {
+    bytes = decode_oer_length(p_buf, FALSE) - 1;
+    const unsigned char* uc = p_buf.get_read_data();
+    init_struct((bytes * 8) - uc[0]);
+    p_buf.increase_pos(1);
+  } else {
+    bytes = p_td.oer->length / 8;
+    if (p_td.oer->length % 8 != 0) {
+      bytes++;
+    }
+    init_struct(p_td.oer->length);
+  }
+
+  const unsigned char* uc = p_buf.get_read_data();
+  int bit_pos = 0;
+  for (size_t i = 0; i < bytes; i++) {
+    for (int j = 7; j >= 0 && bit_pos < val_ptr->n_bits; j--) {
+      set_bit(bit_pos, (uc[i] & (1 << j)));
+      bit_pos++;
+    }
+  }
+  p_buf.increase_pos(bytes);
+  return 0;
+}
 
 // bitstring element class
 
diff --git a/core/Bitstring.hh b/core/Bitstring.hh
index 1339c212cc0381232888bd190cbe8aa093a80277..6c5154703cb6a32c986ecb3ad5032a652a231c67 100644
--- a/core/Bitstring.hh
+++ b/core/Bitstring.hh
@@ -209,6 +209,14 @@ public:
   /** Decodes accordingly to the JSON decoding rules.
     * Returns the length of the encoded data. */
   int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean);
+  
+  /** Encodes accordingly to the OER encoding rules.
+    * Returns the length of the encoded data. */
+  int OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const;
+  
+  /** Decodes accordingly to the OER decoding rules.
+    * Returns the length of the encoded data. */
+  int OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, OER_struct&);
 };
 
 class BITSTRING_ELEMENT {
diff --git a/core/Boolean.cc b/core/Boolean.cc
index 66c0114600cda5df6801a041486600207d034579..b870d3821830cd171996ce688274d9cb497399f1 100644
--- a/core/Boolean.cc
+++ b/core/Boolean.cc
@@ -33,6 +33,7 @@
 #include "Encdec.hh"
 #include "RAW.hh"
 #include "BER.hh"
+#include "OER.hh"
 #include "TEXT.hh"
 #include "Charstring.hh"
 #include "XmlReader.hh"
@@ -344,7 +345,8 @@ void BOOLEAN::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
     TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
     if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
       "No OER descriptor available for type '%s'.", p_td.name);
-    OER_decode(p_td, p_buf);
+    OER_struct p_oer;
+    OER_decode(p_td, p_buf, p_oer);
     break;}
   default:
     TTCN_error("Unknown coding method requested to decode type '%s'",
@@ -805,7 +807,7 @@ int BOOLEAN::OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf) const
   return 1;
 }
 
-int BOOLEAN::OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf)
+int BOOLEAN::OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf, OER_struct&)
 {
   const unsigned char* c = p_buf.get_read_data();
   p_buf.increase_pos(1);
diff --git a/core/Boolean.hh b/core/Boolean.hh
index 4bba9003fde414ed6c32d9c414a85ac1c2539b1c..d52476cfecccfee7fdad5d895e58a75116c55e54 100644
--- a/core/Boolean.hh
+++ b/core/Boolean.hh
@@ -137,7 +137,7 @@ public:
   
   /** Decodes accordingly to the OER encoding rules.
     * Returns the length of the decoded data. */
-  int OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf);
+  int OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf, OER_struct&);
 };
 
 extern boolean operator&&(boolean bool_value, const BOOLEAN& other_value);
diff --git a/core/Charstring.cc b/core/Charstring.cc
index ed0a4a1534226bd302cc19df9098c9d954002751..dc09bdd58a37204f5a16e87157922e29376971c7 100644
--- a/core/Charstring.cc
+++ b/core/Charstring.cc
@@ -43,6 +43,7 @@
 #include "Optional.hh"
 
 #include "../common/dbgnew.hh"
+#include "OER.hh"
 
 #include <string.h>
 #include <ctype.h>
@@ -840,6 +841,12 @@ void CHARSTRING::encode(const TTCN_Typedescriptor_t& p_td,
     JSON_encode(p_td, tok);
     p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
     break;}
+  case TTCN_EncDec::CT_OER: {
+    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_encode(p_td, p_buf);
+    break;}
   default:
     TTCN_error("Unknown coding method requested to encode type '%s'",
                p_td.name);
@@ -927,6 +934,13 @@ void CHARSTRING::decode(const TTCN_Typedescriptor_t& p_td,
                , p_td.name);
     p_buf.set_pos(tok.get_buf_pos());
     break;}
+  case TTCN_EncDec::CT_OER: {
+    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_struct p_oer;
+    OER_decode(p_td, p_buf, p_oer);
+    break;}
   default:
     TTCN_error("Unknown coding method requested to decode type '%s'",
                p_td.name);
@@ -1813,6 +1827,35 @@ int CHARSTRING::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p
   return (int)dec_len;
 }
 
+int CHARSTRING::OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const {
+  if (!is_bound()) {
+    TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
+      "Encoding an unbound charstring value.");
+    return -1;
+  }
+  
+  if (p_td.oer->length == -1) {
+    encode_oer_length(lengthof(), p_buf, FALSE);
+  }
+  p_buf.put_cs(*this);
+  return 0;
+}
+  
+int CHARSTRING::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, OER_struct&) {
+  size_t bytes;
+  if (p_td.oer->length == -1) {
+    bytes = decode_oer_length(p_buf, FALSE);
+  } else {
+    bytes = p_td.oer->length;
+  }
+  const unsigned char* uc = p_buf.get_read_data();
+  init_struct(bytes);
+  for (size_t i = 0; i < bytes; i++) {
+    val_ptr->chars_ptr[i] = uc[i];
+  }
+  p_buf.increase_pos(bytes);
+  return 0;
+}
 
 CHARSTRING_ELEMENT::CHARSTRING_ELEMENT(boolean par_bound_flag,
   CHARSTRING& par_str_val, int par_char_pos)
diff --git a/core/Charstring.hh b/core/Charstring.hh
index 29cc731113219fc350423d0a859bee3c50dfe177..114b804aa3a3e749f4578d0934bc052034d98f99 100644
--- a/core/Charstring.hh
+++ b/core/Charstring.hh
@@ -280,6 +280,10 @@ public:
     * Returns the length of the decoded data. */
   int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean);
   
+  int OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const;
+  
+  int OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, OER_struct&);
+  
 #ifdef TITAN_RUNTIME_2
   virtual int encode_raw(TTCN_Buffer& p_buf) const;
   /** Adds this charstring to the end of a JSON buffer as raw data.
diff --git a/core/Float.cc b/core/Float.cc
index 92aaa21e9c74051446731d4b7d2919efec18dc60..dacecc43719583ba2d84d2b9e0230fed26442db4 100644
--- a/core/Float.cc
+++ b/core/Float.cc
@@ -36,6 +36,7 @@
 #include "Encdec.hh"
 #include "RAW.hh"
 #include "BER.hh"
+#include "OER.hh"
 #include "Charstring.hh"
 #include "Addfunc.hh"
 #include "XmlReader.hh"
@@ -364,6 +365,12 @@ void FLOAT::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
     JSON_encode(p_td, tok);
     p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
     break;}
+  case TTCN_EncDec::CT_OER: {
+    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_encode(p_td, p_buf);
+    break;}
   default:
     TTCN_error("Unknown coding method requested to encode type '%s'",
                p_td.name);
@@ -431,6 +438,13 @@ void FLOAT::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
                , p_td.name);
     p_buf.set_pos(tok.get_buf_pos());
     break;}
+  case TTCN_EncDec::CT_OER: {
+      TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_struct p_oer;
+    OER_decode(p_td, p_buf, p_oer);
+    break;}
   default:
     TTCN_error("Unknown coding method requested to decode type '%s'",
                p_td.name);
@@ -1152,6 +1166,212 @@ int FLOAT::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok,
   return (int)dec_len;
 }
 
+int FLOAT::OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf) const {
+  if (!is_bound()) {
+    TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
+      "Encoding an unbound float value.");
+    return -1;
+  }
+  // Mostly copied from BER
+  if (float_value==0.0) {
+    p_buf.put_c(0);
+  } else if (float_value==(double)INFINITY) {
+    p_buf.put_c(1);
+    p_buf.put_c(64);
+  } else if (float_value==-(double)INFINITY) {
+    p_buf.put_c(1);
+    p_buf.put_c(65);
+  } else if (isnan((double)float_value)) {
+    p_buf.put_c(1);
+    p_buf.put_c(66);
+  } else {
+    double mantissa, exponent;
+    exponent=floor(log10(fabs(float_value)))+1.0-DBL_DIG;
+    mantissa=floor(float_value*pow(10.0,-exponent)+0.5);
+    if(mantissa)while(!fmod(mantissa,10.0))mantissa/=10.0,exponent+=1.0;
+    char * uc =
+      mprintf("\x03%.f.E%s%.0f", mantissa, exponent==0.0?"+":"", exponent);
+    size_t len = mstrlen(uc);
+    p_buf.put_c(len);
+    p_buf.put_s(len, (unsigned char*)uc);
+    Free(uc);
+  }
+  return 0;
+}
+  
+int FLOAT::OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf, OER_struct&) {
+  TTCN_EncDec_ErrorContext ec("While decoding REAL type: ");
+  const unsigned char* uc = p_buf.get_read_data();
+  const size_t bytes = uc[0];
+  p_buf.increase_pos(1);
+  uc = p_buf.get_read_data();
+  // Mostly copied from BER
+  if(bytes==0) {
+    float_value=0.0;
+  }
+  else if(uc[0] & 0x80) {
+    /* binary encoding */
+    /** \todo Perhaps it were good to implement this. Perhaps not. :) */
+    ec.warning("Sorry, decoding of binary encoded REAL values not"
+               " supported.");
+    float_value=0.0;
+  }
+  else if(uc[0] & 0x40) {
+    /* SpecialRealValue */
+    if(bytes>1)
+      ec.error(TTCN_EncDec::ET_INVAL_MSG,
+               "In case of SpecialRealValue, the length of V-part must be 1"
+               " (See X.690 8.5.8).");
+    if (uc[0] & 0x02) {
+      float_value=NOT_A_NUMBER;
+    } else if(uc[0] & 0x01)
+      /* MINUS-INFINITY */
+      float_value=-INFINITY;
+    else {
+      /* PLUS-INFINITY */
+      float_value=INFINITY;
+    }
+  }
+  else {
+    /* decimal encoding */
+    if((uc[0] & 0x3C) || (uc[0] & 0x3F) == 0x00 )
+      ec.error(TTCN_EncDec::ET_INVAL_MSG,
+               "This is a reserved value: 0x%x (See X.690 8.5.7).",
+               uc[0]);
+    int NR=uc[0] & 0x03; // which NumericalRepresentation
+    boolean
+      leadingzero=FALSE,
+      NR_error=FALSE;
+    const unsigned char
+      *Vstr_last=uc+bytes-1,
+      *sign=NULL,
+      *mant1=NULL,
+      *decmark=NULL,
+      *mant2=NULL,
+      *expmark=NULL,
+      *expsign=NULL,
+      *expo=NULL,
+      *ptr=uc+1;
+    size_t
+      mant1_len=0,
+      mant2_len=0,
+      expo_len=0;
+    long exponum;
+    if(bytes==1) goto dec_error;
+    while(*ptr==' ') {
+      if(ptr==Vstr_last) goto dec_error;
+      ptr++;
+    }
+    if(*ptr=='+' || *ptr=='-') {
+      sign=ptr;
+      if(ptr==Vstr_last) goto dec_error;
+      ptr++;
+    }
+    while(*ptr=='0') {
+      leadingzero=TRUE;
+      if(ptr==Vstr_last) goto str_end;
+      ptr++;
+    }
+    while(*ptr>='0' && *ptr<='9') {
+      if(mant1_len==0) mant1=ptr;
+      mant1_len++;
+      if(ptr==Vstr_last) goto str_end;
+      ptr++;
+    }
+    if(*ptr=='.' || *ptr==',') {
+      decmark=ptr;
+      if(ptr==Vstr_last) goto str_end;
+      ptr++;
+    }
+    while(*ptr>='0' && *ptr<='9') {
+      if(mant2_len==0) mant2=ptr;
+      mant2_len++;
+      if(ptr==Vstr_last) goto str_end;
+      ptr++;
+    }
+    if(!leadingzero && !mant1 && !mant2) goto dec_error;
+    if(*ptr=='e' || *ptr=='E') {
+      expmark=ptr;
+      if(ptr==Vstr_last) goto dec_error;
+      ptr++;
+    }
+    if(*ptr=='+' || *ptr=='-') {
+      expsign=ptr;
+      if(ptr==Vstr_last) goto dec_error;
+      ptr++;
+    }
+    while(*ptr=='0') {
+      expo=ptr;
+      if(ptr==Vstr_last) goto str_end;
+      ptr++;
+    }
+    while(*ptr>='0' && *ptr<='9') {
+      if(expo_len==0) expo=ptr;
+      expo_len++;
+      if(ptr==Vstr_last) goto str_end;
+      ptr++;
+    }
+    if(expo_len==0 && expo!=NULL) expo_len=1; /* only leading zero */
+    if(expsign && !expo) goto dec_error;
+    ec.error(TTCN_EncDec::ET_INVAL_MSG,
+             "Superfluous part at the end of decimal encoding.");
+  str_end:
+    /* check NR */
+    if(NR==1) {
+      if(decmark || expmark) NR_error=TRUE;
+    }
+    else if(NR==2) {
+      if(expmark) NR_error=TRUE;
+    }
+    if(NR_error)
+      ec.error(TTCN_EncDec::ET_INVAL_MSG,
+               "This decimal encoding does not conform to NR%d form.", NR);
+    while(mant2_len>1 && mant2[mant2_len-1]=='0') mant2_len--;
+    if(mant2_len==1 && *mant2=='0') mant2_len=0, mant2=NULL;
+    float_value=0.0;
+    if(mant1) for(size_t i=0; i<mant1_len; i++) {
+      float_value*=10.0;
+      float_value+=static_cast<double>(mant1[i]-'0');
+    } // for i if...
+    if(mant2) for(size_t i=0; i<mant2_len; i++) {
+      float_value*=10.0;
+      float_value+=static_cast<double>(mant2[i]-'0');
+    } // for i if...
+    exponum=0;
+    if(expo) {
+      if(ceil(log10(log10(DBL_MAX)))<expo_len) {
+        /* overflow */
+        if(expsign && *expsign=='-') {
+          float_value=0.0;
+        }
+        else {
+          if(sign && *sign=='-') float_value=-INFINITY;
+          else float_value=INFINITY;
+        }
+        goto end;
+      } // overflow
+      else {
+        /* no overflow */
+        for(size_t i=0; i<expo_len; i++) {
+          exponum*=10;
+          exponum+=static_cast<int>(expo[i]-'0');
+        } // for i
+        if(expsign && *expsign=='-')
+          exponum*=-1;
+      } // no overflow
+    } // if expo
+    if(mant2) exponum-=mant2_len;
+    float_value*=pow(10.0, static_cast<double>(exponum));
+    goto end;
+  dec_error:
+    ec.error(TTCN_EncDec::ET_INVAL_MSG, "Erroneous decimal encoding.");
+    float_value=0.0;
+  }
+ end:
+  p_buf.increase_pos(bytes);
+  bound_flag=TRUE;
+  return 0;
+}
 
 // global functions
 
diff --git a/core/Float.hh b/core/Float.hh
index 83afeaed90095ce32cb612d34fe4984b038fdf0a..169946af78c2ae92eb60a6ad6b291edec04d6369 100644
--- a/core/Float.hh
+++ b/core/Float.hh
@@ -161,6 +161,14 @@ public:
   /** Decodes accordingly to the JSON encoding rules.
     * Returns the length of the decoded data. */
   int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean);
+  
+  /** Encodes accordingly to the OER encoding rules.
+    * Returns the length of the encoded data. */
+  int OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const;
+  
+  /** Decodes accordingly to the OER encoding rules.
+    * Returns the length of the decoded data. */
+  int OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, OER_struct&);
 };
 
 extern double operator+(double double_value, const FLOAT& other_value);
diff --git a/core/Integer.cc b/core/Integer.cc
index e8fb9f33ef7328ff8262f989f1bb4c0861d2d20d..875bb09671103d065a5148a8137b1017c4157355 100644
--- a/core/Integer.cc
+++ b/core/Integer.cc
@@ -38,6 +38,7 @@
 #include "RAW.hh"
 #include "BER.hh"
 #include "TEXT.hh"
+#include "OER.hh"
 #include "Charstring.hh"
 #include "Addfunc.hh"
 #include "XmlReader.hh"
@@ -894,7 +895,8 @@ void INTEGER::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
     TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
     if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
       "No OER descriptor available for type '%s'.", p_td.name);
-    OER_decode(p_td, p_buf);
+    OER_struct p_oer;
+    OER_decode(p_td, p_buf, p_oer);
     break;}
   default:
     TTCN_error("Unknown coding method requested to decode type '%s'",
@@ -1782,7 +1784,7 @@ int INTEGER::OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) c
       "Encoding an unbound integer value.");
     return -1;
   }
- 
+  
   // Most of the encoding is copied from the integer BER encoding.
   if (native_flag) {
     RInt value = val.native;
@@ -1827,7 +1829,6 @@ int INTEGER::OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) c
     unsigned char* bn_as_bin = (unsigned char*) Malloc(num_bytes);
     BN_bn2bin(D, bn_as_bin);
 
-    boolean pad = FALSE;
     if (BN_is_negative(D)) {
       for(size_t i = 0; i < num_bytes; ++i){
         bn_as_bin[i] = ~bn_as_bin[i];
@@ -1846,37 +1847,15 @@ int INTEGER::OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) c
           }
         }
       }
-      pad = !(bn_as_bin[0] & 0x80);
-    } else {
-      pad = bn_as_bin[0] & 0x80;
     }
     
     if (p_td.oer->bytes == -1) {
-      if (num_bytes < 128) {
-        p_buf.put_c(num_bytes);
-      } else {
-        size_t bytes = num_bytes;
-        TTCN_Buffer buff;
-        // Encode length in maybe more than 1 bytes
-        size_t needed_bytes = 0;
-        while (bytes != 0) {
-          bytes >>= 8;
-          needed_bytes++;
-        }
-        for (int i = needed_bytes - 1; i >= 0; i--) {
-          buff.put_c(static_cast<unsigned char>(num_bytes >> i*8));
-        }
-        char c = 0;
-        c |= 1 << 7;
-        c+= needed_bytes;
-        p_buf.put_c(c);
-        p_buf.put_buf(buff);
-      }
+      encode_oer_length(num_bytes, p_buf, FALSE);
     } else {
       int rem_bytes = p_td.oer->bytes - num_bytes;
-      char c = BN_is_negative(D) ? 0xFF : 0;
+      char pad = BN_is_negative(D) ? 0xFF : 0;
       for (int i = 0; i < rem_bytes; i++) {
-        p_buf.put_c(c);
+        p_buf.put_c(pad);
       }
     }
     p_buf.put_s(num_bytes, bn_as_bin);
@@ -1885,30 +1864,17 @@ int INTEGER::OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) c
   return 0;
 }
 
-int INTEGER::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf)
+int INTEGER::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, OER_struct&)
 {
   // Most of the decoding is copied from the integer BER decoding.
   size_t num_bytes = 0;
   
   // Get the number of bytes that the integer is encoded on
   if (p_td.oer->bytes == -1) {
-    const unsigned char* uc = p_buf.get_read_data();
-    p_buf.increase_pos(1);
-    // First bit is 1, its length is encoded in subsequent bytes
-    if (*uc & 0x80) {
-      size_t bytes = *uc & 0x7F;
-      for (size_t i = 1; i < bytes+1; i++) {
-        num_bytes += uc[i] << (bytes-i)*8;
-      }
-      p_buf.increase_pos(bytes);
-    } else {
-      // its length is encoded in the last 7 bytes
-      num_bytes = *uc & 0x7F;
-    }
+    num_bytes = decode_oer_length(p_buf, FALSE);
   } else {
     num_bytes = p_td.oer->bytes;
   }
-  
   const unsigned char* const ucstr = p_buf.get_read_data();
   if ((num_bytes > sizeof(RInt)) || (num_bytes >= 4 && p_td.oer->signed_ == FALSE)) { // Bignum
     const boolean negative = ucstr[0] & 0x80 && (p_td.oer->signed_ == TRUE || p_td.oer->bytes == -1);
diff --git a/core/Integer.hh b/core/Integer.hh
index 53289394ecb6f911edb92a0189084518319c257c..a538db16f53b7065729dbbf9c2282aec7e0f0821 100644
--- a/core/Integer.hh
+++ b/core/Integer.hh
@@ -199,7 +199,7 @@ public:
   
   /** Decodes accordingly to the OER encoding rules.
     * Returns the length of the decoded data. */
-  int OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf);
+  int OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf, OER_struct& p_oer);
 };
 
 extern INTEGER operator+(int int_value, const INTEGER& other_value);
diff --git a/core/OER.cc b/core/OER.cc
index 238b762df4ed88ef5e4fd273f589056bda0bd50d..927ef94c56ffbc7757ba68152ab3f99b8bc7191b 100644
--- a/core/OER.cc
+++ b/core/OER.cc
@@ -11,5 +11,194 @@
  *
  ******************************************************************************/
 #include "OER.hh"
+#include "Encdec.hh"
+#include "BER.hh"
+#include "../common/memory.h"
+#include "Error.hh"
 
-const TTCN_OERdescriptor_t BOOLEAN_oer_ = { 0, FALSE };
\ No newline at end of file
+
+void encode_oer_length(size_t num_bytes, TTCN_Buffer& buf, boolean seof) {
+  if (num_bytes < 128 && seof == FALSE) {
+    buf.put_c(num_bytes);
+  } else {
+    size_t bytes = num_bytes;
+    // Encode length in maybe more than 1 bytes
+    size_t needed_bytes = 0;
+    while (bytes != 0) {
+      bytes >>= 8;
+      needed_bytes++;
+    }
+    char c = 0;
+    if (seof == FALSE) {
+      c |= 1 << 7;
+    }
+    c+= needed_bytes;
+    buf.put_c(c);
+    for (int i = needed_bytes - 1; i >= 0; i--) {
+      buf.put_c(static_cast<unsigned char>(num_bytes >> i*8));
+    }
+  }
+}
+
+size_t decode_oer_length(TTCN_Buffer& buf, boolean seof) {
+  const unsigned char* uc = buf.get_read_data();
+  buf.increase_pos(1);
+  
+  size_t num_bytes = 0;
+  if (uc[0] & 0x80 || seof == TRUE) {
+    size_t bytes = uc[0] & (seof == FALSE ? 0x7F : 0xFF);
+    for (size_t i = 1; i < bytes+1; i++) {
+      num_bytes += uc[i] << (bytes-i)*8;
+    }
+    buf.increase_pos(bytes);
+  } else {
+    // its length is encoded in the last 7 bytes
+    num_bytes = *uc & 0x7F;
+  }
+  return num_bytes;
+}
+
+void encode_oer_tag(const ASN_BERdescriptor_t& descr, TTCN_Buffer& buf) {
+  char c;
+  switch(descr.tags[descr.n_tags-1].tagclass) {
+    case ASN_TAG_UNIV:
+      c = 0;
+      break;
+    case ASN_TAG_APPL:
+      c = 1 << 6;
+      break;
+    case ASN_TAG_CONT:
+      c = 1 << 7;
+      break;
+    case ASN_TAG_PRIV:
+      c = 3 << 6;
+      break;
+    default:
+      TTCN_error("Incorrect tagclass while encoding OER tag.");
+  }
+  
+  unsigned int tagnum = descr.tags[descr.n_tags-1].tagnumber;
+  if (tagnum < 63) {
+    c += tagnum;
+    buf.put_c(c);
+  } else {
+    c += 63; // set every bit to 1 from 6 to 1 bit
+    buf.put_c(c);
+    int first_bit_pos = 8*sizeof(unsigned int) - 1;
+    for (; first_bit_pos != 0; first_bit_pos--) {
+      if ((tagnum >> first_bit_pos) & 1) {
+        break;
+      }
+    }
+    size_t needed_bytes = first_bit_pos / 7 + 1;// todo test 0
+    unsigned char * uc = (unsigned char*)Malloc(needed_bytes * sizeof(unsigned char));
+    size_t buf_pos = 0;
+    uc[buf_pos] = 0;
+    int pos = first_bit_pos % 7;
+    while (first_bit_pos > -1) {
+
+        uc[buf_pos] += ((tagnum >> first_bit_pos) & 1) << (pos);
+        pos--;
+      if (pos == -1) {
+        pos = 6;
+        if (buf_pos != needed_bytes - 1) {
+          uc[buf_pos] |= 1 << 7;
+        }
+        buf_pos++;
+        if (buf_pos != needed_bytes) {
+          uc[buf_pos] = 0;
+        }
+      }
+      first_bit_pos--;
+    }
+    buf.put_s(needed_bytes, uc);
+    Free(uc);
+  }
+}
+
+ASN_Tag_t decode_oer_tag(TTCN_Buffer& buf) {
+  ASN_Tag_t tag;
+  const unsigned char * uc = buf.get_read_data();
+  int tagclass = (uc[0] & 0xC0) >> 6;
+  switch (tagclass) {
+    case 0:
+      tag.tagclass = ASN_TAG_UNIV;
+      break;
+    case 1:
+      tag.tagclass = ASN_TAG_APPL;
+      break;
+    case 2:
+      tag.tagclass = ASN_TAG_CONT;
+      break;
+    case 3:
+      tag.tagclass = ASN_TAG_PRIV;
+      break;
+    default:
+      tag.tagclass = ASN_TAG_UNDEF;
+      break;
+  }
+
+  buf.increase_pos(1);
+  if ((uc[0] & 0x3F) != 0x3F) {
+    // Encoded on 6 bits
+    tag.tagnumber = (uc[0] & 0x3F);
+  } else {
+    size_t tagnumber = 0;
+    // Encoded on multiple bytes
+    size_t buf_pos = 1;
+    // If more bytes to follow
+    while (uc[buf_pos] & 0x80) {
+      tagnumber += uc[buf_pos] & 0x7F;
+      tagnumber <<= 7;
+      buf_pos++;
+    }
+    tagnumber += uc[buf_pos];
+    tag.tagnumber = tagnumber;
+    buf.increase_pos(buf_pos);
+  }
+  return tag;
+}
+
+const TTCN_OERdescriptor_t BOOLEAN_oer_ = { 0, FALSE, -1, FALSE };
+
+const TTCN_OERdescriptor_t INTEGER_oer_ = { -1, TRUE, 0, FALSE };
+
+const TTCN_OERdescriptor_t BITSTRING_oer_ = { 0, FALSE, -1, FALSE };
+
+const TTCN_OERdescriptor_t OCTETSTRING_oer_ = { 0, FALSE, -1, FALSE };
+
+const TTCN_OERdescriptor_t FLOAT_oer_ = { 0, FALSE, -1, FALSE };
+
+const TTCN_OERdescriptor_t ASN_NULL_oer_ = { 0, FALSE, -1, FALSE };
+
+const TTCN_OERdescriptor_t IA5String_oer_ = { 0, FALSE, -1, FALSE };
+
+const TTCN_OERdescriptor_t VisibleString_oer_ = { 0, FALSE, -1, FALSE };
+
+const TTCN_OERdescriptor_t NumericString_oer_ = { 0, FALSE, -1, FALSE };
+
+const TTCN_OERdescriptor_t PrintableString_oer_ = { 0, FALSE, -1, FALSE };
+
+const TTCN_OERdescriptor_t BMPString_oer_ = { 0, FALSE, -1, FALSE };
+
+const TTCN_OERdescriptor_t UniversalString_oer_ = { 0, FALSE, -1, FALSE };
+
+const TTCN_OERdescriptor_t UTF8String_oer_ = { 0, FALSE, -1, FALSE };
+
+const TTCN_OERdescriptor_t TeletexString_oer_ = { 0, FALSE, -1, FALSE };
+
+const TTCN_OERdescriptor_t VideotexString_oer_ = { 0, FALSE, -1, FALSE };
+
+const TTCN_OERdescriptor_t GraphicString_oer_ = { 0, FALSE, -1, FALSE };
+
+const TTCN_OERdescriptor_t GeneralString_oer_ = { 0, FALSE, -1, FALSE };
+
+const TTCN_OERdescriptor_t OBJID_oer_ = { 0, FALSE, -1, FALSE };
+
+const TTCN_OERdescriptor_t ASN_ROID_oer_ = { 0, FALSE, -1, FALSE };
+
+const TTCN_OERdescriptor_t EMBEDDED_PDV_oer_ = { 0, FALSE, -1, FALSE };
+
+const TTCN_OERdescriptor_t EXTERNAL_oer_ = { 0, FALSE, -1, FALSE };
+
+const TTCN_OERdescriptor_t ObjectDescriptor_oer_ = { 0, FALSE, -1, FALSE };
\ No newline at end of file
diff --git a/core/OER.hh b/core/OER.hh
index f60910847422e388b568ad99941469b4a91c5812..d1bbab55d5bd00ab5768c4dd842e9409c451461a 100644
--- a/core/OER.hh
+++ b/core/OER.hh
@@ -13,14 +13,57 @@
 #define OER_HH
 
 #include "Types.h"
+#include "Vector.hh"
+
+class TTCN_Buffer;
+class ASN_BERdescriptor_t;
+class ASN_Tag_t;
 
 struct TTCN_OERdescriptor_t 
 {
   int bytes;
   boolean signed_;
+  int length;
+  boolean extendable; // Always false. Possibly a bug with is_extendable()
+};
+
+struct OER_struct
+{
+  OER_struct() : opentype_poses(0), pos(0) {}
+  Vector<size_t> opentype_poses;
+  size_t pos;
 };
 
+void encode_oer_length(size_t num_bytes, TTCN_Buffer& buf, boolean seof);
+
+size_t decode_oer_length(TTCN_Buffer& buf, boolean seof);
+
+void encode_oer_tag(const ASN_BERdescriptor_t& descr, TTCN_Buffer& buf);
+
+ASN_Tag_t decode_oer_tag(TTCN_Buffer& buf);
+
 extern const TTCN_OERdescriptor_t BOOLEAN_oer_;
+extern const TTCN_OERdescriptor_t INTEGER_oer_;
+extern const TTCN_OERdescriptor_t BITSTRING_oer_;
+extern const TTCN_OERdescriptor_t OCTETSTRING_oer_;
+extern const TTCN_OERdescriptor_t FLOAT_oer_;
+extern const TTCN_OERdescriptor_t ASN_NULL_oer_;
+extern const TTCN_OERdescriptor_t IA5String_oer_;
+extern const TTCN_OERdescriptor_t VisibleString_oer_;
+extern const TTCN_OERdescriptor_t NumericString_oer_;
+extern const TTCN_OERdescriptor_t PrintableString_oer_;
+extern const TTCN_OERdescriptor_t BMPString_oer_;
+extern const TTCN_OERdescriptor_t UniversalString_oer_;
+extern const TTCN_OERdescriptor_t UTF8String_oer_;
+extern const TTCN_OERdescriptor_t TeletexString_oer_;
+extern const TTCN_OERdescriptor_t VideotexString_oer_;
+extern const TTCN_OERdescriptor_t GraphicString_oer_;
+extern const TTCN_OERdescriptor_t GeneralString_oer_;
+extern const TTCN_OERdescriptor_t OBJID_oer_;
+extern const TTCN_OERdescriptor_t ASN_ROID_oer_;
+extern const TTCN_OERdescriptor_t EMBEDDED_PDV_oer_;
+extern const TTCN_OERdescriptor_t EXTERNAL_oer_;
+extern const TTCN_OERdescriptor_t ObjectDescriptor_oer_;
 
 #endif /* OER_HH */
 
diff --git a/core/Objid.cc b/core/Objid.cc
index dd09d7b082341d30ea5720b6b810671de58e7c27..68dbf0271465d89a576f646877b9fc68a281ea89 100644
--- a/core/Objid.cc
+++ b/core/Objid.cc
@@ -28,6 +28,7 @@
 #include "../common/static_check.h"
 #include "Integer.hh"
 #include "Optional.hh"
+#include "OER.hh"
 
 static const size_t MIN_COMPONENTS = 2;
 
@@ -309,6 +310,12 @@ void OBJID::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
     JSON_encode(p_td, tok);
     p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
     break;}
+  case TTCN_EncDec::CT_OER: {
+    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_encode(p_td, p_buf);
+    break;}
   default:
     TTCN_error("Unknown coding method requested to encode type '%s'",
                p_td.name);
@@ -362,6 +369,13 @@ void OBJID::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
                , p_td.name);
     p_buf.set_pos(tok.get_buf_pos());
     break;}
+  case TTCN_EncDec::CT_OER: {
+      TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_struct p_oer;
+    OER_decode(p_td, p_buf, p_oer);
+    break;}
   default:
     TTCN_error("Unknown coding method requested to decode type '%s'",
                p_td.name);
@@ -663,6 +677,83 @@ int OBJID::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok,
   return (int)dec_len;
 }
 
+int OBJID::OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const {
+  if (!is_bound()) {
+    TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
+      "Encoding an unbound object identifier value.");
+    return -1;
+  }
+  ASN_BER_TLV_t* new_tlv= BER_encode_TLV(p_td,0);
+  unsigned char *Vptr=new_tlv->V.str.Vstr;
+  encode_oer_length(new_tlv->V.str.Vlen, p_buf, FALSE);
+  p_buf.put_s(new_tlv->V.str.Vlen, Vptr);
+  ASN_BER_TLV_t::destruct(new_tlv, FALSE);
+  return 0;
+}
+  
+int OBJID::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, OER_struct&) {
+  // The same as BER
+  TTCN_EncDec_ErrorContext ec("While decoding OBJID type: ");
+  boolean eoc=FALSE; // end-of-component
+  int i=0;
+  unsigned long long ull=0;
+  STATIC_ASSERT(sizeof(ull) > sizeof(objid_element));
+  size_t bytes = decode_oer_length(p_buf, FALSE);
+  const unsigned char* Vptr = p_buf.get_read_data();
+  boolean err_repr=FALSE;
+  while (Vptr < p_buf.get_read_data() + bytes) {
+    ull |= *Vptr & 0x7F;
+    if ((*Vptr & 0x80) && err_repr==FALSE) { // not-eoc
+      if (ull & unsigned_llong_7msb) {
+        ec.error(TTCN_EncDec::ET_REPR,
+                 "Value of the #%d component is too big.", i+1);
+        err_repr=TRUE;
+      }
+      ull<<=7;
+      eoc=FALSE;
+    }
+    else { // eoc
+      if (i==0 && p_td.asnbasetype==TTCN_Typedescriptor_t::OBJID) {
+        // first two component of objid
+        switch(ull/40ul) {
+        case 0:
+          (*this)[0]=0; break;
+        case 1:
+          (*this)[0]=1; break;
+        default:
+          (*this)[0]=2; break;
+        }
+        (*this)[1]=(int)(ull-40*(*this)[0]);
+        i=1;
+      }
+      else { // other components (>2)
+        // objid_element is UINT/ULONG; the result of the cast is Uxxx_MAX.
+        // It's computed at compile time.
+        if(ull > ((objid_element)-1)) {
+          if(err_repr==FALSE)
+            ec.error(TTCN_EncDec::ET_REPR,
+                     "Value of the #%d component is too big.", i+1);
+          (*this)[i]=(objid_element)-1;
+          // remember the first overflow
+          if (val_ptr->overflow_idx < 0) val_ptr->overflow_idx = i;
+        } // if ul too big
+        else
+          (*this)[i]=(objid_element)ull;
+      }
+      err_repr=FALSE;
+      ull=0;
+      eoc=TRUE;
+      i++;
+    } // eoc
+    Vptr++;
+  } // while Vptr...
+  if(eoc==FALSE)
+    ec.error(TTCN_EncDec::ET_INVAL_MSG,
+             "The last component (#%d) is unterminated.", i+1);
+  p_buf.increase_pos(bytes);
+  return 0;
+}
+
 void OBJID_template::clean_up()
 {
   if (template_selection == VALUE_LIST ||
diff --git a/core/Objid.hh b/core/Objid.hh
index 374009ef73cbeba2c8314b15d970c77ce97923ce..db7901d784b0e3723e585f38a24d5afa9f804d0e 100644
--- a/core/Objid.hh
+++ b/core/Objid.hh
@@ -115,6 +115,14 @@ public:
   /** Decodes accordingly to the JSON decoding rules.
     * Returns the length of the encoded data. */
   int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean);
+  
+  /** Encodes accordingly to the OER encoding rules.
+    * Returns the length of the encoded data. */
+  int OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const;
+  
+  /** Decodes accordingly to the OER decoding rules.
+    * Returns the length of the encoded data. */
+  int OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, OER_struct&);
 };
 
 // objid template class
diff --git a/core/Octetstring.cc b/core/Octetstring.cc
index c40cb88a65e4b1c218570444cf51c223cf577ebf..6973c7290d32c7bcda690283566c65a45db1bfd0 100644
--- a/core/Octetstring.cc
+++ b/core/Octetstring.cc
@@ -37,6 +37,7 @@
 #include "Optional.hh"
 
 #include "../common/dbgnew.hh"
+#include "OER.hh"
 #include <string.h>
 #include <ctype.h>
 
@@ -653,6 +654,12 @@ void OCTETSTRING::encode(const TTCN_Typedescriptor_t& p_td,
     JSON_encode(p_td, tok);
     p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
     break;}
+  case TTCN_EncDec::CT_OER: {
+    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_encode(p_td, p_buf);
+    break;}
   default:
     TTCN_error("Unknown coding method requested to encode type '%s'",
                p_td.name);
@@ -740,6 +747,13 @@ void OCTETSTRING::decode(const TTCN_Typedescriptor_t& p_td,
                , p_td.name);
     p_buf.set_pos(tok.get_buf_pos());
     break;}
+  case TTCN_EncDec::CT_OER: {
+      TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_struct p_oer;
+    OER_decode(p_td, p_buf, p_oer);
+    break;}
   default:
     TTCN_error("Unknown coding method requested to decode type '%s'",
                p_td.name);
@@ -1389,6 +1403,36 @@ int OCTETSTRING::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer&
   return (int)dec_len;
 }
 
+int OCTETSTRING::OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const {
+  if (!is_bound()) {
+    TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
+      "Encoding an unbound octetstring value.");
+    return -1;
+  }
+  if (p_td.oer->length == -1) {
+    encode_oer_length(lengthof(), p_buf, FALSE);
+  }
+  p_buf.put_os(*this);
+  return 0;
+}
+  
+
+int OCTETSTRING::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, OER_struct&) {
+  size_t bytes;
+  if (p_td.oer->length == -1) {
+    bytes = decode_oer_length(p_buf, FALSE);
+  } else {
+    bytes = p_td.oer->length;
+  }
+  init_struct(bytes);
+  const unsigned char* uc = p_buf.get_read_data();
+  for (size_t i = 0; i < bytes; i++) {
+    val_ptr->octets_ptr[i] = uc[i];
+  }
+  p_buf.increase_pos(bytes);
+  return 0;
+}
+
 // octetstring element class
 
 OCTETSTRING_ELEMENT::OCTETSTRING_ELEMENT(boolean par_bound_flag,
diff --git a/core/Octetstring.hh b/core/Octetstring.hh
index 76f259b78c1b3e28cd9d98dd9ed1089b41dc5b25..3323c9c3b6df40f4180342faed8cb5d0b36e622a 100644
--- a/core/Octetstring.hh
+++ b/core/Octetstring.hh
@@ -192,6 +192,14 @@ public:
   /** Decodes accordingly to the JSON encoding rules.
     * Returns the length of the decoded data. */
   int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean);
+  
+  /** Encodes accordingly to the OER encoding rules.
+    * Returns the length of the encoded data. */
+  int OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const;
+  
+  /** Decodes accordingly to the JSON encoding rules.
+    * Returns the length of the decoded data. */
+  int OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, OER_struct&);
 };
 
 
diff --git a/core/Optional.hh b/core/Optional.hh
index 23ee70e27844fa0d548b2c62e52bea154e7fce67..cbddc0bca123fcf1bc09b35736ad770c3946468c 100644
--- a/core/Optional.hh
+++ b/core/Optional.hh
@@ -330,6 +330,8 @@ public:
                   boolean no_err=FALSE, boolean first_call=TRUE);
   int JSON_encode_negtest(const Erroneous_descriptor_t*,
                           const TTCN_Typedescriptor_t&, JSON_Tokenizer&) const;
+  int OER_encode_negtest(const Erroneous_descriptor_t*,
+                          const TTCN_Typedescriptor_t&, TTCN_Buffer&) const;
 #endif
   
   /** Encodes accordingly to the JSON encoding rules.
@@ -340,6 +342,16 @@ public:
     * Returns the length of the decoded data. */
   int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean);
   
+  /** Encodes accordingly to the OER encoding rules.
+    * Returns the length of the encoded data. */
+  int OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const;
+  
+  /** Decodes accordingly to the OER encoding rules.
+    * Returns the length of the decoded data. */
+  int OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, OER_struct&);
+  
+  void OER_decode_opentypes(TTCN_Type_list& p_typelist, TTCN_Buffer& p_buf, OER_struct& p_oer);
+  
 #ifdef TITAN_RUNTIME_2
   /** Called before an element of an optional record of/set of is indexed and passed as an
     * 'inout' or 'out' parameter to a function (only in Runtime2).
@@ -890,6 +902,58 @@ int OPTIONAL<T_type>::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokeni
   return dec_len;
 }
 
+template<typename T_type>
+int OPTIONAL<T_type>::OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const
+{
+#ifdef TITAN_RUNTIME_2
+  switch(get_selection()) {
+#else
+  switch(optional_selection) {
+#endif
+  case OPTIONAL_PRESENT:
+    return optional_value->OER_encode(p_td, p_buf);
+  case OPTIONAL_OMIT:
+    return 0;
+  case OPTIONAL_UNBOUND:
+  default:
+    TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
+      "Encoding an unbound optional value.");
+    return -1;
+  }
+}
+
+#ifdef TITAN_RUNTIME_2
+template<typename T_type>
+int OPTIONAL<T_type>::OER_encode_negtest(const Erroneous_descriptor_t*,
+                                        const TTCN_Typedescriptor_t&,
+                                        TTCN_Buffer&) const 
+{
+// TODO
+  return 0;
+}
+#endif
+
+template<typename T_type>
+int OPTIONAL<T_type>::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, OER_struct& p_oer)
+{
+  set_to_present();
+  optional_value->OER_decode(p_td, p_buf, p_oer);
+  return 0;
+}
+
+template<typename T_type>
+void OPTIONAL<T_type>::OER_decode_opentypes(TTCN_Type_list& p_typelist, TTCN_Buffer& p_buf, OER_struct& p_oer)
+{
+#ifdef TITAN_RUNTIME_2
+  if (is_present()) {
+    optional_selection = OPTIONAL_PRESENT;
+#else
+  if (optional_selection==OPTIONAL_PRESENT) {
+#endif
+    optional_value->OER_decode_opentypes(p_typelist, p_buf, p_oer);
+  }
+}
+
 #ifdef TITAN_RUNTIME_2
 template<typename T_type>
 void OPTIONAL<T_type>::add_refd_index(int index)
diff --git a/core/Universal_charstring.cc b/core/Universal_charstring.cc
index 3bb4fb6c1d78a983bde3b25034c6e23ff57e2af3..86465842b12ebfdd7f4b102a93954c2dbdd52858 100644
--- a/core/Universal_charstring.cc
+++ b/core/Universal_charstring.cc
@@ -38,6 +38,7 @@
 #include "Addfunc.hh" // for unichar2int
 #include "TEXT.hh"
 #include "Optional.hh"
+#include "OER.hh"
 #include <string>
 #include <iostream>
 #include <stdint.h>
@@ -1174,6 +1175,12 @@ void UNIVERSAL_CHARSTRING::encode(const TTCN_Typedescriptor_t& p_td,
     JSON_encode(p_td, tok);
     p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
     break; }
+  case TTCN_EncDec::CT_OER: {
+    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_encode(p_td, p_buf);
+    break;}
   default:
     TTCN_error("Unknown coding method requested to encode type '%s'",
                p_td.name);
@@ -1259,6 +1266,13 @@ void UNIVERSAL_CHARSTRING::decode(const TTCN_Typedescriptor_t& p_td,
                , p_td.name);
     p_buf.set_pos(tok.get_buf_pos());
     break;}
+  case TTCN_EncDec::CT_OER: {
+      TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_struct p_oer;
+    OER_decode(p_td, p_buf, p_oer);
+    break;}
   default:
     TTCN_error("Unknown coding method requested to decode type '%s'",
                p_td.name);
@@ -2609,6 +2623,118 @@ int UNIVERSAL_CHARSTRING::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_To
   return (int)dec_len;
 }
 
+int UNIVERSAL_CHARSTRING::OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const {
+  if (!is_bound()) {
+    TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
+      "Encoding an unbound universal charstring value.");
+    return -1;
+  }
+  if (charstring)
+    const_cast<UNIVERSAL_CHARSTRING&>(*this).convert_cstr_to_uni();
+  TTCN_Buffer buf;
+  switch(p_td.asnbasetype) {
+  case TTCN_Typedescriptor_t::TELETEXSTRING:
+    buf.put_os(TTCN_TeletexString_2_ISO2022(*this));
+    break;
+  case TTCN_Typedescriptor_t::VIDEOTEXSTRING:
+    buf.put_os(TTCN_VideotexString_2_ISO2022(*this));
+    break;
+  case TTCN_Typedescriptor_t::GRAPHICSTRING:
+    buf.put_os(TTCN_GraphicString_2_ISO2022(*this));
+    break;
+  case TTCN_Typedescriptor_t::GENERALSTRING:
+    buf.put_os(TTCN_GeneralString_2_ISO2022(*this));
+    break;
+  case TTCN_Typedescriptor_t::UNIVERSALSTRING:
+    for(int i=0; i<val_ptr->n_uchars; i++) {
+      buf.put_c(val_ptr->uchars_ptr[i].uc_group);
+      buf.put_c(val_ptr->uchars_ptr[i].uc_plane);
+      buf.put_c(val_ptr->uchars_ptr[i].uc_row);
+      buf.put_c(val_ptr->uchars_ptr[i].uc_cell);
+    }
+    break;
+  case TTCN_Typedescriptor_t::BMPSTRING:
+    for(int i=0; i<val_ptr->n_uchars; i++) {
+      buf.put_c(val_ptr->uchars_ptr[i].uc_row);
+      buf.put_c(val_ptr->uchars_ptr[i].uc_cell);
+    }
+    break;
+  case TTCN_Typedescriptor_t::UTF8STRING:
+    encode_utf8(buf);
+    break;
+  default:
+    TTCN_EncDec_ErrorContext::error_internal
+      ("Missing/wrong basetype info for type '%s'.", p_td.name);
+  }
+  if (p_td.oer->length == -1) {
+    encode_oer_length(buf.get_len(), p_buf, FALSE);
+  }
+  p_buf.put_buf(buf);
+  return 0;
+}
+  
+int UNIVERSAL_CHARSTRING::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, OER_struct&) {
+  size_t bytes;
+  if (p_td.oer->length == -1) {
+    bytes = decode_oer_length(p_buf, FALSE);
+  } else {
+    bytes = p_td.oer->length;
+  }
+  OCTETSTRING ostr(bytes, p_buf.get_read_data());
+  const unsigned char* os=ostr;
+  switch(p_td.asnbasetype) {
+  case TTCN_Typedescriptor_t::TELETEXSTRING:
+    *this=TTCN_ISO2022_2_TeletexString(ostr);
+    break;
+  case TTCN_Typedescriptor_t::VIDEOTEXSTRING:
+    *this=TTCN_ISO2022_2_VideotexString(ostr);
+    break;
+  case TTCN_Typedescriptor_t::GRAPHICSTRING:
+    *this=TTCN_ISO2022_2_GraphicString(ostr);
+    break;
+  case TTCN_Typedescriptor_t::GENERALSTRING:
+    *this=TTCN_ISO2022_2_GeneralString(ostr);
+    break;
+  case TTCN_Typedescriptor_t::UNIVERSALSTRING: {
+    if(bytes%4)
+      TTCN_EncDec_ErrorContext::error
+        (TTCN_EncDec::ET_DEC_UCSTR, "Length of UCS-4-coded character"
+         " string is not multiple of 4.");
+    int ucs_len=bytes/4;
+    init_struct(ucs_len);
+    for(int i=0; i<ucs_len; i++) {
+      val_ptr->uchars_ptr[i].uc_group=os[0];
+      val_ptr->uchars_ptr[i].uc_plane=os[1];
+      val_ptr->uchars_ptr[i].uc_row=os[2];
+      val_ptr->uchars_ptr[i].uc_cell=os[3];
+      os+=4;
+    }
+    break; }
+  case TTCN_Typedescriptor_t::BMPSTRING: {
+    if(bytes%2)
+      TTCN_EncDec_ErrorContext::error
+        (TTCN_EncDec::ET_DEC_UCSTR, "Length of UCS-2-coded character"
+         " string is not multiple of 2.");
+    int ucs_len=bytes/2;
+    init_struct(ucs_len);
+    for(int i=0; i<ucs_len; i++) {
+      val_ptr->uchars_ptr[i].uc_group=0;
+      val_ptr->uchars_ptr[i].uc_plane=0;
+      val_ptr->uchars_ptr[i].uc_row=os[0];
+      val_ptr->uchars_ptr[i].uc_cell=os[1];
+      os+=2;
+    }
+    break; }
+  case TTCN_Typedescriptor_t::UTF8STRING:
+    decode_utf8(bytes, os);
+    break;
+  default:
+    TTCN_EncDec_ErrorContext::error_internal
+      ("Missing/wrong basetype info for type '%s'.", p_td.name);
+  } // switch
+  p_buf.increase_pos(bytes);
+  return 0;
+}
 
 static void fill_continuing_octets(int n_continuing,
   unsigned char *continuing_ptr, int n_octets,
diff --git a/core/Universal_charstring.hh b/core/Universal_charstring.hh
index d0ac3728b32a8e7b8e5a957e868b2fbb01a49029..3888721fda2823d21bd24a5d1423ff1218d0c052 100644
--- a/core/Universal_charstring.hh
+++ b/core/Universal_charstring.hh
@@ -405,6 +405,10 @@ public:
     * Returns the length of the decoded data. */
   int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean);
   
+  int OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const;
+  
+  int OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, OER_struct&);
+  
   /** Converts a string containing a character coding format to its corresponding
     * enum value.
     * @param coding_str string containing the coding format
diff --git a/core2/Basetype2.cc b/core2/Basetype2.cc
index 6680a650e2b953eb03a9554c3720541b68434af4..47d760eeb4001a50b68616d7d095c2d24ef5f576 100644
--- a/core2/Basetype2.cc
+++ b/core2/Basetype2.cc
@@ -35,6 +35,7 @@
 #include "Universal_charstring.hh"
 #include "Addfunc.hh"
 #include "PreGenRecordOf.hh"
+#include "Encdec.hh"
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -196,6 +197,13 @@ int Base_Type::JSON_encode_negtest_raw(JSON_Tokenizer&) const
   return 0;
 }
 
+int Base_Type::OER_encode_negtest_raw(JSON_Tokenizer&) const
+{
+  TTCN_error("A value of type %s cannot be used as erroneous raw value for OER encoding.",
+             get_descriptor()->name);
+  return 0;
+}
+
 int Base_Type::XER_encode_negtest(const Erroneous_descriptor_t* /*p_err_descr*/,
   const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, unsigned int flavor2, int indent, embed_values_enc_struct_t*) const
 {
@@ -216,6 +224,13 @@ int Base_Type::JSON_encode_negtest(const Erroneous_descriptor_t* /*p_err_descr*/
   return 0;
 }
 
+int Base_Type::OER_encode_negtest(const Erroneous_descriptor_t* /*p_err_descr*/,
+  const TTCN_Typedescriptor_t& /*p_td*/, TTCN_Buffer& /*p_tok*/) const
+{
+  TTCN_error("Internal error: calling Base_Type::OER_encode_negtest().");
+  return 0;
+}
+
 #else
 #error this is for RT2 only
 #endif
@@ -1650,6 +1665,45 @@ int Record_Of_Type::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenize
   return (int)dec_len;
 }
 
+int Record_Of_Type::OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const {
+  if (!is_bound()) {
+    TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
+      "Encoding an unbound %s of value.", is_set() ? "set" : "record");
+    return -1;
+  }
+  encode_oer_length(get_nof_elements(), p_buf, TRUE);
+  for (int i = 0; i < get_nof_elements(); i++) {
+    get_at(i)->OER_encode(*p_td.oftype_descr, p_buf);
+  }
+  return 0;
+}
+  
+int Record_Of_Type::OER_encode_negtest(const Erroneous_descriptor_t*, const TTCN_Typedescriptor_t&, TTCN_Buffer&) const {
+  //TODO
+  return 0;
+}
+  
+int Record_Of_Type::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, OER_struct& p_oer) {
+  size_t nof_elements = decode_oer_length(p_buf, TRUE);
+  set_size(nof_elements);
+  for (size_t i = 0; i < nof_elements; i++) {
+    get_at(i)->OER_decode(*p_td.oftype_descr, p_buf, p_oer);
+  }
+  return 0;
+}
+
+void Record_Of_Type::OER_decode_opentypes(TTCN_Type_list& p_typelist, TTCN_Buffer& p_buf, OER_struct& p_oer)
+{
+  p_typelist.push(this);
+  TTCN_EncDec_ErrorContext ec_0("Component #");
+  TTCN_EncDec_ErrorContext ec_1;
+  for(int elem_i=0; elem_i<get_nof_elements(); elem_i++) {
+    ec_1.set_msg("%d: ", elem_i);
+    get_at(elem_i)->OER_decode_opentypes(p_typelist, p_buf, p_oer);
+  }
+  p_typelist.pop();
+}
+
 void Record_Of_Type::encode(const TTCN_Typedescriptor_t& p_td,
   TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
 {
@@ -1695,6 +1749,12 @@ void Record_Of_Type::encode(const TTCN_Typedescriptor_t& p_td,
     JSON_encode(p_td, tok);
     p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
     break;}
+  case TTCN_EncDec::CT_OER: {
+    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_encode(p_td, p_buf);
+    break;}
   default:
     TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
   }
@@ -1768,6 +1828,13 @@ void Record_Of_Type::decode(const TTCN_Typedescriptor_t& p_td,
         "because invalid or incomplete message was received", p_td.name);
     p_buf.set_pos(tok.get_buf_pos());
     break;}
+  case TTCN_EncDec::CT_OER: {
+      TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_struct p_oer;
+    OER_decode(p_td, p_buf, p_oer);
+    break;}
   default:
     TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
   }
@@ -2875,6 +2942,12 @@ void Record_Type::encode(const TTCN_Typedescriptor_t& p_td,
     JSON_encode(p_td, tok);
     p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
     break;}
+  case TTCN_EncDec::CT_OER: {
+    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_encode(p_td, p_buf);
+    break;}
   default:
     TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
   }
@@ -2965,6 +3038,13 @@ void Record_Type::decode(const TTCN_Typedescriptor_t& p_td,
         " message was received", p_td.name);
     p_buf.set_pos(tok.get_buf_pos());
     break;}
+  case TTCN_EncDec::CT_OER: {
+      TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_struct p_oer;
+    OER_decode(p_td, p_buf, p_oer);
+    break;}
   default:
     TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
   }
@@ -6067,6 +6147,106 @@ int Record_Type::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer&
   return (int)dec_len;
 }
 
+int Record_Type::OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf) const {
+  if (!is_bound()) {
+    TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
+      "Encoding an unbound %s value.", is_set() ? "set" : "record");
+    return -1;
+  }
+  int next_default_idx = 0;
+  const default_struct* default_indexes = get_default_indexes();
+  int field_count = get_count();
+  int pos = 8;
+  char c = 0;
+  for (int i = 0; i < field_count; i++) {
+    boolean is_default_field = default_indexes && (default_indexes[next_default_idx].index==i);
+    if (is_default_field) {
+      next_default_idx++;
+    }
+    if (get_at(i)->is_optional() || is_default_field) {
+      pos--;
+      c += get_at(i)->is_present() << pos;
+      if (pos == 0) {
+        p_buf.put_c(c);
+        pos = 8;
+        c = 0;
+      }
+    }
+  }
+  if (pos != 8) {
+    p_buf.put_c(c);
+  }
+  for (int i = 0; i < field_count; ++i) {
+    get_at(i)->OER_encode(*fld_descr(i), p_buf);
+  }
+  return 0;
+}
+  
+int Record_Type::OER_encode_negtest(const Erroneous_descriptor_t*, const TTCN_Typedescriptor_t&, TTCN_Buffer&) const {
+  //TODO
+  return 0;
+}
+  
+int Record_Type::OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf, OER_struct& p_oer) {
+  int field_count = get_count();
+  size_t nof_opt = 0;
+  int next_default_idx = 0;
+  const default_struct* default_indexes = get_default_indexes();
+  for (int i = 0; i < field_count; i++) {
+    boolean is_default_field = default_indexes && (default_indexes[next_default_idx].index==i);
+    if (is_default_field) {
+      next_default_idx++;
+    }
+    if (get_at(i)->is_optional() || is_default_field) {
+      nof_opt++;
+    }
+  }
+  size_t act_pos = 0;
+  size_t bytes = nof_opt / 8 + (nof_opt % 8 == 0 ? 0 : 1);
+  const unsigned char* uc = p_buf.get_read_data();
+  p_buf.increase_pos(bytes);
+  next_default_idx = 0;
+  for (int i = 0; i < field_count; ++i) {
+    boolean is_default_field = default_indexes && (default_indexes[next_default_idx].index==i);
+    if (is_default_field) {
+      next_default_idx++;
+    }
+    if (get_at(i)->is_optional() || is_default_field) {
+      if (!(uc[0] & 1 << (7-act_pos))) {
+        get_at(i)->set_to_omit();
+      } else {
+        get_at(i)->OER_decode(*fld_descr(i), p_buf, p_oer);
+      }
+      act_pos++;
+      if (act_pos == 8) {
+        uc = uc + 1;
+        act_pos = 0;
+      }
+    } else {
+      get_at(i)->OER_decode(*fld_descr(i), p_buf, p_oer);
+    }
+  }
+  if (is_opentype_outermost()) {
+    TTCN_EncDec_ErrorContext ec_1("While decoding opentypes: ");
+    TTCN_Type_list p_typelist;
+    OER_decode_opentypes(p_typelist, p_buf, p_oer);
+  } /* if sdef->opentype_outermost */
+  return 0;
+}
+
+void Record_Type::OER_decode_opentypes(TTCN_Type_list& p_typelist, TTCN_Buffer& p_buf, OER_struct& p_oer)
+{
+  p_typelist.push(this);
+  TTCN_EncDec_ErrorContext ec_0("Component '");
+  TTCN_EncDec_ErrorContext ec_1;
+  int field_cnt = get_count();
+  for(int i=0; i<field_cnt; i++) {
+    ec_1.set_msg("%s': ", fld_name(i));
+    get_at(i)->OER_decode_opentypes(p_typelist, p_buf, p_oer);
+  } /* for i */
+  p_typelist.pop();
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 
 Empty_Record_Type::Empty_Record_Type(): bound_flag(FALSE)
@@ -6190,6 +6370,12 @@ void Empty_Record_Type::encode(const TTCN_Typedescriptor_t& p_td,
     JSON_encode(p_td, tok);
     p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
     break;}
+  case TTCN_EncDec::CT_OER: {
+    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_encode(p_td, p_buf);
+    break;}
   default:
     TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
   }
@@ -6267,6 +6453,13 @@ void Empty_Record_Type::decode(const TTCN_Typedescriptor_t& p_td,
         " message was received", p_td.name);
     p_buf.set_pos(tok.get_buf_pos());
     break;}
+  case TTCN_EncDec::CT_OER: {
+      TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
+    if(!p_td.oer)  TTCN_EncDec_ErrorContext::error_internal(
+      "No OER descriptor available for type '%s'.", p_td.name);
+    OER_struct p_oer;
+    OER_decode(p_td, p_buf, p_oer);
+    break;}
   default:
     TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
   }
@@ -6440,6 +6633,20 @@ int Empty_Record_Type::JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&
   return (int)dec_len;
 }
 
+int Empty_Record_Type::OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const {
+  if (!is_bound()) {
+    TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
+      "Encoding an unbound empty %s value.", is_set() ? "set" : "record");
+    return -1;
+  }
+  return 0;
+}
+  
+int Empty_Record_Type::OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, OER_struct&) {
+  bound_flag = TRUE;
+  return 0;
+}
+
 boolean operator==(null_type /*null_value*/, const Empty_Record_Type& other_value)
 {
   if (!other_value.is_bound())
diff --git a/regression_test/OER/Makefile b/regression_test/OER/Makefile
index 178fa514460ebcb7ee366eca6ac4b613a692e9da..21fda14a38b02c23c0fea6dacd04ffff24e9b223 100644
--- a/regression_test/OER/Makefile
+++ b/regression_test/OER/Makefile
@@ -15,7 +15,7 @@ include $(TOPDIR)/Makefile.regression
 .SUFFIXES: .ttcn .asn .hh
 .PHONY: all clean dep run
 
-TTCN3_LIB = ttcn3$(RT2_SUFFIX)-parallel$(DYNAMIC_SUFFIX)
+TTCN3_LIB = ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX)
 
 TTCN3_MODULES = OER.ttcn
 
@@ -48,10 +48,10 @@ compile: $(TTCN3_MODULES) $(ASN1_MODULES)
 	$(TTCN3_COMPILER) $(COMPILER_FLAGS) $^
 
 clean distclean:
-	$(RM) $(TARGET) $(GENERATED_HEADERS) $(GENERATED_SOURCES) $(OBJECTS) *.log Makefile.bak
+	$(RM) $(TARGET) $(GENERATED_HEADERS) $(GENERATED_SOURCES) $(OBJECTS) *.log Makefile.bak compile
 
 dep: $(GENERATED_SOURCES)
 	makedepend $(CPPFLAGS) $(GENERATED_SOURCES)
 
 run: $(TARGET)
-	$(TTCN3_DIR)/bin/ttcn3_start $(TARGET) OER.cfg
+	./$(TARGET) OER.cfg
diff --git a/regression_test/OER/OER.ttcn b/regression_test/OER/OER.ttcn
index c701e82dcc18cbd99497eb56b48dabd2086d6caa..f8b4c8b383edc8fab849c687c0b4a2b971250887 100644
--- a/regression_test/OER/OER.ttcn
+++ b/regression_test/OER/OER.ttcn
@@ -740,6 +740,2062 @@
  			setverdict(fail, "tc_integer: ", match(s8i, s8ires));
  		}
 
+ 		setverdict(pass);
+ 	}
+
+
+ 	external function enc_MyEnum(in MyEnum pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_MyEnum(in octetstring stream) return MyEnum
+     with { extension "prototype (convert) decode(OER)" }
+
+ 	testcase tc_enumerated() runs on EmptyCT {
+ 		var MyEnum me, meres;
+ 		var octetstring os;
+ 		
+ 		me := e0;
+ 		os := enc_MyEnum(me);
+ 		if (os != '00'O) {
+ 			setverdict(fail, "tc_enumerated: ", match('00'O, os));
+ 		}
+ 		meres := dec_MyEnum(os);
+ 		if (me != meres) {
+ 			setverdict(fail, "tc_enumerated: ", match(me, meres));
+ 		}
+
+ 		me := e1;
+ 		os := enc_MyEnum(me);
+ 		if (os != '01'O) {
+ 			setverdict(fail, "tc_enumerated: ", match('01'O, os));
+ 		}
+ 		meres := dec_MyEnum(os);
+ 		if (me != meres) {
+ 			setverdict(fail, "tc_enumerated: ", match(me, meres));
+ 		}
+
+ 		me := e2;
+ 		os := enc_MyEnum(me);
+ 		if (os != '02'O) {
+ 			setverdict(fail, "tc_enumerated: ", match('02'O, os));
+ 		}
+ 		meres := dec_MyEnum(os);
+ 		if (me != meres) {
+ 			setverdict(fail, "tc_enumerated: ", match(me, meres));
+ 		}
+
+ 		me := ebig;
+ 		os := enc_MyEnum(me);
+ 		if (os != '8407D3CDE9'O) {
+ 			setverdict(fail, "tc_enumerated: ", match('8407D3CDE9'O, os));
+ 		}
+ 		meres := dec_MyEnum(os);
+ 		if (me != meres) {
+ 			setverdict(fail, "tc_enumerated: ", match(me, meres));
+ 		}
+
+ 		me := esmall;
+ 		os := enc_MyEnum(me);
+ 		if (os != '84FEB8D1B4'O) {
+ 			setverdict(fail, "tc_enumerated: ", match('84FEB8D1B4'O, os));
+ 		}
+ 		meres := dec_MyEnum(os);
+ 		if (me != meres) {
+ 			setverdict(fail, "tc_enumerated: ", match(me, meres));
+ 		}
+
+ 		setverdict(pass);
+ 	}
+
+
+ 	external function enc_BitstringRestricted(in BitstringRestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_BitstringRestricted(in octetstring stream) return BitstringRestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_BitstringRestricted2(in BitstringRestricted2 pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_BitstringRestricted2(in octetstring stream) return BitstringRestricted2
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_BitstringRestricted3(in BitstringRestricted3 pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_BitstringRestricted3(in octetstring stream) return BitstringRestricted3
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_BitstringUnrestricted(in BitstringUnrestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_BitstringUnrestricted(in octetstring stream) return BitstringUnrestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+ 	testcase tc_bitstring() runs on EmptyCT {
+ 		var BitstringRestricted bs, bsres;
+ 		var octetstring os;
+
+ 		bs := '01011101'B;
+ 		os := enc_BitstringRestricted(bs);
+ 		if (os != '5D'O) {
+ 			setverdict(fail, "tc_bitstring: ", match('5D'O, os));
+ 		}
+ 		bsres := dec_BitstringRestricted(os);
+ 		if (bs != bsres) {
+ 			setverdict(fail, "tc_bitstring: ", match(bs, bsres));
+ 		}
+
+ 		bs := '00000000'B;
+ 		os := enc_BitstringRestricted(bs);
+ 		if (os != '00'O) {
+ 			setverdict(fail, "tc_bitstring: ", match('00'O, os));
+ 		}
+ 		bsres := dec_BitstringRestricted(os);
+ 		if (bs != bsres) {
+ 			setverdict(fail, "tc_bitstring: ", match(bs, bsres));
+ 		}
+
+ 		bs := '11111111'B;
+ 		os := enc_BitstringRestricted(bs);
+ 		if (os != 'FF'O) {
+ 			setverdict(fail, "tc_bitstring: ", match('FF'O, os));
+ 		}
+ 		bsres := dec_BitstringRestricted(os);
+ 		if (bs != bsres) {
+ 			setverdict(fail, "tc_bitstring: ", match(bs, bsres));
+ 		}
+
+ 		var BitstringRestricted2 bs2, bs2res;
+
+ 		bs2 := '010111011'B;
+ 		os := enc_BitstringRestricted2(bs2);
+ 		if (os != '5D80'O) {
+ 			setverdict(fail, "tc_bitstring: ", match('5D80'O, os));
+ 		}
+ 		bs2res := dec_BitstringRestricted2(os);
+ 		if (bs2 != bs2res) {
+ 			setverdict(fail, "tc_bitstring: ", match(bs2, bs2res));
+ 		}
+
+ 		var BitstringRestricted3 bs3, bs3res;
+
+ 		bs3 := '110'B;
+ 		os := enc_BitstringRestricted3(bs3);
+ 		if (os != 'C0'O) {
+ 			setverdict(fail, "tc_bitstring: ", match('C0'O, os));
+ 		}
+ 		bs3res := dec_BitstringRestricted3(os);
+ 		if (bs3 != bs3res) {
+ 			setverdict(fail, "tc_bitstring: ", match(bs3, bs3res));
+ 		}
+
+ 		var BitstringUnrestricted ubs, ubsres;
+ 		
+ 		ubs := '010111011'B;
+ 		os := enc_BitstringUnrestricted(ubs);
+ 		if (os != '03075D80'O) {
+ 			setverdict(fail, "tc_bitstring: ", match('03075D80'O, os));
+ 		}
+ 		ubsres := dec_BitstringUnrestricted(os);
+ 		if (ubs != ubsres) {
+ 			setverdict(fail, "tc_bitstring: ", match(ubs, ubsres));
+ 		}
+
+ 		ubs := '010111011010'B;
+ 		os := enc_BitstringUnrestricted(ubs);
+ 		if (os != '03045DA0'O) {
+ 			setverdict(fail, "tc_bitstring: ", match('03045DA0'O, os));
+ 		}
+ 		ubsres := dec_BitstringUnrestricted(os);
+ 		if (ubs != ubsres) {
+ 			setverdict(fail, "tc_bitstring: ", match(ubs, ubsres));
+ 		}
+
+ 		ubs := ''B;
+ 		os := enc_BitstringUnrestricted(ubs);
+ 		if (os != '0100'O) {
+ 			setverdict(fail, "tc_bitstring: ", match('0100'O, os));
+ 		}
+ 		ubsres := dec_BitstringUnrestricted(os);
+ 		if (ubs != ubsres) {
+ 			setverdict(fail, "tc_bitstring: ", match(ubs, ubsres));
+ 		}
+
+ 		ubs := '0101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101010101011010101010110101010101101110'B;
+ 		os := enc_BitstringUnrestricted(ubs);
+ 		if (os != '8201FC0555AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AADC0'O) {
+ 			setverdict(fail, "tc_bitstring: ", match('8201FC0555AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AAD55AAB556AADC0'O, os));
+ 		}
+ 		ubsres := dec_BitstringUnrestricted(os);
+ 		if (ubs != ubsres) {
+ 			setverdict(fail, "tc_bitstring: ", match(ubs, ubsres));
+ 		}
+
+ 		setverdict(pass);
+ 	}
+
+ 	external function enc_OctetstringRestricted(in OctetstringRestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_OctetstringRestricted(in octetstring stream) return OctetstringRestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_OctetstringUnrestricted(in OctetstringUnrestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_OctetstringUnrestricted(in octetstring stream) return OctetstringUnrestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+ 	testcase tc_octetstring() runs on EmptyCT {
+ 		var OctetstringRestricted ors, orsres;
+ 		var octetstring os;
+
+ 		ors := 'ABCDABCD'O
+ 		os := enc_OctetstringRestricted(ors);
+ 		if (os != 'ABCDABCD'O) {
+ 			setverdict(fail, "tc_octetstring: ", match('ABCDABCD'O, os));
+ 		}
+ 		orsres := dec_OctetstringRestricted(os);
+ 		if (ors != orsres) {
+ 			setverdict(fail, "tc_octetstring: ", match(ors, orsres));
+ 		}
+
+ 		ors := '00000000'O
+ 		os := enc_OctetstringRestricted(ors);
+ 		if (os != '00000000'O) {
+ 			setverdict(fail, "tc_octetstring: ", match('00000000'O, os));
+ 		}
+ 		orsres := dec_OctetstringRestricted(os);
+ 		if (ors != orsres) {
+ 			setverdict(fail, "tc_octetstring: ", match(ors, orsres));
+ 		}
+
+ 		ors := 'FFFFFFFF'O
+ 		os := enc_OctetstringRestricted(ors);
+ 		if (os != 'FFFFFFFF'O) {
+ 			setverdict(fail, "tc_octetstring: ", match('FFFFFFFF'O, os));
+ 		}
+ 		orsres := dec_OctetstringRestricted(os);
+ 		if (ors != orsres) {
+ 			setverdict(fail, "tc_octetstring: ", match(ors, orsres));
+ 		}
+
+ 		var OctetstringUnrestricted ors2, ors2res;
+ 		ors2 := 'ABCDABCD'O
+ 		os := enc_OctetstringUnrestricted(ors2);
+ 		if (os != '04ABCDABCD'O) {
+ 			setverdict(fail, "tc_octetstring: ", match('04ABCDABCD'O, os));
+ 		}
+
+ 		ors2 := 'ABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFD'O
+ 		os := enc_OctetstringUnrestricted(ors2);
+ 		if (os != '8201E6ABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFD'O) {
+ 			setverdict(fail, "tc_octetstring: ", match('8201E6ABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFDABCD12345678CDAFFD'O, os));
+ 		}
+ 		ors2res := dec_OctetstringUnrestricted(os);
+ 		if (ors2 != ors2res) {
+ 			setverdict(fail, "tc_octetstring: ", match(ors2, ors2res));
+ 		}
+
+
+ 		setverdict(pass);
+ 	}
+
+ 	external function enc_RealUnrestricted(in RealUnrestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_RealUnrestricted(in octetstring stream) return RealUnrestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_RealRestricted(in RealRestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_RealRestricted(in octetstring stream) return RealRestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+ 	testcase tc_float() runs on EmptyCT {
+ 		var RealUnrestricted r, rres;
+ 		var octetstring os;
+
+ 		r := 0.0;
+ 		os := enc_RealUnrestricted(r);
+ 		if (os != '00'O) {
+ 			setverdict(fail, "tc_float: ", match('00'O, os));
+ 		}
+ 		rres := dec_RealUnrestricted(os);
+ 		if (r != rres) {
+ 			setverdict(fail, "tc_float: ", match(r, rres));
+ 		}
+
+ 		r := 3.14;
+ 		os := enc_RealUnrestricted(r);
+ 		if (os != '08033331342E452D32'O) {
+ 			setverdict(fail, "tc_float: ", match('08033331342E452D32'O, os));
+ 		}
+ 		rres := dec_RealUnrestricted(os);
+ 		if (r != rres) {
+ 			setverdict(fail, "tc_float: ", match(r, rres));
+ 		}
+
+ 		r := infinity;
+ 		os := enc_RealUnrestricted(r);
+ 		if (os != '0140'O) {
+ 			setverdict(fail, "tc_float: ", match('0140'O, os));
+ 		}
+ 		rres := dec_RealUnrestricted(os);
+ 		if (r != rres) {
+ 			setverdict(fail, "tc_float: ", match(r, rres));
+ 		}
+
+ 		r := -infinity;
+ 		os := enc_RealUnrestricted(r);
+ 		if (os != '0141'O) {
+ 			setverdict(fail, "tc_float: ", match('0141'O, os));
+ 		}
+ 		rres := dec_RealUnrestricted(os);
+ 		if (r != rres) {
+ 			setverdict(fail, "tc_float: ", match(r, rres));
+ 		}
+
+ 		r := not_a_number;
+ 		os := enc_RealUnrestricted(r);
+ 		if (os != '0142'O) {
+ 			setverdict(fail, "tc_float: ", match('0142'O, os));
+ 		}
+ 		rres := dec_RealUnrestricted(os);
+ 		if (r != rres) {
+ 			setverdict(fail, "tc_float: ", match(r, rres));
+ 		}
+
+
+ 		// Restricted real is not supported. Decoded as normal real.
+ 		var RealRestricted r2, r2res;
+
+ 		r2 := 3.14;
+ 		os := enc_RealRestricted(r2);
+ 		if (os != '08033331342E452D32'O) {
+ 			setverdict(fail, "tc_float: ", match('08033331342E452D32'O, os));
+ 		}
+ 		r2res := dec_RealRestricted(os);
+ 		if (r2 != r2res) {
+ 			setverdict(fail, "tc_float: ", match(r2, r2res));
+ 		}
+
+ 		r2 := infinity;
+ 		os := enc_RealRestricted(r2);
+ 		if (os != '0140'O) {
+ 			setverdict(fail, "tc_float: ", match('0140'O, os));
+ 		}
+ 		r2res := dec_RealRestricted(os);
+ 		if (r2 != r2res) {
+ 			setverdict(fail, "tc_float: ", match(r2, r2res));
+ 		}
+
+ 		r2 := -infinity;
+ 		os := enc_RealRestricted(r2);
+ 		if (os != '0141'O) {
+ 			setverdict(fail, "tc_float: ", match('0141'O, os));
+ 		}
+ 		r2res := dec_RealRestricted(os);
+ 		if (r2 != r2res) {
+ 			setverdict(fail, "tc_float: ", match(r2, r2res));
+ 		}
+
+ 		r2 := not_a_number;
+ 		os := enc_RealRestricted(r2);
+ 		if (os != '0142'O) {
+ 			setverdict(fail, "tc_float: ", match('0142'O, os));
+ 		}
+ 		r2res := dec_RealRestricted(os);
+ 		if (r2 != r2res) {
+ 			setverdict(fail, "tc_float: ", match(r2, r2res));
+ 		}
+
+ 		setverdict(pass);
+ 	}
+
+ 	external function enc_NullType(in NullType pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_NullType(in octetstring stream) return NullType
+     with { extension "prototype (convert) decode(OER)" }
+
+ 	testcase tc_null() runs on EmptyCT {
+ 		var NullType nullv, nullres;
+ 		var octetstring os;
+
+ 		nullv := NULL;
+ 		os := enc_NullType(nullv);
+ 		if (os != ''O) {
+ 			setverdict(fail, "tc_null: ", match(''O, os));
+ 		}
+ 		nullres := dec_NullType(os);
+ 		if (nullv != nullres) {
+ 			setverdict(fail, "tc_null: ", match(nullv, nullres));
+ 		}
+
+ 		setverdict(pass);
+ 	}
+
+ 	external function enc_IA5StringRestricted(in IA5StringRestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_IA5StringRestricted(in octetstring stream) return IA5StringRestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_ISO646StringRestricted(in ISO646StringRestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_ISO646StringRestricted(in octetstring stream) return ISO646StringRestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_VisibleStringRestricted(in VisibleStringRestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_VisibleStringRestricted(in octetstring stream) return VisibleStringRestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_NumericStringRestricted(in NumericStringRestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_NumericStringRestricted(in octetstring stream) return NumericStringRestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_PrintableStringRestricted(in PrintableStringRestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_PrintableStringRestricted(in octetstring stream) return PrintableStringRestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_IA5StringUnrestricted(in IA5StringUnrestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_IA5StringUnrestricted(in octetstring stream) return IA5StringUnrestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_ISO646StringUnrestricted(in ISO646StringUnrestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_ISO646StringUnrestricted(in octetstring stream) return ISO646StringUnrestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_VisibleStringUnrestricted(in VisibleStringUnrestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_VisibleStringUnrestricted(in octetstring stream) return VisibleStringUnrestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_NumericStringUnrestricted(in NumericStringUnrestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_NumericStringUnrestricted(in octetstring stream) return NumericStringUnrestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_PrintableStringUnrestricted(in PrintableStringUnrestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_PrintableStringUnrestricted(in octetstring stream) return PrintableStringUnrestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+ 	testcase tc_charstrings() runs on EmptyCT {
+ 		var IA5StringRestricted ia5, ia5res;
+ 		var octetstring os;
+
+ 		ia5 := "abcd";
+ 		os := enc_IA5StringRestricted(ia5);
+ 		if (os != '61626364'O) {
+ 			setverdict(fail, "tc_charstrings: ", match('61626364'O, os));
+ 		}
+ 		ia5res := dec_IA5StringRestricted(os);
+ 		if (ia5 != ia5res) {
+ 			setverdict(fail, "tc_charstrings: ", match(ia5, ia5res));
+ 		}
+
+ 		ia5 := ".:'%";
+ 		os := enc_IA5StringRestricted(ia5);
+ 		if (os != '2E3A2725'O) {
+ 			setverdict(fail, "tc_charstrings: ", match('2E3A2725'O, os));
+ 		}
+ 		ia5res := dec_IA5StringRestricted(os);
+ 		if (ia5 != ia5res) {
+ 			setverdict(fail, "tc_charstrings: ", match(ia5, ia5res));
+ 		}
+
+ 		var ISO646StringRestricted iso, isores;
+
+ 		iso := "abcd";
+ 		os := enc_ISO646StringRestricted(iso);
+ 		if (os != '61626364'O) {
+ 			setverdict(fail, "tc_charstrings: ", match('61626364'O, os));
+ 		}
+ 		isores := dec_ISO646StringRestricted(os);
+ 		if (iso != isores) {
+ 			setverdict(fail, "tc_charstrings: ", match(iso, isores));
+ 		}
+
+ 		iso := ".:'%";
+ 		os := enc_ISO646StringRestricted(iso);
+ 		if (os != '2E3A2725'O) {
+ 			setverdict(fail, "tc_charstrings: ", match('2E3A2725'O, os));
+ 		}
+ 		isores := dec_ISO646StringRestricted(os);
+ 		if (iso != isores) {
+ 			setverdict(fail, "tc_charstrings: ", match(iso, isores));
+ 		}
+
+ 		var VisibleStringRestricted vis, visres;
+
+ 		vis := "abcd";
+ 		os := enc_VisibleStringRestricted(vis);
+ 		if (os != '61626364'O) {
+ 			setverdict(fail, "tc_charstrings: ", match('61626364'O, os));
+ 		}
+ 		visres := dec_VisibleStringRestricted(os);
+ 		if (vis != visres) {
+ 			setverdict(fail, "tc_charstrings: ", match(vis, visres));
+ 		}
+
+ 		vis := ".:'%";
+ 		os := enc_VisibleStringRestricted(vis);
+ 		if (os != '2E3A2725'O) {
+ 			setverdict(fail, "tc_charstrings: ", match('2E3A2725'O, os));
+ 		}
+ 		visres := dec_VisibleStringRestricted(os);
+ 		if (vis != visres) {
+ 			setverdict(fail, "tc_charstrings: ", match(vis, visres));
+ 		}
+
+ 		var NumericStringRestricted num, numres;
+
+ 		num := "1234";
+ 		os := enc_NumericStringRestricted(num);
+ 		if (os != '31323334'O) {
+ 			setverdict(fail, "tc_charstrings: ", match('31323334'O, os));
+ 		}
+ 		numres := dec_NumericStringRestricted(os);
+ 		if (num != numres) {
+ 			setverdict(fail, "tc_charstrings: ", match(num, numres));
+ 		}
+
+ 		num := " 3 4";
+ 		os := enc_NumericStringRestricted(num);
+ 		if (os != '20332034'O) {
+ 			setverdict(fail, "tc_charstrings: ", match('20332034'O, os));
+ 		}
+ 		numres := dec_NumericStringRestricted(os);
+ 		if (num != numres) {
+ 			setverdict(fail, "tc_charstrings: ", match(num, numres));
+ 		}
+
+ 		var PrintableStringRestricted print, printres;
+
+ 		print := "abcd";
+ 		os := enc_PrintableStringRestricted(print);
+ 		if (os != '61626364'O) {
+ 			setverdict(fail, "tc_charstrings: ", match('61626364'O, os));
+ 		}
+ 		printres := dec_PrintableStringRestricted(os);
+ 		if (print != printres) {
+ 			setverdict(fail, "tc_charstrings: ", match(print, printres));
+ 		}
+
+ 		print := ".:'+";
+ 		os := enc_PrintableStringRestricted(print);
+ 		if (os != '2E3A272B'O) {
+ 			setverdict(fail, "tc_charstrings: ", match('2E3A272B'O, os));
+ 		}
+ 		printres := dec_PrintableStringRestricted(os);
+ 		if (print != printres) {
+ 			setverdict(fail, "tc_charstrings: ", match(print, printres));
+ 		}
+
+
+ 		// Unrestricted cases
+ 		var IA5StringUnrestricted ia52, ia52res;
+
+ 		ia52 := "abcd";
+ 		os := enc_IA5StringUnrestricted(ia52);
+ 		if (os != '0461626364'O) {
+ 			setverdict(fail, "tc_charstrings: ", match('0461626364'O, os));
+ 		}
+ 		ia52res := dec_IA5StringUnrestricted(os);
+ 		if (ia52 != ia52res) {
+ 			setverdict(fail, "tc_charstrings: ", match(ia52, ia52res));
+ 		}
+
+ 		ia52 := ".:'%";
+ 		os := enc_IA5StringUnrestricted(ia52);
+ 		if (os != '042E3A2725'O) {
+ 			setverdict(fail, "tc_charstrings: ", match('042E3A2725'O, os));
+ 		}
+ 		ia52res := dec_IA5StringUnrestricted(os);
+ 		if (ia5 != ia5res) {
+ 			setverdict(fail, "tc_charstrings: ", match(ia52, ia52res));
+ 		}
+
+ 		var ISO646StringUnrestricted iso2, iso2res;
+
+ 		iso2 := "abcd";
+ 		os := enc_ISO646StringUnrestricted(iso2);
+ 		if (os != '0461626364'O) {
+ 			setverdict(fail, "tc_charstrings: ", match('0461626364'O, os));
+ 		}
+ 		iso2res := dec_ISO646StringUnrestricted(os);
+ 		if (iso2 != iso2res) {
+ 			setverdict(fail, "tc_charstrings: ", match(iso2, iso2res));
+ 		}
+
+ 		iso2 := ".:'%";
+ 		os := enc_ISO646StringUnrestricted(iso2);
+ 		if (os != '042E3A2725'O) {
+ 			setverdict(fail, "tc_charstrings: ", match('042E3A2725'O, os));
+ 		}
+ 		iso2res := dec_ISO646StringUnrestricted(os);
+ 		if (iso2 != iso2res) {
+ 			setverdict(fail, "tc_charstrings: ", match(iso2, iso2res));
+ 		}
+
+ 		var VisibleStringUnrestricted vis2, vis2res;
+
+ 		vis2 := "abcd";
+ 		os := enc_VisibleStringUnrestricted(vis2);
+ 		if (os != '0461626364'O) {
+ 			setverdict(fail, "tc_charstrings: ", match('0461626364'O, os));
+ 		}
+ 		vis2res := dec_VisibleStringUnrestricted(os);
+ 		if (vis2 != vis2res) {
+ 			setverdict(fail, "tc_charstrings: ", match(vis2, vis2res));
+ 		}
+
+ 		vis2 := ".:'%";
+ 		os := enc_VisibleStringUnrestricted(vis2);
+ 		if (os != '042E3A2725'O) {
+ 			setverdict(fail, "tc_charstrings: ", match('042E3A2725'O, os));
+ 		}
+ 		vis2res := dec_VisibleStringUnrestricted(os);
+ 		if (vis2 != vis2res) {
+ 			setverdict(fail, "tc_charstrings: ", match(vis2, vis2res));
+ 		}
+
+ 		var NumericStringUnrestricted num2, num2res;
+
+ 		num2 := "1234";
+ 		os := enc_NumericStringUnrestricted(num2);
+ 		if (os != '0431323334'O) {
+ 			setverdict(fail, "tc_charstrings: ", match('0431323334'O, os));
+ 		}
+ 		num2res := dec_NumericStringUnrestricted(os);
+ 		if (num2 != num2res) {
+ 			setverdict(fail, "tc_charstrings: ", match(num2, num2res));
+ 		}
+
+ 		num2 := " 3 4";
+ 		os := enc_NumericStringUnrestricted(num2);
+ 		if (os != '0420332034'O) {
+ 			setverdict(fail, "tc_charstrings: ", match('0420332034'O, os));
+ 		}
+ 		num2res := dec_NumericStringUnrestricted(os);
+ 		if (num2 != num2res) {
+ 			setverdict(fail, "tc_charstrings: ", match(num2, num2res));
+ 		}
+
+ 		var PrintableStringUnrestricted print2, print2res;
+
+ 		print2 := "abcd";
+ 		os := enc_PrintableStringUnrestricted(print2);
+ 		if (os != '0461626364'O) {
+ 			setverdict(fail, "tc_charstrings: ", match('0461626364'O, os));
+ 		}
+ 		print2res := dec_PrintableStringUnrestricted(os);
+ 		if (print2 != print2res) {
+ 			setverdict(fail, "tc_charstrings: ", match(print2, print2res));
+ 		}
+
+ 		print2 := ".:'+";
+ 		os := enc_PrintableStringUnrestricted(print2);
+ 		if (os != '042E3A272B'O) {
+ 			setverdict(fail, "tc_charstrings: ", match('042E3A272B'O, os));
+ 		}
+ 		print2res := dec_PrintableStringUnrestricted(os);
+ 		if (print2 != print2res) {
+ 			setverdict(fail, "tc_charstrings: ", match(print2, print2res));
+ 		}
+
+ 		setverdict(pass);
+
+ 	}
+
+ 	external function enc_BMPStringRestricted(in BMPStringRestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_BMPStringRestricted(in octetstring stream) return BMPStringRestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_UniversalStringRestricted(in UniversalStringRestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_UniversalStringRestricted(in octetstring stream) return UniversalStringRestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_UTF8StringRestricted(in UTF8StringRestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_UTF8StringRestricted(in octetstring stream) return UTF8StringRestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_TeletexStringRestricted(in TeletexStringRestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_TeletexStringRestricted(in octetstring stream) return TeletexStringRestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_T61StringRestricted(in T61StringRestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_T61StringRestricted(in octetstring stream) return T61StringRestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_VideotexStringRestricted(in VideotexStringRestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_VideotexStringRestricted(in octetstring stream) return VideotexStringRestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_GraphicStringRestricted(in GraphicStringRestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_GraphicStringRestricted(in octetstring stream) return GraphicStringRestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_GeneralStringRestricted(in GeneralStringRestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_GeneralStringRestricted(in octetstring stream) return GeneralStringRestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_BMPStringUnrestricted(in BMPStringUnrestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_BMPStringUnrestricted(in octetstring stream) return BMPStringUnrestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_UniversalStringUnrestricted(in UniversalStringUnrestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_UniversalStringUnrestricted(in octetstring stream) return UniversalStringUnrestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_UTF8StringUnrestricted(in UTF8StringUnrestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_UTF8StringUnrestricted(in octetstring stream) return UTF8StringUnrestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_TeletexStringUnrestricted(in TeletexStringUnrestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_TeletexStringUnrestricted(in octetstring stream) return TeletexStringUnrestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_T61StringUnrestricted(in T61StringUnrestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_T61StringUnrestricted(in octetstring stream) return T61StringUnrestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_VideotexStringUnrestricted(in VideotexStringUnrestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_VideotexStringUnrestricted(in octetstring stream) return VideotexStringUnrestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_GraphicStringUnrestricted(in GraphicStringUnrestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_GraphicStringUnrestricted(in octetstring stream) return GraphicStringUnrestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_GeneralStringUnrestricted(in GeneralStringUnrestricted pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_GeneralStringUnrestricted(in octetstring stream) return GeneralStringUnrestricted
+     with { extension "prototype (convert) decode(OER)" }
+
+ 	testcase tc_universal_charstring() runs on EmptyCT {
+ 		var BMPStringRestricted bs, bsres;
+ 		var octetstring os;
+
+ 		bs := "abcd";
+ 		os := enc_BMPStringRestricted(bs);
+ 		if (os != '0061006200630064'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('0061006200630064'O, os));
+ 		}
+ 		bsres := dec_BMPStringRestricted(os);
+ 		if (bs != bsres) {
+ 			setverdict(fail, "tc_charstrings: ", match(bs, bsres));
+ 		}
+
+ 		bs := ".:'" & char(0,0,64,42);
+ 		os := enc_BMPStringRestricted(bs);
+ 		if (os != '002E003A0027402A'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('002E003A0027402A'O, os));
+ 		}
+ 		bsres := dec_BMPStringRestricted(os);
+ 		if (bs != bsres) {
+ 			setverdict(fail, "tc_charstrings: ", match(bs, bsres));
+ 		}
+
+ 		var UniversalStringRestricted us, usres;
+
+ 		us := "abcd";
+ 		os := enc_UniversalStringRestricted(us);
+ 		if (os != '00000061000000620000006300000064'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('00000061000000620000006300000064'O, os));
+ 		}
+ 		usres := dec_UniversalStringRestricted(os);
+ 		if (us != usres) {
+ 			setverdict(fail, "tc_charstrings: ", match(us, usres));
+ 		}
+
+ 		us := ".:'" & char(2,5,64,42);
+ 		os := enc_UniversalStringRestricted(us);
+ 		if (os != '0000002E0000003A000000270205402A'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('0000002E0000003A000000270205402A'O, os));
+ 		}
+ 		usres := dec_UniversalStringRestricted(os);
+ 		if (us != usres) {
+ 			setverdict(fail, "tc_charstrings: ", match(us, usres));
+ 		}
+
+ 		var UTF8StringRestricted uts, utsres;
+
+ 		uts := "abcd";
+ 		os := enc_UTF8StringRestricted(uts);
+ 		if (os != '0461626364'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('0461626364'O, os));
+ 		}
+ 		utsres := dec_UTF8StringRestricted(os);
+ 		if (uts != utsres) {
+ 			setverdict(fail, "tc_charstrings: ", match(uts, utsres));
+ 		}
+
+ 		uts := ".:'" & char(2,5,64,42);
+ 		os := enc_UTF8StringRestricted(uts);
+ 		if (os != '082E3A27FA819480AA'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('082E3A27FA819480AA'O, os));
+ 		}
+ 		utsres := dec_UTF8StringRestricted(os);
+ 		if (uts != utsres) {
+ 			setverdict(fail, "tc_charstrings: ", match(uts, utsres));
+ 		}
+
+ 		/*var TeletexStringRestricted ts, tsres;
+
+ 		ts := "ttxx";
+ 		os := enc_TeletexStringRestricted(ts);
+ 		if (os != '0461626364'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('0461626364'O, os));
+ 		}
+ 		tsres := dec_TeletexStringRestricted(os);
+ 		if (ts != tsres) {
+ 			setverdict(fail, "tc_charstrings: ", match(ts, tsres));
+ 		}
+
+ 		ts := ".:'" & char(2,5,64,42);
+ 		os := enc_TeletexStringRestricted(ts);
+ 		if (os != '082E3A27FA819480AA'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('082E3A27FA819480AA'O, os));
+ 		}
+ 		tsres := dec_TeletexStringRestricted(os);
+ 		if (ts != tsres) {
+ 			setverdict(fail, "tc_charstrings: ", match(ts, tsres));
+ 		}
+
+ 		var T61StringRestricted t61s, t61sres;
+
+ 		t61s := "ttxx";
+ 		os := enc_T61StringRestricted(t61s);
+ 		if (os != '0461626364'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('0461626364'O, os));
+ 		}
+ 		t61sres := dec_T61StringRestricted(os);
+ 		if (t61s != t61sres) {
+ 			setverdict(fail, "tc_charstrings: ", match(t61s, t61sres));
+ 		}
+
+ 		t61s := ".:'" & char(2,5,64,42);
+ 		os := enc_T61StringRestricted(t61s);
+ 		if (os != '082E3A27FA819480AA'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('082E3A27FA819480AA'O, os));
+ 		}
+ 		t61sres := dec_T61StringRestricted(os);
+ 		if (t61s != t61sres) {
+ 			setverdict(fail, "tc_charstrings: ", match(t61s, t61sres));
+ 		}
+
+ 		var VideotexStringRestricted vts, vtsres;
+
+ 		vts := "ttxx";
+ 		os := enc_VideotexStringRestricted(vts);
+ 		if (os != '0461626364'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('0461626364'O, os));
+ 		}
+ 		vtsres := dec_VideotexStringRestricted(os);
+ 		if (vts != vtsres) {
+ 			setverdict(fail, "tc_charstrings: ", match(vts, vtsres));
+ 		}
+
+ 		vts := ".:'" & char(2,5,64,42);
+ 		os := enc_VideotexStringRestricted(vts);
+ 		if (os != '082E3A27FA819480AA'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('082E3A27FA819480AA'O, os));
+ 		}
+ 		vtsres := dec_VideotexStringRestricted(os);
+ 		if (vts != vtsres) {
+ 			setverdict(fail, "tc_charstrings: ", match(vts, vtsres));
+ 		}
+
+ 		var GraphicStringRestricted gts, gtsres;
+
+ 		gts := "ttxx";
+ 		os := enc_GraphicStringRestricted(gts);
+ 		if (os != '0461626364'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('0461626364'O, os));
+ 		}
+ 		gtsres := dec_GraphicStringRestricted(os);
+ 		if (gts != gsres) {
+ 			setverdict(fail, "tc_charstrings: ", match(gts, gtsres));
+ 		}
+
+ 		gts := ".:'" & char(2,5,64,42);
+ 		os := enc_GraphicStringRestricted(gts);
+ 		if (os != '082E3A27FA819480AA'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('082E3A27FA819480AA'O, os));
+ 		}
+ 		gtsres := dec_GraphicStringRestricted(os);
+ 		if (gts != gtsres) {
+ 			setverdict(fail, "tc_charstrings: ", match(gts, gtsres));
+ 		}
+
+ 		var GeneralStringRestricted gets, getsres;
+
+ 		gets := "ttxx";
+ 		os := enc_GeneralStringRestricted(gets);
+ 		if (os != '0461626364'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('0461626364'O, os));
+ 		}
+ 		getsres := dec_GeneralStringRestricted(os);
+ 		if (gets != gesres) {
+ 			setverdict(fail, "tc_charstrings: ", match(gets, getsres));
+ 		}
+
+ 		gets := ".:'" & char(2,5,64,42);
+ 		os := enc_GeneralStringRestricted(gets);
+ 		if (os != '082E3A27FA819480AA'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('082E3A27FA819480AA'O, os));
+ 		}
+ 		getsres := dec_GeneralStringRestricted(os);
+ 		if (gets != getsres) {
+ 			setverdict(fail, "tc_charstrings: ", match(gets, getsres));
+ 		}*/
+
+
+ 		var BMPStringUnrestricted bs2, bs2res;
+
+ 		bs2 := "abcd";
+ 		os := enc_BMPStringUnrestricted(bs2);
+ 		if (os != '080061006200630064'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('080061006200630064'O, os));
+ 		}
+ 		bs2res := dec_BMPStringUnrestricted(os);
+ 		if (bs2 != bs2res) {
+ 			setverdict(fail, "tc_universal_charstring: ", match(bs2, bs2res));
+ 		}
+
+ 		bs2 := ".:'" & char(0,0,64,42);
+ 		os := enc_BMPStringUnrestricted(bs2);
+ 		if (os != '08002E003A0027402A'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('08002E003A0027402A'O, os));
+ 		}
+ 		bs2res := dec_BMPStringUnrestricted(os);
+ 		if (bs2 != bs2res) {
+ 			setverdict(fail, "tc_universal_charstring: ", match(bs2, bs2res));
+ 		}
+
+ 		var UniversalStringUnrestricted us2, us2res;
+
+ 		us2 := "abcd";
+ 		os := enc_UniversalStringUnrestricted(us2);
+ 		if (os != '1000000061000000620000006300000064'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('1000000061000000620000006300000064'O, os));
+ 		}
+ 		us2res := dec_UniversalStringUnrestricted(os);
+ 		if (us2 != us2res) {
+ 			setverdict(fail, "tc_universal_charstring: ", match(us2, us2res));
+ 		}
+
+ 		us2 := ".:'" & char(2,5,64,42);
+ 		os := enc_UniversalStringUnrestricted(us2);
+ 		if (os != '100000002E0000003A000000270205402A'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('100000002E0000003A000000270205402A'O, os));
+ 		}
+ 		us2res := dec_UniversalStringUnrestricted(os);
+ 		if (us2 != us2res) {
+ 			setverdict(fail, "tc_universal_charstring: ", match(us2, us2res));
+ 		}
+
+ 		var UTF8StringUnrestricted uts2, uts2res;
+
+ 		uts2 := "abcd";
+ 		os := enc_UTF8StringUnrestricted(uts2);
+ 		if (os != '0461626364'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('0461626364'O, os));
+ 		}
+ 		uts2res := dec_UTF8StringUnrestricted(os);
+ 		if (uts2 != uts2res) {
+ 			setverdict(fail, "tc_universal_charstring: ", match(uts2, uts2res));
+ 		}
+
+ 		uts2 := ".:'" & char(2,5,64,42);
+ 		os := enc_UTF8StringUnrestricted(uts2);
+ 		if (os != '082E3A27FA819480AA'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('082E3A27FA819480AA'O, os));
+ 		}
+ 		uts2res := dec_UTF8StringUnrestricted(os);
+ 		if (uts2 != uts2res) {
+ 			setverdict(fail, "tc_universal_charstring: ", match(uts2, uts2res));
+ 		}
+
+ 		var TeletexStringUnrestricted ts2, ts2res;
+
+ 		ts2 := "abcd";
+ 		os := enc_TeletexStringUnrestricted(ts2);
+ 		if (os != '0461626364'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('0461626364'O, os));
+ 		}
+ 		ts2res := dec_TeletexStringUnrestricted(os);
+ 		if (ts2 != ts2res) {
+ 			setverdict(fail, "tc_universal_charstring: ", match(ts2, ts2res));
+ 		}
+
+ 		ts2 := ".:'*";
+ 		os := enc_TeletexStringUnrestricted(ts2);
+ 		if (os != '042E3A272A'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('042E3A272A'O, os));
+ 		}
+ 		ts2res := dec_TeletexStringUnrestricted(os);
+ 		if (ts2 != ts2res) {
+ 			setverdict(fail, "tc_universal_charstring: ", match(ts2, ts2res));
+ 		}
+
+ 		var T61StringUnrestricted t61s2, t61s2res;
+
+ 		t61s2 := "abcd";
+ 		os := enc_T61StringUnrestricted(t61s2);
+ 		if (os != '0461626364'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('0461626364'O, os));
+ 		}
+ 		t61s2res := dec_T61StringUnrestricted(os);
+ 		if (t61s2 != t61s2res) {
+ 			setverdict(fail, "tc_universal_charstring: ", match(t61s2, t61s2res));
+ 		}
+
+ 		t61s2 := ".:'*";
+ 		os := enc_T61StringUnrestricted(t61s2);
+ 		if (os != '042E3A272A'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('042E3A272A'O, os));
+ 		}
+ 		t61s2res := dec_T61StringUnrestricted(os);
+ 		if (t61s2 != t61s2res) {
+ 			setverdict(fail, "tc_universal_charstring: ", match(t61s2, t61s2res));
+ 		}
+
+ 		var VideotexStringUnrestricted vts2, vts2res;
+
+ 		vts2 := "abcd";
+ 		os := enc_VideotexStringUnrestricted(vts2);
+ 		if (os != '0461626364'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('0461626364'O, os));
+ 		}
+ 		vts2res := dec_VideotexStringUnrestricted(os);
+ 		if (vts2 != vts2res) {
+ 			setverdict(fail, "tc_universal_charstring: ", match(vts2, vts2res));
+ 		}
+
+ 		vts2 := ".:'*";
+ 		os := enc_VideotexStringUnrestricted(vts2);
+ 		if (os != '042E3A272A'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('042E3A272A'O, os));
+ 		}
+ 		vts2res := dec_VideotexStringUnrestricted(os);
+ 		if (vts2 != vts2res) {
+ 			setverdict(fail, "tc_universal_charstring: ", match(vts2, vts2res));
+ 		}
+
+ 		var GraphicStringUnrestricted gts2, gts2res;
+
+ 		gts2 := "abcd";
+ 		os := enc_GraphicStringUnrestricted(gts2);
+ 		if (os != '0461626364'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('0461626364'O, os));
+ 		}
+ 		gts2res := dec_GraphicStringUnrestricted(os);
+ 		if (gts2 != gts2res) {
+ 			setverdict(fail, "tc_universal_charstring: ", match(gts2, gts2res));
+ 		}
+
+ 		gts2 := ".:'*";
+ 		os := enc_GraphicStringUnrestricted(gts2);
+ 		if (os != '042E3A272A'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('042E3A272A'O, os));
+ 		}
+ 		gts2res := dec_GraphicStringUnrestricted(os);
+ 		if (gts2 != gts2res) {
+ 			setverdict(fail, "tc_universal_charstring: ", match(gts2, gts2res));
+ 		}
+
+ 		var GeneralStringUnrestricted gets2, gets2res;
+
+ 		gets2 := "abcd";
+ 		os := enc_GeneralStringUnrestricted(gets2);
+ 		if (os != '0461626364'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('0461626364'O, os));
+ 		}
+ 		gets2res := dec_GeneralStringUnrestricted(os);
+ 		if (gets2 != gets2res) {
+ 			setverdict(fail, "tc_universal_charstring: ", match(gets2, gets2res));
+ 		}
+
+ 		gets2 := ".:'*";
+ 		os := enc_GeneralStringUnrestricted(gets2);
+ 		if (os != '042E3A272A'O) {
+ 			setverdict(fail, "tc_universal_charstring: ", match('042E3A272A'O, os));
+ 		}
+ 		gets2res := dec_GeneralStringUnrestricted(os);
+ 		if (gets2 != gets2res) {
+ 			setverdict(fail, "tc_universal_charstring: ", match(gets2, gets2res));
+ 		}
+
+
+ 		setverdict(pass);
+
+ 	}
+
+ 	external function enc_OBJID(in OBJID pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_OBJID(in octetstring stream) return OBJID
+     with { extension "prototype (convert) decode(OER)" }
+
+     external function enc_ROBJID(in ROBJID pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_ROBJID(in octetstring stream) return ROBJID
+     with { extension "prototype (convert) decode(OER)" }
+
+ 	testcase tc_objid() runs on EmptyCT {
+ 		var OBJID oid, oidres;
+ 		var octetstring os;
+
+ 		oid := objid{1 2 3 4 5 6};
+ 		os := enc_OBJID(oid);
+ 		if (os != '052A03040506'O) {
+ 			setverdict(fail, "tc_objid: ", match('052A03040506'O, os));
+ 		}
+ 		oidres := dec_OBJID(os);
+ 		if (oid != oidres) {
+ 			setverdict(fail, "tc_charstrings: ", match(oid, oidres));
+ 		}
+
+ 		oid := objid{1 35 994 431 5 1};
+ 		os := enc_OBJID(oid);
+ 		if (os != '074B8762832F0501'O) {
+ 			setverdict(fail, "tc_objid: ", match('074B8762832F0501'O, os));
+ 		}
+ 		oidres := dec_OBJID(os);
+ 		if (oid != oidres) {
+ 			setverdict(fail, "tc_charstrings: ", match(oid, oidres));
+ 		}
+
+ 		var ROBJID roid, roidres;
+
+ 		roid := myROBJID;
+ 		os := enc_ROBJID(roid);
+ 		if (os != '06010203040506'O) {
+ 			setverdict(fail, "tc_objid: ", match('06010203040506'O, os));
+ 		}
+ 		roidres := dec_ROBJID(os);
+ 		if (roid != roidres) {
+ 			setverdict(fail, "tc_charstrings: ", match(roid, roidres));
+ 		}
+
+ 		roid := myROBJID2;
+ 		os := enc_ROBJID(roid);
+ 		if (os != '0801238762832F0501'O) {
+ 			setverdict(fail, "tc_objid: ", match('0801238762832F0501'O, os));
+ 		}
+ 		roidres := dec_ROBJID(os);
+ 		if (roid != roidres) {
+ 			setverdict(fail, "tc_charstrings: ", match(roid, roidres));
+ 		}
+
+ 		setverdict(pass);
+ 	}
+
+ 	external function enc_MyPDV(in MyPDV pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_MyPDV(in octetstring stream) return MyPDV
+     with { extension "prototype (convert) decode(OER)" }
+
+ 	testcase tc_pdv() runs on EmptyCT {
+ 		var MyPDV pdv, pdvres;
+ 		var octetstring os;
+
+ 		pdv := {
+ 			identification := {
+ 				syntaxes := {
+ 					abstract := objid{1 2 3},
+ 					transfer := objid{1 5 6}
+ 				}
+ 			},
+ 			data_value := '12345678'O
+ 		};
+ 		os := enc_MyPDV(pdv);
+ 		if (os != '80022A03022D060412345678'O) {
+ 			setverdict(fail, "tc_pdv: ", match('80022A03022D060412345678'O, os));
+ 		}
+ 		pdvres := dec_MyPDV(os);
+ 		if (pdv != pdvres) {
+ 			setverdict(fail, "tc_pdv: ", match(pdv, pdvres));
+ 		}
+
+ 		pdv := {
+ 			identification := {
+ 				syntax := objid{1 2 3}
+ 			},
+ 			data_value := '12345678'O
+ 		};
+ 		os := enc_MyPDV(pdv);
+ 		if (os != '81022A030412345678'O) {
+ 			setverdict(fail, "tc_pdv: ", match('81022A030412345678'O, os));
+ 		}
+ 		pdvres := dec_MyPDV(os);
+ 		if (pdv != pdvres) {
+ 			setverdict(fail, "tc_pdv: ", match(pdv, pdvres));
+ 		}
+
+ 		pdv := {
+ 			identification := {
+ 				presentation_context_id := 414
+ 			},
+ 			data_value := '12345678'O
+ 		};
+ 		os := enc_MyPDV(pdv);
+ 		if (os != '8202019E0412345678'O) {
+ 			setverdict(fail, "tc_pdv: ", match('8202019E0412345678'O, os));
+ 		}
+ 		pdvres := dec_MyPDV(os);
+ 		if (pdv != pdvres) {
+ 			setverdict(fail, "tc_pdv: ", match(pdv, pdvres));
+ 		}
+
+ 		pdv := {
+ 			identification := {
+ 				context_negotiation := {
+ 					presentation_context_id := 414,
+ 					transfer_syntax := objid{1 2 3}
+ 				}
+ 			},
+ 			data_value := '12345678'O
+ 		};
+ 		os := enc_MyPDV(pdv);
+ 		if (os != '8302019E022A030412345678'O) {
+ 			setverdict(fail, "tc_pdv: ", match('8302019E022A030412345678'O, os));
+ 		}
+ 		pdvres := dec_MyPDV(os);
+ 		if (pdv != pdvres) {
+ 			setverdict(fail, "tc_pdv: ", match(pdv, pdvres));
+ 		}
+
+ 		pdv := {
+ 			identification := {
+ 				transfer_syntax := objid{1 2 3}
+ 			},
+ 			data_value := '12345678'O
+ 		};
+ 		os := enc_MyPDV(pdv);
+ 		if (os != '84022A030412345678'O) {
+ 			setverdict(fail, "tc_pdv: ", match('84022A030412345678'O, os));
+ 		}
+ 		pdvres := dec_MyPDV(os);
+ 		if (pdv != pdvres) {
+ 			setverdict(fail, "tc_pdv: ", match(pdv, pdvres));
+ 		}
+
+ 		pdv := {
+ 			identification := {
+ 				fixed := NULL
+ 			},
+ 			data_value := '12345678'O
+ 		};
+ 		os := enc_MyPDV(pdv);
+ 		if (os != '850412345678'O) {
+ 			setverdict(fail, "tc_pdv: ", match('850412345678'O, os));
+ 		}
+ 		pdvres := dec_MyPDV(os);
+ 		if (pdv != pdvres) {
+ 			setverdict(fail, "tc_pdv: ", match(pdv, pdvres));
+ 		}
+
+ 		setverdict(pass);
+ 	}
+
+ 	external function enc_Union(in Union pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_Union(in octetstring stream) return Union
+     with { extension "prototype (convert) decode(OER)" }
+
+ 	testcase tc_union() runs on EmptyCT {
+ 		var Union u, ures;
+ 		var octetstring os;
+
+ 		u := {
+ 			f1 := 1
+ 		}
+ 		os := enc_Union(u);
+ 		if (os != '7F400101'O) {
+ 			setverdict(fail, "tc_union: ", match('7F400101'O, os));
+ 		}
+ 		ures := dec_Union(os);
+ 		if (u != ures) {
+ 			setverdict(fail, "tc_union: ", match(u, ures));
+ 		}
+
+ 		u := {
+ 			f2 := 1
+ 		}
+ 		os := enc_Union(u);
+ 		if (os != '7F3F0101'O) {
+ 			setverdict(fail, "tc_union: ", match('7F3F0101'O, os));
+ 		}
+ 		ures := dec_Union(os);
+ 		if (u != ures) {
+ 			setverdict(fail, "tc_union: ", match(u, ures));
+ 		}
+
+ 		u := {
+ 			f3 := 1
+ 		}
+ 		os := enc_Union(u);
+ 		if (os != '7E0101'O) {
+ 			setverdict(fail, "tc_union: ", match('7E0101'O, os));
+ 		}
+ 		ures := dec_Union(os);
+ 		if (u != ures) {
+ 			setverdict(fail, "tc_union: ", match(u, ures));
+ 		}
+
+ 		u := {
+ 			f4 := 1
+ 		}
+ 		os := enc_Union(u);
+ 		if (os != '7FFF7F0101'O) {
+ 			setverdict(fail, "tc_union: ", match('7FFF7F0101'O, os));
+ 		}
+ 		ures := dec_Union(os);
+ 		if (u != ures) {
+ 			setverdict(fail, "tc_union: ", match(u, ures));
+ 		}
+
+ 		u := {
+ 			f5 := 1
+ 		}
+ 		os := enc_Union(u);
+ 		if (os != '020101'O) {
+ 			setverdict(fail, "tc_union: ", match('020101'O, os));
+ 		}
+ 		ures := dec_Union(os);
+ 		if (u != ures) {
+ 			setverdict(fail, "tc_union: ", match(u, ures));
+ 		}
+
+ 		u := {
+ 			f6 := 1
+ 		}
+ 		os := enc_Union(u);
+ 		if (os != 'FF82450101'O) {
+ 			setverdict(fail, "tc_union: ", match('FF82450101'O, os));
+ 		}
+ 		ures := dec_Union(os);
+ 		if (u != ures) {
+ 			setverdict(fail, "tc_union: ", match(u, ures));
+ 		}
+
+ 		u := {
+ 			f7 := 1
+ 		}
+ 		os := enc_Union(u);
+ 		if (os != 'FFBB2C0101'O) {
+ 			setverdict(fail, "tc_union: ", match('FFBB2C0101'O, os));
+ 		}
+ 		ures := dec_Union(os);
+ 		if (u != ures) {
+ 			setverdict(fail, "tc_union: ", match(u, ures));
+ 		}
+
+ 		u := {
+ 			f8 := 1
+ 		}
+ 		os := enc_Union(u);
+ 		if (os != 'D20101'O) {
+ 			setverdict(fail, "tc_union: ", match('D20101'O, os));
+ 		}
+ 		ures := dec_Union(os);
+ 		if (u != ures) {
+ 			setverdict(fail, "tc_union: ", match(u, ures));
+ 		}
+
+ 		u := {
+ 			f9 := 1
+ 		}
+ 		os := enc_Union(u);
+ 		if (os != 'C301'O) {
+ 			setverdict(fail, "tc_union: ", match('C301'O, os));
+ 		}
+ 		ures := dec_Union(os);
+ 		if (u != ures) {
+ 			setverdict(fail, "tc_union: ", match(u, ures));
+ 		}
+
+ 		setverdict(pass);
+ 	}
+
+	external function enc_EmptyRecord(in EmptyRecord pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_EmptyRecord(in octetstring stream) return EmptyRecord
+     with { extension "prototype (convert) decode(OER)" }
+
+ 	external function enc_ExtensionRecord(in ExtensionRecord pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_ExtensionRecord(in octetstring stream) return ExtensionRecord
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_NoOptionalRecord(in NoOptionalRecord pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_NoOptionalRecord(in octetstring stream) return NoOptionalRecord
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_OptionalRecord(in OptionalRecord pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_OptionalRecord(in octetstring stream) return OptionalRecord
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_SomeOptionalRecord(in SomeOptionalRecord pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_SomeOptionalRecord(in octetstring stream) return SomeOptionalRecord
+     with { extension "prototype (convert) decode(OER)" }
+
+ 	testcase tc_sequence() runs on EmptyCT {
+ 		var octetstring os;
+
+ 		var EmptyRecord emr, emrres;
+ 		emr := {  }
+ 		os := enc_EmptyRecord(emr);
+ 		if (os != ''O) {
+ 			setverdict(fail, "tc_sequence: ", match(''O, os));
+ 		}
+ 		emrres := dec_EmptyRecord(os);
+ 		if (emr != emrres) {
+ 			setverdict(fail, "tc_sequence: ", match(emr, emrres));
+ 		}
+
+ 		// Test extension bit presence, FAILS, possibly some bug with is_extendable() function
+ 		/*var ExtensionRecord er, erres;
+ 		er := { me := e2 }
+ 		os := enc_ExtensionRecord(er);
+ 		if (os != '0001'O) {
+ 			setverdict(fail, "tc_sequence: ", match('0001'O, os));
+ 		}
+ 		erres := dec_ExtensionRecord(os);
+ 		if (er != erres) {
+ 			setverdict(fail, "tc_sequence: ", match(er, erres));
+ 		}*/
+
+ 		var NoOptionalRecord nr, nrres;
+
+ 		nr := {
+ 			ub := 4536366262,
+			u1b := 111,
+			u1b2 := 66,
+			s1b := -85,
+			s1b2 := -21,
+			u2b := 32596,
+			s2b := -17639,
+			u4b := 56464631,
+			s4b := -1331326,
+			u8b := 4946464979873,
+			s8b := -4164613213,
+			me := ebig,
+			bsr := '10101111'B,
+			bsr2 := '101111101'B,
+			bsr3 := '010'B,
+			bsu := '10101110101010110'B,
+			osr := 'ABCD1234'O,
+			osu := '131314676886BDBADA'O,
+			ru := 42343242.4352,
+			rr := 4321431.511,
+			nullt := NULL,
+			iasr := "sags",
+			isor := "gdgg",
+			vsr := "aanb",
+			nsr := "1697",
+			psr := "abfd",
+			ias := "gdsgdsgdsgdhhfgjhfd",
+			iso := "454325f46gssf",
+			vs := "gdfhgdshgdshgdr7u",
+			ns := "697365463",
+			ps := "435346gf",
+			/*bmpr := char(0,0,54,63) & "abf",
+			usr := char(0,0,54,63) & "abf",
+			utfr := char(0,0,54,63) & "abf",
+			tsr := char(0,0,54,63) & "abf",
+			t61sr := char(0,0,54,63) & "abf",
+			visr := char(0,0,54,63) & "abf",
+			gsr := char(0,0,54,63) & "abf",
+			gesr := char(0,0,54,63) & "abf",*/
+			bmpu := char(0,0,54,63) & "abf",
+			usu := char(0,0,54,63) & "abfsdfa" ,
+			uftu := char(0,0,54,63) & "abfsdfa",
+			tsu :=  "abfsdfa" ,
+			t61u :=  "abfsdfa" ,
+			vsu :=  "abfsdfa" ,
+			gsu :=  "abfsdfa" ,
+			gesu := "abfsdfa"
+			//ob := objid{1 16 63 1 6 76},
+			//rob := myROBJID
+ 		}
+ 		os := enc_NoOptionalRecord(nr);
+ 		if (os != '05010E6374B66F42ABEB7F54BB19035D94F7FFEBAF820000047FB049BBA1FFFFFFFF07C50BA38407D3CDE9AFBE80400407AEAB00ABCD123409131314676886BDBADA11033432333433323432343335322E452D340F03343332313433313531312E452D33736167736764676761616E623136393761626664136764736764736764736764686866676A6866640D343534333235663436677373661167646668676473686764736867647237750936393733363534363308343335333436676608363F006100620066200000363F000000610000006200000066000000730000006400000066000000610AE398BF6162667364666107616266736466610761626673646661076162667364666107616266736466610761626673646661'O) {
+ 			setverdict(fail, "tc_sequence: ", match('05010E6374B66F42ABEB7F54BB19035D94F7FFEBAF820000047FB049BBA1FFFFFFFF07C50BA38407D3CDE9AFBE80400407AEAB00ABCD123409131314676886BDBADA11033432333433323432343335322E452D340F03343332313433313531312E452D33736167736764676761616E623136393761626664136764736764736764736764686866676A6866640D343534333235663436677373661167646668676473686764736867647237750936393733363534363308343335333436676608363F006100620066200000363F000000610000006200000066000000730000006400000066000000610AE398BF6162667364666107616266736466610761626673646661076162667364666107616266736466610761626673646661'O, os));
+ 		}
+ 		nrres := dec_NoOptionalRecord(os);
+ 		if (nr != nrres) {
+ 			setverdict(fail, "tc_sequence: ", match(nr, nrres));
+ 		}
+
+
+ 		var OptionalRecord onr, onrres;
+
+ 		onr := {
+ 			ub := 4536366262,
+			u1b := omit,
+			u1b2 := 66,
+			s1b := -85,
+			s1b2 := -21,
+			u2b := 32596,
+			s2b := -17639,
+			u4b := 56464631,
+			s4b := -1331326,
+			u8b := 4946464979873,
+			s8b := -4164613213,
+			me := ebig,
+			bsr := '10101111'B,
+			bsr2 := '101111101'B,
+			bsr3 := '010'B,
+			bsu := '10101110101010110'B,
+			osr := 'ABCD1234'O,
+			osu := '131314676886BDBADA'O,
+			ru := 42343242.4352,
+			rr := 4321431.511,
+			nullt := NULL,
+			iasr := "sags",
+			isor := "gdgg",
+			vsr := "aanb",
+			nsr := "1697",
+			psr := "abfd",
+			ias := "gdsgdsgdsgdhhfgjhfd",
+			iso := "454325f46gssf",
+			vs := "gdfhgdshgdshgdr7u",
+			ns := "697365463",
+			ps := "435346gf",
+			/*bmpr := char(0,0,54,63) & "abf",
+			usr := char(0,0,54,63) & "abf",
+			utfr := char(0,0,54,63) & "abf",
+			tsr := char(0,0,54,63) & "abf",
+			t61sr := char(0,0,54,63) & "abf",
+			visr := char(0,0,54,63) & "abf",
+			gsr := char(0,0,54,63) & "abf",
+			gesr := char(0,0,54,63) & "abf",*/
+			bmpu := char(0,0,54,63) & "abf",
+			usu := char(0,0,54,63) & "abfsdfa" ,
+			uftu := char(0,0,54,63) & "abfsdfa",
+			tsu :=  "abfsdfa" ,
+			t61u :=  "abfsdfa" ,
+			vsu :=  "abfsdfa" ,
+			gsu :=  "abfsdfa" ,
+			gesu := "abfsdfa"
+			//ob := objid{1 16 63 1 6 76},
+			//rob := myROBJID
+ 		}
+ 		os := enc_OptionalRecord(onr);
+ 		if (os != 'BFFFFFFFFE05010E6374B642ABEB7F54BB19035D94F7FFEBAF820000047FB049BBA1FFFFFFFF07C50BA38407D3CDE9AFBE80400407AEAB00ABCD123409131314676886BDBADA11033432333433323432343335322E452D340F03343332313433313531312E452D33736167736764676761616E623136393761626664136764736764736764736764686866676A6866640D343534333235663436677373661167646668676473686764736867647237750936393733363534363308343335333436676608363F006100620066200000363F000000610000006200000066000000730000006400000066000000610AE398BF6162667364666107616266736466610761626673646661076162667364666107616266736466610761626673646661'O) {
+ 			setverdict(fail, "tc_sequence: ", match('BFFFFFFFFE05010E6374B642ABEB7F54BB19035D94F7FFEBAF820000047FB049BBA1FFFFFFFF07C50BA38407D3CDE9AFBE80400407AEAB00ABCD123409131314676886BDBADA11033432333433323432343335322E452D340F03343332313433313531312E452D33736167736764676761616E623136393761626664136764736764736764736764686866676A6866640D343534333235663436677373661167646668676473686764736867647237750936393733363534363308343335333436676608363F006100620066200000363F000000610000006200000066000000730000006400000066000000610AE398BF6162667364666107616266736466610761626673646661076162667364666107616266736466610761626673646661'O, os));
+ 		}
+ 		onrres := dec_OptionalRecord(os);
+ 		if (onr != onrres) {
+ 			setverdict(fail, "tc_sequence: ", match(onr, onrres));
+ 		}
+
+ 		onr := {
+ 			ub := 4536366262,
+			u1b := omit,
+			u1b2 := 66,
+			s1b := -85,
+			s1b2 := -21,
+			u2b := 32596,
+			s2b := -17639,
+			u4b := 56464631,
+			s4b := -1331326,
+			u8b := 4946464979873,
+			s8b := -4164613213,
+			me := esmall,
+			bsr := omit,
+			bsr2 := '101111101'B,
+			bsr3 := '010'B,
+			bsu := '10101110101010110'B,
+			osr := 'ABCD1234'O,
+			osu := '131314676886BDBADA'O,
+			ru := 42343242.4352,
+			rr := 4321431.511,
+			nullt := NULL,
+			iasr := "sags",
+			isor := omit,
+			vsr := "aanb",
+			nsr := "1697",
+			psr := "abfd",
+			ias := "gdsgdsgdsgdhhfgjhfd",
+			iso := omit,
+			vs := omit,
+			ns := omit,
+			ps := "435346gf",
+			/*bmpr := char(0,0,54,63) & "abf",
+			usr := char(0,0,54,63) & "abf",
+			utfr := char(0,0,54,63) & "abf",
+			tsr := char(0,0,54,63) & "abf",
+			t61sr := char(0,0,54,63) & "abf",
+			visr := char(0,0,54,63) & "abf",
+			gsr := char(0,0,54,63) & "abf",
+			gesr := char(0,0,54,63) & "abf",*/
+			bmpu := char(0,0,54,63) & "abf",
+			usu := char(0,0,54,63) & "abfsdfa" ,
+			uftu := omit,
+			tsu :=  "abfsdfa" ,
+			t61u :=  "abfsdfa" ,
+			vsu :=  "abfsdfa" ,
+			gsu :=  "abfsdfa" ,
+			gesu := "abfsdfa"
+			//ob := objid{1 16 63 1 6 76},
+			//rob := myROBJID
+ 		}
+ 		os := enc_OptionalRecord(onr);
+ 		if (os != 'BFF7FDE3BE05010E6374B642ABEB7F54BB19035D94F7FFEBAF820000047FB049BBA1FFFFFFFF07C50BA384FEB8D1B4BE80400407AEAB00ABCD123409131314676886BDBADA11033432333433323432343335322E452D340F03343332313433313531312E452D337361677361616E623136393761626664136764736764736764736764686866676A68666408343335333436676608363F006100620066200000363F0000006100000062000000660000007300000064000000660000006107616266736466610761626673646661076162667364666107616266736466610761626673646661'O) {
+ 			setverdict(fail, "tc_sequence: ", match('BFF7FDE3BE05010E6374B642ABEB7F54BB19035D94F7FFEBAF820000047FB049BBA1FFFFFFFF07C50BA384FEB8D1B4BE80400407AEAB00ABCD123409131314676886BDBADA11033432333433323432343335322E452D340F03343332313433313531312E452D337361677361616E623136393761626664136764736764736764736764686866676A68666408343335333436676608363F006100620066200000363F0000006100000062000000660000007300000064000000660000006107616266736466610761626673646661076162667364666107616266736466610761626673646661'O, os));
+ 		}
+ 		onrres := dec_OptionalRecord(os);
+ 		if (onr != onrres) {
+ 			setverdict(fail, "tc_sequence: ", match(onr, onrres));
+ 		}
+
+
+ 		onr := {
+ 			ub := omit,
+			u1b := omit,
+			u1b2 := omit,
+			s1b := omit,
+			s1b2 := omit,
+			u2b := omit,
+			s2b := omit,
+			u4b := omit,
+			s4b := omit,
+			u8b := omit,
+			s8b := omit,
+			me := omit,
+			bsr := omit,
+			bsr2 := omit,
+			bsr3 := omit,
+			bsu := omit,
+			osr := omit,
+			osu := omit,
+			ru := omit,
+			rr := omit,
+			nullt := omit,
+			iasr := omit,
+			isor := omit,
+			vsr := omit,
+			nsr := omit,
+			psr := omit,
+			ias := omit,
+			iso := omit,
+			vs := omit,
+			ns := omit,
+			ps := omit,
+			/*bmpr := char(0,0,54,63) & "abf",
+			usr := char(0,0,54,63) & "abf",
+			utfr := char(0,0,54,63) & "abf",
+			tsr := char(0,0,54,63) & "abf",
+			t61sr := char(0,0,54,63) & "abf",
+			visr := char(0,0,54,63) & "abf",
+			gsr := char(0,0,54,63) & "abf",
+			gesr := char(0,0,54,63) & "abf",*/
+			bmpu := omit,
+			usu := omit,
+			uftu := omit,
+			tsu :=  omit,
+			t61u :=  omit,
+			vsu :=  omit,
+			gsu :=  omit,
+			gesu := omit
+			//ob := objid{1 16 63 1 6 76},
+			//rob := myROBJID
+ 		}
+ 		os := enc_OptionalRecord(onr);
+ 		if (os != '0000000000'O) {
+ 			setverdict(fail, "tc_sequence: ", match('0000000000'O, os));
+ 		}
+ 		onrres := dec_OptionalRecord(os);
+ 		if (onr != onrres) {
+ 			setverdict(fail, "tc_sequence: ", match(onr, onrres));
+ 		}
+
+ 		var SomeOptionalRecord sor, sorres;
+ 		sor := {
+ 			f0 := 0,
+ 			f1 := 1,
+ 			f2 := 2,
+ 			f3 := 3,
+ 			f4 := 4,
+ 			f5 := 5,
+ 			f6 := 6,
+ 			f7 := 7,
+ 			f8 := 8,
+ 			f9 := 9
+ 		}
+ 		os := enc_SomeOptionalRecord(sor);
+ 		if (os != 'FC0100010101020103010401050106010701080109'O) {
+ 			setverdict(fail, "tc_sequence: ", match('FC0100010101020103010401050106010701080109'O, os));
+ 		}
+ 		sorres := dec_SomeOptionalRecord(os);
+ 		if (sor != sorres) {
+ 			setverdict(fail, "tc_sequence: ", match(sor, sorres));
+ 		}
+
+ 		sor := {
+ 			f0 := 0,
+ 			f1 := 1,
+ 			f2 := 2,
+ 			f3 := 3,
+ 			f4 := omit,
+ 			f5 := omit,
+ 			f6 := 6,
+ 			f7 := 7,
+ 			f8 := 8,
+ 			f9 := 9
+ 		}
+ 		os := enc_SomeOptionalRecord(sor);
+ 		if (os != 'CC01000101010201030106010701080109'O) {
+ 			setverdict(fail, "tc_sequence: ", match('CC01000101010201030106010701080109'O, os));
+ 		}
+ 		sorres := dec_SomeOptionalRecord(os);
+ 		if (sor != sorres) {
+ 			setverdict(fail, "tc_sequence: ", match(sor, sorres));
+ 		}
+
+ 		sor := {
+ 			f0 := 0,
+ 			f1 := 1,
+ 			f2 := omit,
+ 			f3 := 3,
+ 			f4 := omit,
+ 			f5 := omit,
+ 			f6 := 6,
+ 			f7 := omit,
+ 			f8 := 8,
+ 			f9 := 9
+ 		}
+ 		os := enc_SomeOptionalRecord(sor);
+ 		if (os != '84010001010103010601080109'O) {
+ 			setverdict(fail, "tc_sequence: ", match('84010001010103010601080109'O, os));
+ 		}
+ 		sorres := dec_SomeOptionalRecord(os);
+ 		if (sor != sorres) {
+ 			setverdict(fail, "tc_sequence: ", match(sor, sorres));
+ 		}
+
+
+ 		setverdict(pass);
+ 	}
+
+ 	external function enc_MySet(in MySet pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_MySet(in octetstring stream) return MySet
+     with { extension "prototype (convert) decode(OER)" }
+
+ 	testcase tc_set() runs on EmptyCT {
+ 		var MySet ms, msres;
+ 		var octetstring os;
+
+ 		ms := {
+ 			r1 := 3.14,
+ 			f1 := 1,
+ 			f2 := 2,
+ 			f3 := 3,
+ 			f4 := 4, 
+ 			f5 := 5,
+ 			f6 := 6
+ 		}
+ 		os := enc_MySet(ms);
+ 		if (os != '800102010401030106010508033331342E452D320101'O) {
+ 			setverdict(fail, "tc_set: ", match('800102010401030106010508033331342E452D320101'O, os));
+ 		}
+ 		msres := dec_MySet(os);
+ 		if (ms != msres) {
+ 			setverdict(fail, "tc_set: ", match(ms, msres));
+ 		}
+
+ 		setverdict(pass);
+ 	}
+
+ 	external function enc_MyRecordOf(in MyRecordOf pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_MyRecordOf(in octetstring stream) return MyRecordOf
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_MySetOf(in MySetOf pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_MySetOf(in octetstring stream) return MySetOf
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_ROI(in ROI pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_ROI(in octetstring stream) return ROI
+     with { extension "prototype (convert) decode(OER)" }
+
+ 	testcase  tc_recordof() runs on EmptyCT {
+ 		var MyRecordOf ro, rores;
+ 		var octetstring os;
+
+ 		ro := {
+ 			{
+ 				f0 := 0,
+	 			f1 := 1,
+	 			f2 := 2,
+	 			f3 := 3,
+	 			f4 := omit,
+	 			f5 := omit,
+	 			f6 := 6,
+	 			f7 := 7,
+	 			f8 := 8,
+	 			f9 := 9
+	 		},
+	 		{
+	 			f0 := 0,
+	 			f1 := 1,
+	 			f2 := 2,
+	 			f3 := 3,
+	 			f4 := omit,
+	 			f5 := omit,
+	 			f6 := 6,
+	 			f7 := 7,
+	 			f8 := 8,
+	 			f9 := 9
+	 		}
+ 		}
+ 		os := enc_MyRecordOf(ro);
+ 		if (os != '0102CC01000101010201030106010701080109CC01000101010201030106010701080109'O) {
+ 			setverdict(fail, "tc_recordof: ", match('0102CC01000101010201030106010701080109CC01000101010201030106010701080109'O, os));
+ 		}
+ 		rores := dec_MyRecordOf(os);
+ 		if (ro != rores) {
+ 			setverdict(fail, "tc_recordof: ", match(ro, rores));
+ 		}
+
+ 		var MySetOf so, sores;
+
+ 		so := {
+ 			{
+	 			r1 := 3.14,
+	 			f1 := 1,
+	 			f2 := 2,
+	 			f3 := 3,
+	 			f4 := 4, 
+	 			f5 := 5,
+	 			f6 := 6
+	 		},
+	 		{
+	 			r1 := 3.14,
+	 			f1 := 1,
+	 			f2 := 2,
+	 			f3 := 3,
+	 			f4 := 4, 
+	 			f5 := 5,
+	 			f6 := 6
+	 		}
+ 		}
+ 		os := enc_MySetOf(so);
+ 		if (os != '0102800102010401030106010508033331342E452D320101800102010401030106010508033331342E452D320101'O) {
+ 			setverdict(fail, "tc_recordof: ", match('0102800102010401030106010508033331342E452D320101800102010401030106010508033331342E452D320101'O, os));
+ 		}
+ 		sores := dec_MySetOf(os);
+ 		if (so != sores) {
+ 			setverdict(fail, "tc_recordof: ", match(so, sores));
+ 		}
+
+ 		var ROI roi, roires;
+
+ 		roi := {1,2,3,4}
+ 		os := enc_ROI(roi);
+ 		if (os != '010401020304'O) {
+ 			setverdict(fail, "tc_recordof: ", match('010401020304'O, os));
+ 		}
+ 		roires := dec_ROI(os);
+ 		if (roi != roires) {
+ 			setverdict(fail, "tc_recordof: ", match(roi, roires));
+ 		}
+
+ 		os := '010401020304'O;
+ 		roires := dec_ROI(os);
+ 		if (roi != roires) {
+ 			setverdict(fail, "tc_recordof: ", match(roi, roires));
+ 		}
+
+ 		setverdict(pass);
+ 	}
+
+ 	external function enc_MyExternal(in MyExternal pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_MyExternal(in octetstring stream) return MyExternal
+     with { extension "prototype (convert) decode(OER)" }
+
+ 	testcase tc_external() runs on EmptyCT {
+ 		var MyExternal ex, exres;
+ 		var octetstring os;
+
+ 		ex := {
+ 			identification := {
+ 				syntax := objid{1 2 3}
+ 			},
+ 			data_value_descriptor := omit,
+ 			data_value := '12345678'O
+ 		};
+ 		os := enc_MyExternal(ex);
+ 		if (os != '80022A03810412345678'O) {
+ 			setverdict(fail, "tc_external: ", match('80022A03810412345678'O, os));
+ 		}
+ 		exres := dec_MyExternal(os);
+ 		if (ex != exres) {
+ 			setverdict(fail, "tc_external: ", match(ex, exres));
+ 		}
+
+ 		ex := {
+ 			identification := {
+ 				presentation_context_id := 7934
+ 			},
+ 			data_value_descriptor := "something",
+ 			data_value := '12345678'O
+ 		};
+ 		os := enc_MyExternal(ex);
+ 		if (os != '60021EFE09736F6D657468696E67810412345678'O) {
+ 			setverdict(fail, "tc_external: ", match('60021EFE09736F6D657468696E67810412345678'O, os));
+ 		}
+ 		exres := dec_MyExternal(os);
+ 		if (ex != exres) {
+ 			setverdict(fail, "tc_external: ", match(ex, exres));
+ 		}
+
+ 		ex := {
+ 			identification := {
+ 				context_negotiation := {
+ 					presentation_context_id := 414,
+ 					transfer_syntax := objid{1 2 3}
+ 				}
+ 			},
+ 			data_value_descriptor := "something",
+ 			data_value := '12345678'O
+ 		};
+ 		os := enc_MyExternal(ex);
+ 		if (os != 'E0022A0302019E09736F6D657468696E67810412345678'O) {
+ 			setverdict(fail, "tc_external: ", match('E0022A0302019E09736F6D657468696E67810412345678'O, os));
+ 		}
+ 		exres := dec_MyExternal(os);
+ 		if (ex != exres) {
+ 			setverdict(fail, "tc_external: ", match(ex, exres));
+ 		}
+
+
+
+ 		setverdict(pass);
+ 	}
+
+ 	external function enc_Item(in Item pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_Item(in octetstring stream) return Item
+     with { extension "prototype (convert) decode(OER)" }
+
+ 	testcase tc_opentype() runs on EmptyCT {
+ 		var Item pf, pfres;
+ 		var octetstring os;
+
+ 		pf := {
+ 			otherFeature := {subItem := {itemCode := 109, otherFeature := {Weight := "54" }} },
+ 			itemCode := 104,
+ 			itemDescription := "Bookshelf",
+ 			feature := {Weight := "24"},
+ 			isTaxable := false
+ 		};
+ 		os := enc_Item(pf);
+ 		if (os != '080000006D030235340000006809426F6F6B7368656C660302323400'O) {
+ 			setverdict(fail, "tc_opentype: ", match('080000006D030235340000006809426F6F6B7368656C660302323400'O, os));
+ 		}
+ 		pfres := dec_Item(os);
+ 		if (pf != pfres) {
+ 			setverdict(fail, "tc_opentype: ", match(pf, pfres));
+ 		}
+
+ 		setverdict(pass);
+ 	}
+
+ 	external function enc_PersonnelRecord(in PersonnelRecord pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_PersonnelRecord(in octetstring stream) return PersonnelRecord
+     with { extension "prototype (convert) decode(OER)" }
+
+ 	testcase tc_example() runs on EmptyCT {
+ 		var PersonnelRecord prres;
+ 		var octetstring os;
+
+ 		os := enc_PersonnelRecord(johny);
+ 		if (os != '80044A6F686E015005536D6974680133084469726563746F72083139373130393137044D617279015405536D69746801020552616C7068015405536D69746808313935373131313105537573616E0142054A6F6E6573083139353930373137'O) {
+ 			setverdict(fail, "tc_example: ", match('80044A6F686E015005536D6974680133084469726563746F72083139373130393137044D617279015405536D69746801020552616C7068015405536D69746808313935373131313105537573616E0142054A6F6E6573083139353930373137'O, os));
+ 		}
+ 		prres := dec_PersonnelRecord(os);
+ 		if (johny != prres) {
+ 			setverdict(fail, "tc_example: ", match(johny, prres));
+ 		}
 
 
  		setverdict(pass);
@@ -748,5 +2804,21 @@
  	control {
  		execute(tc_boolean());
  		execute(tc_integer());
+ 		execute(tc_enumerated());
+ 		execute(tc_bitstring());
+ 		execute(tc_octetstring());
+ 		execute(tc_float());
+ 		execute(tc_null());
+ 		execute(tc_charstrings());
+ 		execute(tc_universal_charstring());
+ 		execute(tc_objid());
+ 		execute(tc_sequence());
+ 		execute(tc_pdv());
+ 		execute(tc_union());
+ 		execute(tc_set());
+ 		execute(tc_recordof());
+ 		execute(tc_external());
+ 		execute(tc_opentype());
+ 		execute(tc_example());
  	}
  }
\ No newline at end of file
diff --git a/regression_test/OER/Types.asn b/regression_test/OER/Types.asn
index 1100ad6e1733421f4fdfeb37a5236f0e8788eae3..21b63c4ce87ef9e0e4666c3bcb09b054294ccb37 100644
--- a/regression_test/OER/Types.asn
+++ b/regression_test/OER/Types.asn
@@ -10,13 +10,12 @@
 --
 --/////////////////////////////////////////////////////////////////////////////
 Types
-DEFINITIONS
+DEFINITIONS 
 
 AUTOMATIC TAGS
-
+EXTENSIBILITY IMPLIED
 ::=
-
-BEGIN
+ BEGIN
 
 IMPORTS ; -- nothing
 
@@ -44,4 +43,332 @@ Unsigned8byteInt ::= INTEGER (0..18446744073709551615)
 
 Signed8byteInt ::= INTEGER (-9223372036854775808..9223372036854775807)
 
+MyEnum ::= ENUMERATED 
+{
+  e0      (0),
+  e1      (1),
+  e2      (2),
+  ebig    (131321321),
+  esmall  (-21442124)
+}
+
+BitstringRestricted ::= BIT STRING (SIZE(8))
+
+BitstringRestricted2 ::= BIT STRING (SIZE(9))
+
+BitstringRestricted3 ::= BIT STRING (SIZE(3))
+
+BitstringUnrestricted ::= BIT STRING
+
+OctetstringRestricted ::= OCTET STRING (SIZE(4))
+
+OctetstringUnrestricted ::= OCTET STRING
+
+RealUnrestricted ::= REAL
+
+RealRestricted ::= REAL (0 | WITH COMPONENTS { mantissa (-99999..99999), base (1), exponent (-20..20)})
+
+NullType ::= NULL
+
+IA5StringRestricted ::= IA5String (SIZE(4))
+
+ISO646StringRestricted ::= ISO646String (SIZE(4))
+
+VisibleStringRestricted ::= VisibleString (SIZE(4))
+
+NumericStringRestricted ::= NumericString (SIZE(4))
+
+PrintableStringRestricted ::= PrintableString (SIZE(4))
+
+IA5StringUnrestricted ::= IA5String
+
+ISO646StringUnrestricted ::= ISO646String
+
+VisibleStringUnrestricted ::= VisibleString
+
+NumericStringUnrestricted ::= NumericString
+
+PrintableStringUnrestricted ::= PrintableString
+
+BMPStringRestricted ::= BMPString (SIZE(4))
+
+UniversalStringRestricted ::= UniversalString (SIZE(4))
+
+UTF8StringRestricted ::= UTF8String (SIZE(4))
+
+TeletexStringRestricted ::= TeletexString (SIZE(4))
+
+T61StringRestricted ::= T61String (SIZE(4))
+
+VideotexStringRestricted ::= VideotexString (SIZE(4))
+
+GraphicStringRestricted ::= GraphicString (SIZE(4))
+
+GeneralStringRestricted ::= GeneralString (SIZE(4))
+
+BMPStringUnrestricted ::= BMPString
+
+UniversalStringUnrestricted ::= UniversalString
+
+UTF8StringUnrestricted ::= UTF8String
+
+TeletexStringUnrestricted ::= TeletexString
+
+T61StringUnrestricted ::= T61String
+
+VideotexStringUnrestricted ::= VideotexString
+
+GraphicStringUnrestricted ::= GraphicString
+
+GeneralStringUnrestricted ::= GeneralString
+
+OBJID ::= OBJECT IDENTIFIER
+
+ROBJID ::= RELATIVE-OID
+
+myROBJID ROBJID ::= {1 2 3 4 5 6}
+
+myROBJID2 ROBJID ::= {1 35 994 431 5 1}
+
+--MyInt2 ::= INTEGER ( REAL(1.0..3.0) UNION PrintableString("abc") UNION INTEGER(1..10) )
+
+NoOptionalRecord ::= SEQUENCE {
+	ub UnLimitedInt,
+	u1b Unsigned1byteInt,
+	u1b2 Unsigned1byteInt2,
+	s1b Signed1byteInt,
+	s1b2 Signed1byteInt2,
+	u2b Unsigned2byteInt,
+	s2b Signed2byteInt,
+	u4b Unsigned4byteInt,
+	s4b Signed4byteInt,
+	u8b Unsigned8byteInt,
+	s8b Signed8byteInt,
+	me MyEnum,
+	bsr BitstringRestricted,
+	bsr2 BitstringRestricted2,
+	bsr3 BitstringRestricted3,
+	bsu BitstringUnrestricted,
+	osr OctetstringRestricted,
+	osu OctetstringUnrestricted,
+	ru RealUnrestricted,
+	rr RealRestricted,
+	nullt NullType,
+	iasr IA5StringRestricted,
+	isor ISO646StringRestricted,
+	vsr VisibleStringRestricted,
+	nsr NumericStringRestricted,
+	psr PrintableStringRestricted,
+	ias IA5StringUnrestricted,
+	iso ISO646StringUnrestricted,
+	vs VisibleStringUnrestricted,
+	ns NumericStringUnrestricted,
+	ps PrintableStringUnrestricted,
+	--bmpr BMPStringRestricted,
+	--usr UniversalStringRestricted,
+	--utfr UTF8StringRestricted,
+	--tsr TeletexStringRestricted,
+	--t61sr T61StringRestricted,
+	--visr VideotexStringRestricted,
+	--gsr GraphicStringRestricted,
+	--gesr GeneralStringRestricted,
+	bmpu BMPStringUnrestricted,
+	usu UniversalStringUnrestricted,
+	uftu UTF8StringUnrestricted,
+	tsu TeletexStringUnrestricted,
+	t61u T61StringUnrestricted,
+	vsu VideotexStringUnrestricted,
+	gsu GraphicStringUnrestricted,
+	gesu GeneralStringUnrestricted
+	--ob OBJID,
+	--rob ROBJID
+}
+
+
+OptionalRecord ::= SEQUENCE {
+	ub UnLimitedInt OPTIONAL,
+	u1b Unsigned1byteInt OPTIONAL,
+	u1b2 Unsigned1byteInt2 OPTIONAL,
+	s1b Signed1byteInt OPTIONAL,
+	s1b2 Signed1byteInt2 OPTIONAL,
+	u2b Unsigned2byteInt OPTIONAL,
+	s2b Signed2byteInt OPTIONAL,
+	u4b Unsigned4byteInt OPTIONAL,
+	s4b Signed4byteInt OPTIONAL,
+	u8b Unsigned8byteInt OPTIONAL,
+	s8b Signed8byteInt OPTIONAL,
+	me MyEnum OPTIONAL,
+	bsr BitstringRestricted OPTIONAL,
+	bsr2 BitstringRestricted2 OPTIONAL,
+	bsr3 BitstringRestricted3 OPTIONAL,
+	bsu BitstringUnrestricted OPTIONAL,
+	osr OctetstringRestricted OPTIONAL,
+	osu OctetstringUnrestricted OPTIONAL,
+	ru RealUnrestricted OPTIONAL,
+	rr RealRestricted OPTIONAL,
+	nullt NullType OPTIONAL,
+	iasr IA5StringRestricted OPTIONAL,
+	isor ISO646StringRestricted OPTIONAL,
+	vsr VisibleStringRestricted OPTIONAL,
+	nsr NumericStringRestricted OPTIONAL,
+	psr PrintableStringRestricted OPTIONAL,
+	ias IA5StringUnrestricted OPTIONAL,
+	iso ISO646StringUnrestricted OPTIONAL,
+	vs VisibleStringUnrestricted OPTIONAL,
+	ns NumericStringUnrestricted OPTIONAL,
+	ps PrintableStringUnrestricted OPTIONAL,
+	--bmpr BMPStringRestricted,
+	--usr UniversalStringRestricted,
+	--utfr UTF8StringRestricted,
+	--tsr TeletexStringRestricted,
+	--t61sr T61StringRestricted,
+	--visr VideotexStringRestricted,
+	--gsr GraphicStringRestricted,
+	--gesr GeneralStringRestricted,
+	bmpu BMPStringUnrestricted OPTIONAL,
+	usu UniversalStringUnrestricted OPTIONAL,
+	uftu UTF8StringUnrestricted OPTIONAL,
+	tsu TeletexStringUnrestricted OPTIONAL,
+	t61u T61StringUnrestricted OPTIONAL,
+	vsu VideotexStringUnrestricted OPTIONAL,
+	gsu GraphicStringUnrestricted OPTIONAL,
+	gesu GeneralStringUnrestricted OPTIONAL
+	--ob OBJID,
+	--rob ROBJID
+}
+
+ExtensionRecord ::= SEQUENCE {
+	me MyEnum,
+	...,
+	f INTEGER
+}
+
+EmptyRecord ::= SEQUENCE {
+
+}
+
+SomeOptionalRecord ::= SEQUENCE {
+	f0 INTEGER DEFAULT 5,
+	f1 INTEGER,
+	f2 INTEGER OPTIONAL,
+	f3 INTEGER,
+	f4 INTEGER OPTIONAL,
+	f5 INTEGER OPTIONAL,
+	f6 INTEGER,
+	f7 INTEGER OPTIONAL,
+	f8 INTEGER,
+	f9 INTEGER DEFAULT 2
+}
+
+MyPDV ::= EMBEDDED PDV
+
+Union ::= CHOICE {
+	f1 [APPLICATION 64] INTEGER,
+	f2 [APPLICATION 63] INTEGER,
+	f3 [APPLICATION 62] INTEGER,
+	f4 [APPLICATION 16383] INTEGER,
+	f5 INTEGER,
+	f6 [PRIVATE 325] INTEGER,
+	f7 [PRIVATE 7596] INTEGER,
+	f8 [PRIVATE 18] INTEGER,
+	f9 [PRIVATE 3] Unsigned1byteInt
+}
+
+MySet ::= SET {
+	r1 [PRIVATE 2] [PRIVATE 7] REAL,
+	f1 [PRIVATE 4] INTEGER,
+	f2 INTEGER OPTIONAL,
+	f3 [APPLICATION 234] INTEGER,
+	f4 [APPLICATION 2] INTEGER,
+	f5 [3] INTEGER,
+	f6 [1] INTEGER
+}
+
+MyRecordOf ::= SEQUENCE OF SomeOptionalRecord
+
+MySetOf ::= SET OF MySet
+
+ROI ::= SEQUENCE OF Unsigned1byteInt
+
+MyExternal ::= EXTERNAL
+
+
+SUBPRODUCT ::= CLASS {
+&code	       INTEGER (1..99999) UNIQUE,
+&OtherFeature
+} WITH SYNTAX { CODE &code, OTHERFEATURE &OtherFeature}
+
+
+SubProductCatalog SUBPRODUCT ::= {
+{CODE 109, OTHERFEATURE Weight}
+}
+
+SubItem ::= SEQUENCE {
+	itemCode       	SUBPRODUCT.&code ({SubProductCatalog }),
+	otherFeature    SUBPRODUCT.&OtherFeature ({SubProductCatalog}{@itemCode})
+}
+
+PRODUCT ::= CLASS {
+&OtherFeature,
+&code	       INTEGER (1..99999) UNIQUE,
+&description	VisibleString (SIZE (1..100)),
+--OpenType-- &Feature	    
+} WITH SYNTAX { OTHERFEATURE &OtherFeature, CODE &code , DESCRIPTION &description , FEATURE &Feature }
+
+ProductCatalog PRODUCT ::= {
+{OTHERFEATURE SubItem, CODE 104, DESCRIPTION "Bookshelf",  FEATURE Weight}
+}
+
+Generation ::= ENUMERATED {two-G, three-G, four-G}
+Weight ::= IA5String
+
+Item ::= SEQUENCE {
+otherFeature    PRODUCT.&OtherFeature ({ProductCatalog}{@itemCode}),
+itemCode       	PRODUCT.&code ({ProductCatalog }),
+itemDescription	PRODUCT.&description({ProductCatalog}{@itemCode}),
+feature        	PRODUCT.&Feature ({ProductCatalog}{@itemCode}),
+isTaxable	      BOOLEAN
+}
+
+
+PersonnelRecord ::= [APPLICATION 0] IMPLICIT SET {
+	name Name,
+	title [0] VisibleString,
+	number EmployeeNumber,
+	dateOfHire [1] Date,
+	nameOfSpouse [2] Name,
+	children [3] IMPLICIT
+	SEQUENCE OF ChildInformation DEFAULT {}
+
+}
+
+ChildInformation ::= SET
+{ 
+	name Name,
+	dateOfBirth [0] Date
+}
+
+Name ::= [APPLICATION 1] IMPLICIT SEQUENCE
+{
+	givenName VisibleString,
+	initial VisibleString,
+	familyName VisibleString
+}
+
+EmployeeNumber ::= [APPLICATION 2] IMPLICIT INTEGER
+
+Date ::= [APPLICATION 3] IMPLICIT VisibleString -- YYYYMMDD
+
+johny PersonnelRecord ::= { name {givenName "John", initial "P", familyName "Smith"},
+title "Director",
+number 51,
+dateOfHire "19710917",
+nameOfSpouse {givenName "Mary", initial "T", familyName "Smith"},
+children
+{{name {givenName "Ralph", initial "T", familyName "Smith"},
+dateOfBirth "19571111"},
+{name {givenName "Susan", initial "B", familyName "Jones"},
+dateOfBirth "19590717"}}}
+
+
 END
\ No newline at end of file