diff --git a/compiler2/Type_chk.cc b/compiler2/Type_chk.cc
index 55317df02b737c13b2059e51ed03ca7c8fe52638..fc74f72ead7824ffbeb8a6c5412c52ed6fb3fb03 100644
--- a/compiler2/Type_chk.cc
+++ b/compiler2/Type_chk.cc
@@ -3098,10 +3098,92 @@ void Type::chk_oer() {
         }
       }
       break; }
+    case T_CHOICE_A:
+      oerattrib->extendable = t->u.secho.ctss->has_ellipsis();
+      if (oerattrib->extendable) {
+        oerattrib->nr_of_root_comps = t->u.secho.ctss->get_nof_root_comps();
+      }
+      break;
+    case T_SET_A: {
+      oerattrib->extendable = t->u.secho.ctss->has_ellipsis();
+      if (oerattrib->extendable) {
+        oerattrib->nr_of_root_comps = t->u.secho.ctss->get_nof_root_comps();
+      }
+      // TITAN will reorder the fields for DER coding, which is mostly fine.
+      // Until the extensions... In OER the DER ordering is good, but the extended
+      // fields do not need the reordering.
+      // Here a "map" called p is created which contains the good indexes of the fields.
+      size_t nElements = t->get_nof_comps();
+      vector<CompField> se_comps;
+      map<Tag, CompField> se_comps_map;
+      for(size_t i=0; i<nElements; i++) {
+        CompField* cf=t->get_comp_byIndex(i);
+        Tag *tag = cf->get_type()->get_smallest_tag();
+        se_comps_map.add(*tag, cf);
+        delete tag;
+      }
+      for(size_t i=0; i<nElements; i++)
+        se_comps.add(se_comps_map.get_nth_elem(i));
+      se_comps_map.clear();
+      
+      size_t limit = oerattrib->extendable ? oerattrib->nr_of_root_comps : nElements;
+      vector<CompField> se_comps2;
+      for(size_t i=0; i<limit; i++) {
+        CompField* cf=t->get_comp_byIndex(i);
+        Tag *tag = cf->get_type()->get_smallest_tag();
+        se_comps_map.add(*tag, cf);
+        delete tag;
+      }
+      for(size_t i=0; i<limit; i++)
+        se_comps2.add(se_comps_map.get_nth_elem(i));
+      se_comps_map.clear();
+      for(size_t i=limit; i<nElements; i++)
+        se_comps2.add(t->get_comp_byIndex(i));
+      
+      for (size_t i = 0; i < nElements; i++) {
+        const Identifier& id = se_comps[i]->get_name();
+        for (size_t j = 0; j < nElements; j++) {
+          if (id == se_comps2[j]->get_name()) {
+            oerattrib->p.add(new int(j));
+            break;
+          }
+        }
+      }
+      se_comps.clear();
+      se_comps2.clear();
+    }
     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();
+      oerattrib->extendable = t->u.secho.ctss->has_ellipsis();
+      if (oerattrib->extendable) {
+        oerattrib->nr_of_root_comps = t->u.secho.ctss->get_nof_root_comps();
+        ExtAdds* eas = t->u.secho.ctss->get_ext_and_exc()->get_eas();
+        int last_idx = 0;
+        for (size_t i = 0; i < eas->get_nof_comps(); i++) {
+          int idx = eas->get_group_byIndex(i);
+          if (last_idx != 0 && last_idx == idx) {
+            // do nothing, the field is part of the group
+          } else if (last_idx != 0 && idx == 0) {
+            // the group is ended
+            oerattrib->ext_attr_groups.add(new int(i));
+            last_idx = 0;
+          } else if (last_idx != 0 && idx != 0) {
+            // The group is ended, but new one comes immediately
+            last_idx = idx;
+            oerattrib->ext_attr_groups.add(new int(i));
+            oerattrib->ext_attr_groups.add(new int(i));
+          } else if (last_idx == 0 && idx != 0) {
+            // new group
+            last_idx = idx;
+            oerattrib->ext_attr_groups.add(new int(i));
+          }
+        }
+        if (last_idx != 0) {
+          oerattrib->ext_attr_groups.add(new int(eas->get_nof_comps()));
+        }
+      }
+      if (t->typetype != T_SET_A) {
+        for (size_t i = 0; i < t->get_nof_comps(); i++) 
+          oerattrib->p.add(new int(i));
       }
       break; }
     case T_SEQOF:
diff --git a/compiler2/Type_codegen.cc b/compiler2/Type_codegen.cc
index 37f5d021569a1c0a865556e08bd36efd650482bd..d4d2e4bd6aafd5935b00033c6f895a5e3006767d 100644
--- a/compiler2/Type_codegen.cc
+++ b/compiler2/Type_codegen.cc
@@ -1087,16 +1087,47 @@ 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, -1, FALSE };\n"
+      "const TTCN_OERdescriptor_t %s_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };\n"
       , get_genname_own().c_str());
   } else {
+     target->source.global_vars = mputprintf(target->source.global_vars,
+      "const int %s_oer_ext_arr_[%lu] = {"
+      , get_genname_own().c_str()
+      , oerattrib->ext_attr_groups.size());
+    for (size_t i = 0; i < oerattrib->ext_attr_groups.size(); i++) {
+      target->source.global_vars = mputprintf(target->source.global_vars,
+        "%i", *oerattrib->ext_attr_groups[i]);
+      if (i != oerattrib->ext_attr_groups.size() - 1) {
+        target->source.global_vars = mputstr(target->source.global_vars, ", ");
+      }
+    }
+     target->source.global_vars = mputstr(target->source.global_vars, "};\n");
+     target->source.global_vars = mputprintf(target->source.global_vars,
+      "const int %s_oer_p_[%lu] = {"
+      , get_genname_own().c_str()
+      , oerattrib->p.size());
+    for (size_t i = 0; i < oerattrib->p.size(); i++) {
+      target->source.global_vars = mputprintf(target->source.global_vars,
+        "%i", *oerattrib->p[i]);
+      if (i != oerattrib->p.size() - 1) {
+        target->source.global_vars = mputstr(target->source.global_vars, ", ");
+      }
+    }
+     target->source.global_vars = mputstr(target->source.global_vars, "};\n");
     target->source.global_vars = mputprintf(target->source.global_vars,
-      "const TTCN_OERdescriptor_t %s_oer_ = { %i, %s, %i, %s };\n"
+      "const TTCN_OERdescriptor_t %s_oer_ = { %i, %s, %i, %s, %i, %lu, %s_oer_ext_arr_, %lu, %s_oer_p_"
       , get_genname_own().c_str() 
       , oerattrib->bytes
       , oerattrib->signed_ ? "TRUE" : "FALSE"
       , oerattrib->length
-      , oerattrib->extendable ? "TRUE" : "FALSE");
+      , oerattrib->extendable ? "TRUE" : "FALSE"
+      , oerattrib->nr_of_root_comps
+      , oerattrib->ext_attr_groups.size()
+      , get_genname_own().c_str()
+      , oerattrib->p.size()
+      , get_genname_own().c_str());
+    
+    target->source.global_vars = mputstr(target->source.global_vars, "};\n");
   }
   
 }
@@ -1219,6 +1250,10 @@ void Type::generate_code_Choice(output_struct *target)
     get_gen_coder_functions(CT_XER);
   sdef.hasJson = get_gen_coder_functions(CT_JSON);
   sdef.hasOer = get_gen_coder_functions(CT_OER);
+  if (oerattrib) {
+    sdef.oerExtendable = oerattrib->extendable;
+    sdef.oerNrOrRootcomps = oerattrib->nr_of_root_comps;
+  }
   sdef.has_opentypes = get_has_opentypes();
   sdef.opentype_outermost = get_is_opentype_outermost();
   sdef.ot = generate_code_ot(pool);
@@ -1632,6 +1667,20 @@ void Type::generate_code_Se(output_struct *target)
     get_gen_coder_functions(CT_XER);
   sdef.hasJson = get_gen_coder_functions(CT_JSON);
   sdef.hasOer = get_gen_coder_functions(CT_OER);
+  if (oerattrib) {
+    sdef.oerExtendable = oerattrib->extendable;
+    sdef.oerNrOrRootcomps = oerattrib->nr_of_root_comps;
+    sdef.oerEagNum = oerattrib->ext_attr_groups.size();
+    sdef.oerEag = (int*)Malloc(sdef.oerEagNum*sizeof(int));
+    for (int i = 0; i < sdef.oerEagNum; i++) {
+      sdef.oerEag[i] = *(oerattrib->ext_attr_groups[i]);
+    }
+    sdef.oerPNum = oerattrib->p.size();
+    sdef.oerP = (int*)Malloc(sdef.oerPNum*sizeof(int));
+    for (int i = 0; i < sdef.oerPNum; i++) {
+      sdef.oerP[i] = *(oerattrib->p[i]);
+    }
+  }
   if (xerattrib){
     Module *my_module = get_my_scope()->get_scope_mod();
     sdef.xerHasNamespaces = my_module->get_nof_ns() != 0;
@@ -2046,6 +2095,12 @@ void Type::generate_code_Se(output_struct *target)
     }
   }
   Free(sdef.elements);
+  if (sdef.oerEag) {
+    Free(sdef.oerEag);
+  }
+  if (sdef.oerP) {
+    Free(sdef.oerP);
+  }
 }
 
 bool Type::is_untagged() const { return xerattrib && xerattrib->untagged_; }
diff --git a/compiler2/Typestuff.cc b/compiler2/Typestuff.cc
index ff5b661b5f7b2d90b64a27e1559201dad1cb55c7..64fb0b98af1f0262756125b105c816f1bbbcf321 100644
--- a/compiler2/Typestuff.cc
+++ b/compiler2/Typestuff.cc
@@ -709,6 +709,19 @@ namespace Common {
       get_fullname().c_str(), (unsigned long) n);
     return 0;
   }
+  
+  int ExtAdds::get_group_byIndex(size_t n) const
+  {
+    size_t offset = n;
+    for(size_t i = 0; i < eas.size(); i++) {
+      size_t size = eas[i]->get_nof_comps();
+      if (offset < size) return eas[i]->get_group_number();
+      else offset -= size;
+    }
+    FATAL_ERROR("%s: Requested index %lu does not exist.", \
+      get_fullname().c_str(), (unsigned long) n);
+    return 0;
+  }
 
   bool ExtAdds::has_comp_withName(const Identifier& p_name) const
   {
@@ -737,6 +750,10 @@ namespace Common {
   {
     if(!p_ea)
       FATAL_ERROR("NULL parameter: Asn::ExtAdds::add_ea()");
+    if (p_ea->is_ext_attr_group()) {
+      num_of_groups++;
+      p_ea->set_group_number(num_of_groups);
+    }
     eas.add(p_ea);
   }
 
diff --git a/compiler2/Typestuff.hh b/compiler2/Typestuff.hh
index c7ee40fdb79b40f954b601f5025299309e38f163..2ede5e412667b80e93f83332459d9eda375b2200 100644
--- a/compiler2/Typestuff.hh
+++ b/compiler2/Typestuff.hh
@@ -130,6 +130,7 @@ namespace Common {
     bool has_comp_withName(const Identifier& p_name);
     CompField* get_comp_byName(const Identifier& p_name);
     void tr_compsof(ReferenceChain *refch, bool in_ellipsis);
+    ExtAndExc* get_ext_and_exc() const { return ee; }
     bool has_ellipsis() const { return ee != 0; }
     bool needs_auto_tags();
     void add_auto_tags();
@@ -160,6 +161,9 @@ namespace Common {
     virtual bool has_comp_withName(const Identifier& p_name) const = 0;
     virtual CompField* get_comp_byName(const Identifier& p_name) const = 0;
     virtual void tr_compsof(ReferenceChain *refch, bool is_set) = 0;
+    virtual bool is_ext_attr_group() const { return false; }
+    virtual int get_group_number() const { return 0; }
+    virtual void set_group_number(int) {}
   };
 
   /**
@@ -168,18 +172,21 @@ namespace Common {
   class ExtAdds : public Node {
   private:
     vector<ExtAdd> eas;
+    // The number of ExtAddGrps
+    int num_of_groups;
     /** Copy constructor not implemented */
     ExtAdds(const ExtAdds& p);
     /** Assignment disabled */
     ExtAdds& operator=(const ExtAdds& p);
   public:
-    ExtAdds() : Node(), eas() { }
+    ExtAdds() : Node(), eas(), num_of_groups(0) { }
     virtual ~ExtAdds();
     virtual ExtAdds *clone() const;
     virtual void set_fullname(const string& p_fullname);
     virtual void set_my_scope(Scope *p_scope);
     size_t get_nof_comps() const;
     CompField* get_comp_byIndex(size_t n) const;
+    int get_group_byIndex(size_t n) const;
     bool has_comp_withName(const Identifier& p_name) const;
     CompField* get_comp_byName(const Identifier& p_name) const;
     void tr_compsof(ReferenceChain *refch, bool is_set);
@@ -215,6 +222,7 @@ namespace Common {
     void tr_compsof(ReferenceChain *refch, bool is_set)
       { eas->tr_compsof(refch, is_set); }
     void set_eas(ExtAdds *p_eas);
+    ExtAdds * get_eas() const { return eas; }
     virtual void dump(unsigned level) const;
   };
 
@@ -226,6 +234,8 @@ namespace Common {
     /** can be NULL if not present */
     Value *versionnumber;
     CTs *cts;
+    // Needed for oer coding
+    int groupnumber;
     /** Copy constructor not implemented */
     ExtAddGrp(const ExtAddGrp& p);
     /** Assignment disabled */
@@ -242,6 +252,10 @@ namespace Common {
     virtual CompField* get_comp_byName(const Identifier& p_name) const;
     virtual void tr_compsof(ReferenceChain *refch, bool is_set);
     virtual void dump(unsigned level) const;
+    virtual bool is_ext_attr_group() const { return true; }
+    virtual int get_group_number() const { return groupnumber; }
+    virtual void set_group_number(int num) { groupnumber = num; }
+
   };
 
   /**
diff --git a/compiler2/datatypes.h b/compiler2/datatypes.h
index 7cce1d644f7440a5c47baf0077a55bd25cfff0bb..f85fd171c07bba4a59328a41df50d405fe9019a6 100644
--- a/compiler2/datatypes.h
+++ b/compiler2/datatypes.h
@@ -104,6 +104,12 @@ typedef struct {
   boolean hasXer;
   boolean hasJson;
   boolean hasOer;
+  boolean oerExtendable;
+  int oerNrOrRootcomps;
+  int oerEagNum;
+  int* oerEag;
+  int oerPNum;
+  int* oerP;
   boolean xerUntagged;
   boolean xerUntaggedOne; /**< from Type::u.secho.has_single_charenc */
   boolean xerUseNilPossible; /* for sequence */
diff --git a/compiler2/record.c b/compiler2/record.c
index b016a22d68834cb9f7959038022cf7413d9cef30..53333fec1080e96375f94ac8f02431b29d1fa92f 100644
--- a/compiler2/record.c
+++ b/compiler2/record.c
@@ -4655,56 +4655,193 @@ void defRecordClass1(const struct_def *sdef, output_struct *output)
   if (oer_needed) {
     // OER encode, RT1
     src = mputprintf(src,
-      "int %s::OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf) const\n"
+      "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 %s value.\");\n"
       "  return -1;\n"
       "  }\n", name, sdef->kind == SET ? "set" : "record");
+
+    if (sdef->oerExtendable && sdef->oerNrOrRootcomps != sdef->nElements) {
+      src = mputstr(src,
+        "  boolean has_extension = FALSE;\n");
+      for (i = sdef->oerNrOrRootcomps; i < sdef->nElements; i++) {
+        src = mputprintf(src,
+        "  has_extension = has_extension || (field_%s.is_bound() && field_%s.is_present());\n",
+          sdef->elements[i].name, sdef->elements[sdef->oerP[i]].name);
+      }
+    }
     size_t opt_elements = 0;
-    for (i = 0; i < sdef->nElements; i++) {
-      if (sdef->elements[i].isOptional || sdef->elements[i].isDefault) {
+    size_t limit = sdef->oerExtendable ? sdef->oerNrOrRootcomps : sdef->nElements;
+    for (i = 0; i < limit; i++) {
+      if (sdef->elements[sdef->oerP[i]].isOptional || sdef->elements[sdef->oerP[i]].isDefault) {
         opt_elements++;
       }
     }
-    int needed_bytes = opt_elements / 8 + 1;
+    int bits = opt_elements+(sdef->oerExtendable == TRUE);
+    int needed_bytes = bits / 8 + (bits % 8 == 0 ? 0 : 1);
 
-    if (opt_elements != 0) {
-      src = mputprintf(src,
-        "  unsigned char c[%i] = {0};\n"
-        , needed_bytes);
+    int pos = 8;
+    if (opt_elements != 0 || sdef->oerExtendable) {
+      src = mputstr(src,
+        "  char c = 0;\n");
+      if (sdef->oerExtendable && sdef->oerNrOrRootcomps != sdef->nElements) {
+        pos--;
+        src = mputprintf(src,
+          "  if (has_extension) {\n"
+          "    c += %i;\n"
+          "  }\n", 1 << 7);
+      }
     }
+    
     int ind = 0;
-    int pos = 8;
-    for (i = 0; i < sdef->nElements; i++) {
-      if (sdef->elements[i].isOptional || sdef->elements[i].isDefault) {
+    for (i = 0; i < limit; i++) {
+      if (sdef->elements[sdef->oerP[i]].isOptional || sdef->elements[sdef->oerP[i]].isDefault) {
         pos--;
         src = mputprintf(src,
           "  if (field_%s.is_present()) {\n"
-          "    c[%i] += 1 << %i;\n"
+          "    c += %i;\n"
           "  }\n"
-          , sdef->elements[i].name, ind, pos);
+          , sdef->elements[sdef->oerP[i]].name
+          , 1 << pos);
         if (pos == 0) {
           pos = 8;
           ind++;
+          src = mputstr(src,
+            "  p_buf.put_c(c);\n"
+            "  c = 0\n;");
         }
       }
     }
-    if (opt_elements != 0) {
-      src = mputprintf(src,
-        "  p_buf.put_s(%i, c);\n"
-        , needed_bytes);
+    if (opt_elements != 0 || sdef->oerExtendable) {
+      if (pos != 8 || ind == 0) {
+        src = mputstr(src,
+          "  p_buf.put_c(c);\n");
+      }
     }
-    for (i = 0; i < sdef->nElements; i++) {
-      if (sdef->elements[i].isOptional || sdef->elements[i].isDefault) {
+    for (i = 0; i < limit; i++) {
+      if (sdef->elements[sdef->oerP[i]].isOptional || sdef->elements[sdef->oerP[i]].isDefault) {
         src = mputprintf(src,
           "  if (field_%s.is_present())\n  "
-          , sdef->elements[i].name);
+          , sdef->elements[sdef->oerP[i]].name);
       }
       src = mputprintf(src,
         "  field_%s.OER_encode(%s_descr_, p_buf);\n"
-        , sdef->elements[i].name, sdef->elements[i].typedescrname);
+        , sdef->elements[sdef->oerP[i]].name, sdef->elements[sdef->oerP[i]].typedescrname);
+    }
+
+    if (sdef->oerExtendable && sdef->oerNrOrRootcomps != sdef->nElements) {
+      bits = 0;
+      int eag_pos = 0;
+      for (i = limit; i < sdef->nElements; i++) {
+        if (sdef->oerEagNum != 0 && sdef->oerEag[eag_pos] == i - limit) {
+          eag_pos++;
+          bits++;
+          i += sdef->oerEag[eag_pos] - sdef->oerEag[eag_pos-1] - 1;
+          eag_pos++;
+        } else {
+          bits++;
+        }
+      }
+      needed_bytes = bits / 8 + (bits % 8 == 0 ? 0 : 1);
+      src = mputprintf(src,
+        "  if (has_extension) {\n"
+        "%s"
+        "    TTCN_Buffer tmp_buf;\n"
+        "    TTCN_Buffer tmp_buf2;\n"
+        "    TTCN_Buffer tmp_buf3;\n"
+        "    c = 0;\n"
+        , sdef->oerEagNum != 0 ? "    boolean has_present = FALSE;\n" : "");
+      eag_pos = 0;
+      pos = 8;
+      ind = 0;
+      for (i = limit; i < sdef->nElements; i++) {
+        pos--;
+        if (sdef->oerEagNum != 0 && sdef->oerEag[eag_pos] == i - limit) {
+          eag_pos++;
+          int opt_elems = 0;
+          for (int j = i; j < limit + sdef->oerEag[eag_pos]; j++) {
+            if (sdef->elements[sdef->oerP[j]].isOptional || sdef->elements[sdef->oerP[j]].isDefault) {
+              opt_elems++;
+            }
+            src = mputprintf(src,
+              "    has_present = has_present || field_%s.is_present();\n", sdef->elements[sdef->oerP[j]].name);
+          }
+          src = mputprintf(src,
+            "    if (has_present) {\n"
+            "      has_present = FALSE;\n"
+            "      c += %i;\n", 1 << pos);
+          if (opt_elems != 0) {
+            src = mputstr(src,
+              "      char c2 = 0;\n");
+            int pos2 = 8;
+            int ind2 = 0;
+            for (int j = i; j < limit + sdef->oerEag[eag_pos]; j++) {
+              if (sdef->elements[sdef->oerP[j]].isOptional || sdef->elements[sdef->oerP[j]].isDefault) {
+                pos2--;
+                src = mputprintf(src,
+                  "      if (field_%s.is_present()) {\n"
+                  "        c2 += %i;\n"
+                  "      }\n"
+                  , sdef->elements[sdef->oerP[j]].name, 1 << pos2);
+                if (pos2 == 0) {
+                  pos2 = 8;
+                  ind2++;
+                  src = mputstr(src,
+                    "      tmp_buf2.put_c(c2);\n"
+                    "      c2 = 0;\n");
+                }
+              }
+            }
+            if (pos2 != 8) {
+              src = mputstr(src,
+                "      tmp_buf2.put_c(c2);\n");
+            }
+          }
+          for (int j = i; j < limit + sdef->oerEag[eag_pos]; j++) {
+            src = mputprintf(src,
+              "      field_%s.OER_encode(%s_descr_, tmp_buf2);\n"
+              , sdef->elements[sdef->oerP[j]].name, sdef->elements[sdef->oerP[j]].typedescrname);
+          }
+          src = mputstr(src,
+            "      encode_oer_length(tmp_buf2.get_len(), tmp_buf, FALSE);\n"
+            "      tmp_buf.put_buf(tmp_buf2);\n"
+            "      tmp_buf2.clear();\n"
+            "    }\n");
+          i += sdef->oerEag[eag_pos] - sdef->oerEag[eag_pos-1] - 1;
+          eag_pos++;
+        } else {
+          src = mputprintf(src,
+            "    if (field_%s.is_present()) {\n"
+            "      c += %i;\n"
+            "      field_%s.OER_encode(%s_descr_, tmp_buf2);\n"
+            "      encode_oer_length(tmp_buf2.get_len(), tmp_buf, FALSE);\n"
+            "      tmp_buf.put_buf(tmp_buf2);\n"
+            "      tmp_buf2.clear();\n"
+            "    }\n"
+             , sdef->elements[sdef->oerP[i]].name, 1 << pos
+             , sdef->elements[sdef->oerP[i]].name, sdef->elements[sdef->oerP[i]].typedescrname);
+        }
+        if (pos == 0) {
+          ind++;
+          pos = 8;
+          src = mputstr(src,
+            "    tmp_buf3.put_c(c);\n"
+            "    c = 0;\n");
+        }
+      }
+      if (pos != 8) {
+        src = mputstr(src,
+            "    tmp_buf3.put_c(c);\n");
+      }
+      src = mputprintf(src,
+        "    encode_oer_length(%i, p_buf, FALSE);\n"
+        "    p_buf.put_c(%i);\n"
+        "    p_buf.put_buf(tmp_buf3);\n"
+        "    p_buf.put_buf(tmp_buf);\n"
+        "    tmp_buf.clear();\n"
+        "  }\n", needed_bytes+1, pos);
     }
     src = mputstr(src,
       "  return 0;\n"
@@ -4714,7 +4851,9 @@ void defRecordClass1(const struct_def *sdef, output_struct *output)
     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) {
+    bits = opt_elements+(sdef->oerExtendable == TRUE);
+    needed_bytes = bits / 8 + (bits % 8 == 0 ? 0 : 1);
+    if (needed_bytes != 0) {
       src = mputprintf(src, 
         "  const unsigned char* uc = p_buf.get_read_data();\n"
         "  p_buf.increase_pos(%i);\n"
@@ -4722,18 +4861,26 @@ void defRecordClass1(const struct_def *sdef, output_struct *output)
     }
     ind = 0;
     pos = 8;
-    for (i = 0; i < sdef->nElements; i++) {
-      if (sdef->elements[i].isOptional || sdef->elements[i].isDefault) {
+    if (sdef->oerExtendable) {
+      src = mputstr(src,
+        "  boolean has_extension = FALSE;\n"
+        "  if (uc[0] & 0x80) {\n"
+        "    has_extension = TRUE;\n"
+        "  }\n");
+      pos--;
+    }
+    for (i = 0; i < limit; i++) {
+      if (sdef->elements[sdef->oerP[i]].isOptional || sdef->elements[sdef->oerP[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) {
+            , sdef->elements[sdef->oerP[i]].typedescrname);
+          if (sdef->elements[sdef->oerP[i]].isOptional) {
             src = mputprintf(src, " else\n"
               "    field_%s = OMIT_VALUE;\n"
-              , sdef->elements[i].name);
+              , sdef->elements[sdef->oerP[i]].name);
           }
         if (pos == 0) {
           ind++;
@@ -4742,10 +4889,104 @@ void defRecordClass1(const struct_def *sdef, output_struct *output)
       } else {
         src = mputprintf(src,
           "  field_%s.OER_decode(%s_descr_, p_buf, p_oer);\n"
-          , sdef->elements[i].name
-          , sdef->elements[i].typedescrname);
+          , sdef->elements[sdef->oerP[i]].name
+          , sdef->elements[sdef->oerP[i]].typedescrname);
+      }
+    }
+    
+    if (sdef->oerExtendable) {
+      src = mputstr(src,
+        "  if (has_extension) {\n"
+        "    size_t bytes = decode_oer_length(p_buf, FALSE);\n"
+        "    uc = p_buf.get_read_data();\n"
+        "    p_buf.increase_pos(bytes);\n"
+        "    uc++;\n");
+      int eag_pos = 0;
+      pos = 8;
+      ind = 0;
+      for (i = limit; i < sdef->nElements; i++) {
+        pos--;
+        src = mputprintf(src,
+          "    if (!(uc[%i] & %i)) {\n"
+          , ind, 1 << pos);
+        if (sdef->oerEagNum != 0 && sdef->oerEag[eag_pos] == i - limit) {
+          eag_pos++;
+          for (int j = i; j < limit + sdef->oerEag[eag_pos]; j++) {
+            if (sdef->elements[sdef->oerP[j]].isOptional) {
+              src = mputprintf(src,
+                "      field_%s = OMIT_VALUE;\n"
+                , sdef->elements[sdef->oerP[j]].name);
+            }
+          }
+          eag_pos--;
+        } else {
+          if (sdef->elements[sdef->oerP[i]].isOptional) {
+            src = mputprintf(src,
+              "      field_%s = OMIT_VALUE;\n"
+              , sdef->elements[i].name);
+          }
+        }
+        src = mputstr(src,
+          "    } else {\n"
+          "      decode_oer_length(p_buf, FALSE);\n");
+        if (sdef->oerEagNum != 0 && sdef->oerEag[eag_pos] == i - limit) {
+          eag_pos++;
+          int nof_opt = 0;
+          for (int j = i; j < limit + sdef->oerEag[eag_pos]; j++) {
+            if (sdef->elements[sdef->oerP[j]].isOptional || sdef->elements[sdef->oerP[j]].isDefault) {
+              nof_opt++;
+            }
+          }
+          needed_bytes = nof_opt / 8 + (nof_opt % 8 == 0 ? 0 : 1);
+          src = mputprintf(src,
+            "      const unsigned char* uc2 = p_buf.get_read_data();\n"
+            "      (void)uc2;\n"
+            "      p_buf.increase_pos(%i);\n"
+            , needed_bytes);
+          int pos2 = 8;
+          int ind2 = 0;
+          for (int j = i; j < limit + sdef->oerEag[eag_pos]; j++) {
+            if (sdef->elements[sdef->oerP[j]].isOptional || sdef->elements[sdef->oerP[j]].isDefault) {
+              pos2--;
+              src = mputprintf(src,
+                "      if (uc2[%i] & %i) {\n"
+                "        field_%s.OER_decode(%s_descr_, p_buf, p_oer);\n"
+                "      }\n"
+                , ind2, 1 << pos2, sdef->elements[sdef->oerP[j]].name, sdef->elements[sdef->oerP[j]].typedescrname);
+              if (sdef->elements[sdef->oerP[j]].isOptional) {
+                src = mputprintf(src,
+                  "        else {\n"
+                  "          field_%s = OMIT_VALUE;\n"
+                  "        }\n"
+                  , sdef->elements[sdef->oerP[j]].name);
+              }
+              if (pos2 == 0) {
+                pos2 = 8;
+                ind2++;
+              }
+            } else {
+              src = mputprintf(src,
+                "      field_%s.OER_decode(%s_descr_, p_buf, p_oer);\n"
+                , sdef->elements[sdef->oerP[j]].name, sdef->elements[sdef->oerP[j]].typedescrname);
+            }
+          }
+          i += sdef->oerEag[eag_pos] - sdef->oerEag[eag_pos-1] - 1;
+          eag_pos++;
+        } else {
+          src = mputprintf(src,
+            "      field_%s.OER_decode(%s_descr_, p_buf, p_oer);\n"
+            , sdef->elements[sdef->oerP[i]].name, sdef->elements[sdef->oerP[i]].typedescrname);
+        }
+        src = mputstr(src, "    }\n");
+        if (pos == 0) {
+          pos = 8;
+          ind++;
+        }
       }
+      src = mputstr(src,
+        "  }\n");
     }
+    
     if (sdef->opentype_outermost) {
       src = mputstr(src,
         "  TTCN_EncDec_ErrorContext ec_1(\"While decoding opentypes: \");"
diff --git a/compiler2/ttcn3/OerAST.cc b/compiler2/ttcn3/OerAST.cc
index a4a754150c1b9d096655d4a59219d72fd2a7171e..0cf688c514000a10b9ca24963c17a0b5c5bdbbcd 100644
--- a/compiler2/ttcn3/OerAST.cc
+++ b/compiler2/ttcn3/OerAST.cc
@@ -15,10 +15,24 @@ OerAST::OerAST() :
   bytes(-1),
   signed_(false),
   length(-1),
-  extendable(false)
+  extendable(false),
+  nr_of_root_comps(0),
+  ext_attr_groups(),
+  p()
 {}
 
+OerAST::~OerAST() {
+  for (size_t i = 0; i < ext_attr_groups.size(); i++) {
+    delete ext_attr_groups[i];
+  }
+  ext_attr_groups.clear();
+  for (size_t i = 0; i < p.size(); i++) {
+    delete p[i];
+  }
+  p.clear();
+}
+
 bool OerAST::empty() const {
   return bytes == -1 && signed_ == false && length == -1 &&
-    extendable == false;
+    extendable == false && nr_of_root_comps == 0 && ext_attr_groups.empty() && p.empty();
 }
diff --git a/compiler2/ttcn3/OerAST.hh b/compiler2/ttcn3/OerAST.hh
index eb047006fb8429fdad40358af1543f13ab8240fa..26e3e9d39b32e55cecba91cca60ac019ad2a468c 100644
--- a/compiler2/ttcn3/OerAST.hh
+++ b/compiler2/ttcn3/OerAST.hh
@@ -12,14 +12,20 @@
 #ifndef OERAST_HH
 #define OERAST_HH
 
+#include "../vector.hh"
+
 class OerAST {
 public:
   int bytes;
   bool signed_;
   int length;
   bool extendable;
+  int nr_of_root_comps;
+  vector<int> ext_attr_groups;
+  vector<int> p;
   
   OerAST();
+  ~OerAST();
   bool empty() const;
 };
 
diff --git a/compiler2/union.c b/compiler2/union.c
index 5b1a117c49e1e526339382cde4f0b8addfdc0f7c..4023b471336fbc73e621e64a4a6f37fd88249352 100644
--- a/compiler2/union.c
+++ b/compiler2/union.c
@@ -2381,10 +2381,14 @@ void defUnionClass(struct_def const *sdef, output_struct *output)
       src = mputprintf(src, "  case %s_%s:\n", selection_prefix, sdef->elements[i].name);
       if (sdef->has_opentypes == FALSE) {
         src = mputprintf(src,
+          "    {TTCN_Buffer buf;\n"
           "    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);
+          "    field_%s->OER_encode(%s_descr_, buf);\n"
+          "%s"
+          "    p_buf.put_buf(buf);\n"
+          "    break;\n}"
+          , sdef->elements[i].typedescrname, sdef->elements[i].name, sdef->elements[i].typedescrname
+          , (!sdef->oerExtendable || i < sdef->oerNrOrRootcomps) ? "" : "    encode_oer_length(buf.get_len(), p_buf, FALSE);\n");
       } else {
         src = mputprintf(src,
           "    {\n"
@@ -2428,26 +2432,32 @@ void defUnionClass(struct_def const *sdef, output_struct *output)
             "    err_vals = p_err_descr->get_field_err_values(%d);\n"
             "    emb_descr = p_err_descr->get_field_emb_descr(%d);\n"
             "    if (NULL != err_vals && NULL != err_vals->value) {\n"
+            "      TTCN_Buffer tmp_buf;\n"
             "      if (NULL != err_vals->value->errval) {\n"
             "        if(err_vals->value->raw){\n"
-            "          err_vals->value->errval->OER_encode_negtest_raw(p_buf);\n"
+            "          err_vals->value->errval->OER_encode_negtest_raw(tmp_buf);\n"
             "        } else {\n"
             "          if (NULL == err_vals->value->type_descr) {\n"
             "            TTCN_error(\"internal error: erroneous value typedescriptor missing\");\n"
             "          }\n"
             "          encode_oer_tag(*err_vals->value->type_descr->ber, p_buf);\n"
-            "          err_vals->value->errval->OER_encode(*err_vals->value->type_descr, p_buf);\n"
+            "          err_vals->value->errval->OER_encode(*err_vals->value->type_descr, tmp_buf);\n"
+            "%s"
             "        }\n"
             "      }\n"
+            "      p_buf.put_buf(tmp_buf);\n"
             "    } else {\n"
             "      if (NULL != emb_descr) {\n"
             "        field_%s->OER_encode_negtest(emb_descr, %s_descr_, p_buf);\n"
             "      } else {\n"
+            "        encode_oer_tag(*err_vals->value->type_descr->ber, p_buf);\n"
             "        field_%s->OER_encode(%s_descr_, p_buf);\n"
             "      }\n"
             "    }\n"
             "    break;\n"
             , selection_prefix, sdef->elements[i].name, (int)i, (int)i
+            , (!sdef->oerExtendable || i < sdef->oerNrOrRootcomps) ?
+              "" : "          encode_oer_length(tmp_buf.get_len(), p_buf, FALSE);\n"
             , sdef->elements[i].name, sdef->elements[i].typedescrname
             , sdef->elements[i].name, sdef->elements[i].typedescrname);
         }
@@ -2482,10 +2492,13 @@ void defUnionClass(struct_def const *sdef, output_struct *output)
           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%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);
+            , sdef->elements[i].typedescrname,
+            (!sdef->oerExtendable || i < sdef->oerNrOrRootcomps) ? "" : "      decode_oer_length(p_buf, FALSE);\n"
+            , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname);
         }
         src = mputprintf(src,
         "{\n"
diff --git a/core/OER.cc b/core/OER.cc
index 009f71853aa5e0d7ef8f754ff139eed557680eed..3ab33adf3a1dade933d624e926b75d79950a5645 100644
--- a/core/OER.cc
+++ b/core/OER.cc
@@ -159,46 +159,46 @@ ASN_Tag_t decode_oer_tag(TTCN_Buffer& buf) {
   return tag;
 }
 
-const TTCN_OERdescriptor_t BOOLEAN_oer_ = { 0, FALSE, -1, FALSE };
+const TTCN_OERdescriptor_t BOOLEAN_oer_ = { 0, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
 
-const TTCN_OERdescriptor_t INTEGER_oer_ = { -1, TRUE, 0, FALSE };
+const TTCN_OERdescriptor_t INTEGER_oer_ = { -1, TRUE, 0, FALSE, 0, 0, NULL, 0, NULL };
 
-const TTCN_OERdescriptor_t BITSTRING_oer_ = { 0, FALSE, -1, FALSE };
+const TTCN_OERdescriptor_t BITSTRING_oer_ = { 0, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
 
-const TTCN_OERdescriptor_t OCTETSTRING_oer_ = { 0, FALSE, -1, FALSE };
+const TTCN_OERdescriptor_t OCTETSTRING_oer_ = { 0, FALSE, -1, FALSE, 0, 0, NULL , 0, NULL};
 
-const TTCN_OERdescriptor_t FLOAT_oer_ = { 0, FALSE, -1, FALSE };
+const TTCN_OERdescriptor_t FLOAT_oer_ = { 0, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
 
-const TTCN_OERdescriptor_t ASN_NULL_oer_ = { 0, FALSE, -1, FALSE };
+const TTCN_OERdescriptor_t ASN_NULL_oer_ = { 0, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
 
-const TTCN_OERdescriptor_t IA5String_oer_ = { 0, FALSE, -1, FALSE };
+const TTCN_OERdescriptor_t IA5String_oer_ = { 0, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
 
-const TTCN_OERdescriptor_t VisibleString_oer_ = { 0, FALSE, -1, FALSE };
+const TTCN_OERdescriptor_t VisibleString_oer_ = { 0, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
 
-const TTCN_OERdescriptor_t NumericString_oer_ = { 0, FALSE, -1, FALSE };
+const TTCN_OERdescriptor_t NumericString_oer_ = { 0, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
 
-const TTCN_OERdescriptor_t PrintableString_oer_ = { 0, FALSE, -1, FALSE };
+const TTCN_OERdescriptor_t PrintableString_oer_ = { 0, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
 
-const TTCN_OERdescriptor_t BMPString_oer_ = { 0, FALSE, -1, FALSE };
+const TTCN_OERdescriptor_t BMPString_oer_ = { 0, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
 
-const TTCN_OERdescriptor_t UniversalString_oer_ = { 0, FALSE, -1, FALSE };
+const TTCN_OERdescriptor_t UniversalString_oer_ = { 0, FALSE, -1, FALSE , 0, 0, NULL, 0, NULL };
 
-const TTCN_OERdescriptor_t UTF8String_oer_ = { 0, FALSE, -1, FALSE };
+const TTCN_OERdescriptor_t UTF8String_oer_ = { 0, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
 
-const TTCN_OERdescriptor_t TeletexString_oer_ = { 0, FALSE, -1, FALSE };
+const TTCN_OERdescriptor_t TeletexString_oer_ = { 0, FALSE, -1, FALSE, 0, 0, NULL , 0, NULL};
 
-const TTCN_OERdescriptor_t VideotexString_oer_ = { 0, FALSE, -1, FALSE };
+const TTCN_OERdescriptor_t VideotexString_oer_ = { 0, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
 
-const TTCN_OERdescriptor_t GraphicString_oer_ = { 0, FALSE, -1, FALSE };
+const TTCN_OERdescriptor_t GraphicString_oer_ = { 0, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
 
-const TTCN_OERdescriptor_t GeneralString_oer_ = { 0, FALSE, -1, FALSE };
+const TTCN_OERdescriptor_t GeneralString_oer_ = { 0, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
 
-const TTCN_OERdescriptor_t OBJID_oer_ = { 0, FALSE, -1, FALSE };
+const TTCN_OERdescriptor_t OBJID_oer_ = { 0, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
 
-const TTCN_OERdescriptor_t ASN_ROID_oer_ = { 0, FALSE, -1, FALSE };
+const TTCN_OERdescriptor_t ASN_ROID_oer_ = { 0, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
 
-const TTCN_OERdescriptor_t EMBEDDED_PDV_oer_ = { 0, FALSE, -1, FALSE };
+const TTCN_OERdescriptor_t EMBEDDED_PDV_oer_ = { 0, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
 
-const TTCN_OERdescriptor_t EXTERNAL_oer_ = { 0, FALSE, -1, FALSE };
+const TTCN_OERdescriptor_t EXTERNAL_oer_ = { 0, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
 
-const TTCN_OERdescriptor_t ObjectDescriptor_oer_ = { 0, FALSE, -1, FALSE };
\ No newline at end of file
+const TTCN_OERdescriptor_t ObjectDescriptor_oer_ = { 0, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
\ No newline at end of file
diff --git a/core/OER.hh b/core/OER.hh
index d1bbab55d5bd00ab5768c4dd842e9409c451461a..d2af25c69269c25893cc221d6887c50c0a30efe3 100644
--- a/core/OER.hh
+++ b/core/OER.hh
@@ -24,7 +24,20 @@ struct TTCN_OERdescriptor_t
   int bytes;
   boolean signed_;
   int length;
-  boolean extendable; // Always false. Possibly a bug with is_extendable()
+  boolean extendable;
+  int nr_of_root_comps;
+  // length of the eag int array
+  int eag_len;
+  // contains the start and end index of the extension groups, indexed from the
+  // index of last root component.
+  // {2 4} means that the 3rd and 4th element of the extensions are in a group.
+  // always contains even number of integers
+  const int * const eag;
+  int p_len;
+  // Contains the correct order of fields. (CER coding reorders fields)
+  // p[1] = 2 means that the reordered fields are not correct for OER coding,
+  // and the first field must be the second while coding in oer.
+  const int * const p;
 };
 
 struct OER_struct
diff --git a/core2/Basetype2.cc b/core2/Basetype2.cc
index 71eac887b270f1b3f39e9089bf5f481a609fc92e..886b2050067f84c8b4782c801c7184f56848e6c8 100644
--- a/core2/Basetype2.cc
+++ b/core2/Basetype2.cc
@@ -36,6 +36,7 @@
 #include "Addfunc.hh"
 #include "PreGenRecordOf.hh"
 #include "Encdec.hh"
+#include "OER.hh"
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -6262,14 +6263,30 @@ int Record_Type::OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_bu
   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);
+  int limit = field_count;
+  bool has_extension = false;
+  // If extendable record and has real extensions the first bit of the
+  // preamble is 1
+  if (p_td.oer->extendable) {
+    for (int i = p_td.oer->nr_of_root_comps; i < field_count; i++) {
+      // If there are extension fields the first bit is 1
+      if (get_at(p_td.oer->p[i])->is_bound() && get_at(p_td.oer->p[i])->is_present()) {
+        c = 1 << 7;
+        has_extension = true;
+        break;
+      }
+    }
+    pos--;
+    limit = p_td.oer->nr_of_root_comps;
+  }
+  for (int i = 0; i < limit; i++) {
+    boolean is_default_field = default_indexes && (default_indexes[next_default_idx].index==p_td.oer->p[i]);
     if (is_default_field) {
       next_default_idx++;
     }
-    if (get_at(i)->is_optional() || is_default_field) {
+    if (get_at(p_td.oer->p[i])->is_optional() || is_default_field) {
       pos--;
-      c += get_at(i)->is_present() << pos;
+      c += get_at(p_td.oer->p[i])->is_present() << pos;
       if (pos == 0) {
         p_buf.put_c(c);
         pos = 8;
@@ -6280,13 +6297,113 @@ int Record_Type::OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_bu
   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);
+  for (int i = 0; i < limit; ++i) {
+    get_at(p_td.oer->p[i])->OER_encode(*fld_descr(p_td.oer->p[i]), p_buf);
+  }
+
+  // If the record is extendable and has real extensions
+  if (has_extension) {
+    // Calculate the extension addition presence bitmap
+    TTCN_Buffer tmp_buf;
+    c = 0;
+    pos = 8;
+    int eag_pos = p_td.oer->eag_len == 0 ? -1 : 0;
+    for (int i = limit; i < field_count; i++) {
+      pos--;
+      if (eag_pos != -1 && p_td.oer->eag[eag_pos] == i - limit) {
+        eag_pos++;
+        for (int j = i; j < limit + p_td.oer->eag[eag_pos]; j++) {
+          if (get_at(p_td.oer->p[j])->is_bound() && get_at(p_td.oer->p[j])->is_present()) {
+            // Add bit if there are at least one present field
+            c += 1 << pos;
+            break;
+          }
+        }
+        i += p_td.oer->eag[eag_pos] - p_td.oer->eag[eag_pos-1] - 1;
+        eag_pos++;
+      } else {
+        // extension attribute groups counted as one in the presence bitmap
+        if (get_at(p_td.oer->p[i])->is_present()) {
+          c += 1 << pos;
+        }
+      }
+      // Prepare next octet of the bitmap
+      if (pos == 0) {
+        tmp_buf.put_c(c);
+        pos = 8;
+        c = 0;
+      }
+    }
+    // Put remaining presence bitmap
+    if (pos != 8) {
+      tmp_buf.put_c(c);
+    }
+ 
+    encode_oer_length(1 + tmp_buf.get_len(), p_buf, FALSE);
+    // Put the 'remaining bit' octet if there are any
+    p_buf.put_c(pos);
+    p_buf.put_buf(tmp_buf);
+    tmp_buf.clear();
+    
+    eag_pos = p_td.oer->eag_len == 0 ? -1 : 0;
+    for (int i = limit; i < field_count; ++i) {
+      boolean is_default_field = default_indexes && (default_indexes[next_default_idx].index==p_td.oer->p[i]);
+      if (is_default_field) {
+        next_default_idx++;
+      }
+      if (eag_pos != -1 && p_td.oer->eag[eag_pos] == i - limit) {
+        // If it is the start of the ext attribute group then calculate presence bitmap,
+        // because it is encoded as a sequence
+        eag_pos++;
+        c = 0;
+        pos = 8;
+        if (is_default_field) {
+          next_default_idx--;
+        }
+        bool has_present = false;
+        for (int j = i; j < limit + p_td.oer->eag[eag_pos]; j++) {
+          if (get_at(p_td.oer->p[j])->is_present()) {
+            has_present = true;
+          }
+          is_default_field = default_indexes && (default_indexes[next_default_idx].index==p_td.oer->p[j]);
+          if (is_default_field) {
+            next_default_idx++;
+          }
+          if (get_at(p_td.oer->p[j])->is_optional() || is_default_field) {
+            pos--;
+            c += get_at(p_td.oer->p[j])->is_present() << pos;
+            if (pos == 0) {
+              tmp_buf.put_c(c);
+              pos = 8;
+              c = 0;
+            }
+          }
+        }
+        if (pos != 8) {
+          tmp_buf.put_c(c);
+        }
+        if (has_present) {
+          for (int j = i; j < limit + p_td.oer->eag[eag_pos]; j++) {
+            get_at(p_td.oer->p[j])->OER_encode(*fld_descr(p_td.oer->p[j]), tmp_buf);
+          }
+          encode_oer_length(tmp_buf.get_len(), p_buf, FALSE);
+          p_buf.put_buf(tmp_buf);
+        }
+        tmp_buf.clear();
+        i += p_td.oer->eag[eag_pos] - p_td.oer->eag[eag_pos-1] - 1;
+        eag_pos++;
+      } else if (get_at(p_td.oer->p[i])->is_bound() && get_at(p_td.oer->p[i])->is_present()) {
+        get_at(p_td.oer->p[i])->OER_encode(*fld_descr(p_td.oer->p[i]), tmp_buf);
+        encode_oer_length(tmp_buf.get_len(), p_buf, FALSE);
+        p_buf.put_buf(tmp_buf);
+        tmp_buf.clear();
+      }
+    }
   }
   return 0;
 }
   
-int Record_Type::OER_encode_negtest(const Erroneous_descriptor_t* p_err_descr, const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf) const {
+int Record_Type::OER_encode_negtest(const Erroneous_descriptor_t* p_err_descr, const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const {
   int values_idx = 0;
   int edescr_idx = 0;
   int field_count = get_count();
@@ -6294,16 +6411,37 @@ int Record_Type::OER_encode_negtest(const Erroneous_descriptor_t* p_err_descr, c
   const default_struct* default_indexes = get_default_indexes();
   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);
+  int limit = field_count;
+  bool has_extension = false;
+  // If extendable record and has real extensions the first bit of the
+  // preamble is 1
+  if (p_td.oer->extendable) {
+    for (int i = p_td.oer->nr_of_root_comps; i < field_count; i++) {
+      const Erroneous_values_t* err_vals = p_err_descr->next_field_err_values(p_td.oer->p[i], values_idx);
+      boolean present = FALSE;
+      if (NULL != err_vals && NULL != err_vals->value && NULL != err_vals->value->errval) {
+        present = TRUE;
+      }
+      // If there are extension fields the first bit is 1
+      if ((get_at(p_td.oer->p[i])->is_bound() && get_at(p_td.oer->p[i])->is_present()) || present) {
+        c = 1 << 7;
+        has_extension = true;
+        break;
+      }
+    }
+    pos--;
+    limit = p_td.oer->nr_of_root_comps;
+  }
+  for (int i = 0; i < limit; i++) {
+    boolean is_default_field = default_indexes && (default_indexes[next_default_idx].index==p_td.oer->p[i]);
     if (is_default_field) {
       next_default_idx++;
     }
-    if (get_at(i)->is_optional() || is_default_field) {
+    if (get_at(p_td.oer->p[i])->is_optional() || is_default_field) {
       pos--;
-      const Erroneous_values_t* err_vals = p_err_descr->next_field_err_values(i, values_idx);
+      const Erroneous_values_t* err_vals = p_err_descr->next_field_err_values(p_td.oer->p[i], values_idx);
       int present = 1;
-      if ((NULL != err_vals && NULL != err_vals->value && NULL == err_vals->value->errval) || !get_at(i)->is_present()) {
+      if ((NULL != err_vals && NULL != err_vals->value && NULL == err_vals->value->errval) || !get_at(p_td.oer->p[i])->is_present()) {
         present = 0;
       }
       c += present << pos;
@@ -6318,13 +6456,13 @@ int Record_Type::OER_encode_negtest(const Erroneous_descriptor_t* p_err_descr, c
     p_buf.put_c(c);
   }
   values_idx = 0;
-  for (int i = 0; i < field_count; ++i) {
+  for (int i = 0; i < limit; ++i) {
     if (-1 != p_err_descr->omit_before && p_err_descr->omit_before > i) {
       continue;
     }
     
-    const Erroneous_values_t* err_vals = p_err_descr->next_field_err_values(i, values_idx);
-    const Erroneous_descriptor_t* emb_descr = p_err_descr->next_field_emb_descr(i, edescr_idx);
+    const Erroneous_values_t* err_vals = p_err_descr->next_field_err_values(p_td.oer->p[i], values_idx);
+    const Erroneous_descriptor_t* emb_descr = p_err_descr->next_field_emb_descr(p_td.oer->p[i], edescr_idx);
     
     if (NULL != err_vals && NULL != err_vals->before) {
       if (NULL == err_vals->before->errval) {
@@ -6353,11 +6491,11 @@ int Record_Type::OER_encode_negtest(const Erroneous_descriptor_t* p_err_descr, c
         }
       }
     } else {
-      if (NULL != fld_descr(i)->oer || get_at(i)->is_present()) {
+      if (NULL != fld_descr(p_td.oer->p[i])->oer || get_at(p_td.oer->p[i])->is_present()) {
         if (NULL != emb_descr) {
-          get_at(i)->OER_encode_negtest(emb_descr, *fld_descr(i), p_buf);
+          get_at(p_td.oer->p[i])->OER_encode_negtest(emb_descr, *fld_descr(p_td.oer->p[i]), p_buf);
         } else {
-          get_at(i)->OER_encode(*fld_descr(i), p_buf);
+          get_at(p_td.oer->p[i])->OER_encode(*fld_descr(p_td.oer->p[i]), p_buf);
         }
       }
     }
@@ -6381,38 +6519,303 @@ int Record_Type::OER_encode_negtest(const Erroneous_descriptor_t* p_err_descr, c
       break;
     }
   }
+  
+  // If the record is extendable and has real extensions
+  if (has_extension) {
+    // Calculate the extension addition presence bitmap
+    TTCN_Buffer tmp_buf;
+    c = 0;
+    pos = 8;
+    int eag_pos = p_td.oer->eag_len == 0 ? -1 : 0;
+    int old_values_idx = values_idx;
+    for (int i = limit; i < field_count; i++) {
+      pos--;
+      if (eag_pos != -1 && p_td.oer->eag[eag_pos] == i - limit) {
+        eag_pos++;
+        for (int j = i; j < limit + p_td.oer->eag[eag_pos]; j++) {
+          const Erroneous_values_t* err_vals = p_err_descr->next_field_err_values(p_td.oer->p[j], values_idx);
+          boolean present = FALSE;
+          boolean omit = FALSE;
+          if (NULL != err_vals && NULL != err_vals->value && NULL != err_vals->value->errval) {
+            present = TRUE;
+          }
+          if (NULL != err_vals && NULL != err_vals->value && NULL == err_vals->value->errval) {
+            omit = TRUE;
+          }
+          if (!omit && ((get_at(p_td.oer->p[j])->is_bound() && get_at(p_td.oer->p[j])->is_present()) || present)) {
+            // Add bit if there are at least one present field
+            c += 1 << pos;
+            break;
+          }
+        }
+        i += p_td.oer->eag[eag_pos] - p_td.oer->eag[eag_pos-1] - 1;
+        eag_pos++;
+      } else {
+        // Normal extension field
+        const Erroneous_values_t* err_vals = p_err_descr->next_field_err_values(p_td.oer->p[i], values_idx);
+        boolean present = FALSE;
+        boolean omit = FALSE;
+        if (NULL != err_vals && NULL != err_vals->value && NULL != err_vals->value->errval) {
+          present = TRUE;
+        }
+        if (NULL != err_vals && NULL != err_vals->value && NULL == err_vals->value->errval) {
+          omit = TRUE;
+        }
+        if (!omit && (get_at(p_td.oer->p[i])->is_present() || present)) {
+          c += 1 << pos;
+        }
+      }
+      // Prepare next octet of the bitmap
+      if (pos == 0) {
+        tmp_buf.put_c(c);
+        pos = 8;
+        c = 0;
+      }
+    }
+    // Put remaining presence bitmap
+    if (pos != 8) {
+      tmp_buf.put_c(c);
+    }
+ 
+    encode_oer_length(1 + tmp_buf.get_len(), p_buf, FALSE);
+    // Put the 'remaining bit' octet if there are any
+    p_buf.put_c(pos);
+    p_buf.put_buf(tmp_buf);
+    tmp_buf.clear();
+    values_idx = old_values_idx;
+    eag_pos = p_td.oer->eag_len == 0 ? -1 : 0;
+    for (int i = limit; i < field_count; ++i) {
+      boolean is_default_field = default_indexes && (default_indexes[next_default_idx].index==p_td.oer->p[i]);
+      if (is_default_field) {
+        next_default_idx++;
+      }
+      
+      if (eag_pos != -1 && p_td.oer->eag[eag_pos] == i - limit) {
+        // If it is the start of the ext attribute group then calculate presence bitmap,
+        // because it is encoded as a sequence
+        eag_pos++;
+        c = 0;
+        pos = 8;
+        if (is_default_field) {
+          next_default_idx--;
+        }
+        bool has_present = false;
+        for (int j = i; j < limit + p_td.oer->eag[eag_pos]; j++) {
+          const Erroneous_values_t* err_vals = p_err_descr->next_field_err_values(p_td.oer->p[j], values_idx);
+          boolean present = FALSE;
+          boolean omit = FALSE;
+          if (NULL != err_vals && NULL != err_vals->value && NULL != err_vals->value->errval) {
+            present = TRUE;
+          }
+          if (NULL != err_vals && NULL != err_vals->value && NULL == err_vals->value->errval) {
+            omit = TRUE;
+          }
+          if (!omit && (get_at(p_td.oer->p[j])->is_present() || present)) {
+            has_present = true;
+          }
+          is_default_field = default_indexes && (default_indexes[next_default_idx].index==p_td.oer->p[j]);
+          if (is_default_field) {
+            next_default_idx++;
+          }
+          if (get_at(p_td.oer->p[j])->is_optional() || is_default_field) {
+            pos--;
+            c += (!omit && (get_at(p_td.oer->p[j])->is_present() || present)) << pos;
+            if (pos == 0) {
+              tmp_buf.put_c(c);
+              pos = 8;
+              c = 0;
+            }
+          }
+        }
+        if (pos != 8) {
+          tmp_buf.put_c(c);
+        }
+        if (has_present) {
+          for (int j = i; j < limit + p_td.oer->eag[eag_pos]; j++) {
+            const Erroneous_values_t* err_vals = p_err_descr->next_field_err_values(p_td.oer->p[j], values_idx);
+            const Erroneous_descriptor_t* emb_descr = p_err_descr->next_field_emb_descr(p_td.oer->p[j], edescr_idx);
+            if (-1 != p_err_descr->omit_before && p_err_descr->omit_before > j) {
+              continue;
+            }
+            if (NULL != err_vals && NULL != err_vals->before) {
+              if (NULL == err_vals->before->errval) {
+                TTCN_error("internal error: erroneous before value missing");
+              }
+              if (err_vals->before->raw) {
+                err_vals->before->errval->OER_encode_negtest_raw(tmp_buf);
+              } else {
+                if (NULL == err_vals->before->type_descr) {
+                  TTCN_error("internal error: erroneous before typedescriptor missing");
+                }
+                // it's an extra field
+                err_vals->before->errval->OER_encode(*(err_vals->before->type_descr), tmp_buf);
+              }
+            }
+
+            if (NULL != err_vals && NULL != err_vals->value) {
+              if (NULL != err_vals->value->errval) {
+                if (err_vals->value->raw) {
+                  err_vals->value->errval->OER_encode_negtest_raw(tmp_buf);
+                } else {
+                  if (NULL == err_vals->value->type_descr) {
+                    TTCN_error("internal error: erroneous before typedescriptor missing");
+                  }
+                  err_vals->value->errval->OER_encode(*(err_vals->value->type_descr), tmp_buf);
+                }
+              }
+            } else {
+              if (NULL != fld_descr(p_td.oer->p[j])->oer || get_at(p_td.oer->p[j])->is_present()) {
+                if (NULL != emb_descr) {
+                  get_at(p_td.oer->p[j])->OER_encode_negtest(emb_descr, *fld_descr(p_td.oer->p[j]), tmp_buf);
+                } else if (get_at(p_td.oer->p[j])->is_bound()) {
+                  get_at(p_td.oer->p[j])->OER_encode(*fld_descr(p_td.oer->p[j]), tmp_buf);
+                }
+              }
+            }
+
+            if (NULL != err_vals && NULL != err_vals->after) {
+              if (NULL == err_vals->after->errval) {
+                TTCN_error("internal error: erroneous after value missing");
+              }
+              if (err_vals->after->raw) {
+                err_vals->after->errval->OER_encode_negtest_raw(tmp_buf);
+              } else {
+                if (NULL == err_vals->after->type_descr) {
+                  TTCN_error("internal error: erroneous before typedescriptor missing");
+                }
+                // it's an extra field
+                err_vals->after->errval->OER_encode(*(err_vals->after->type_descr), tmp_buf);
+              }
+            }
+            if (-1 != p_err_descr->omit_after && p_err_descr->omit_after <= j) {
+              break;
+            }
+          }
+          encode_oer_length(tmp_buf.get_len(), p_buf, FALSE);
+          p_buf.put_buf(tmp_buf);
+        }
+        tmp_buf.clear();
+        i += p_td.oer->eag[eag_pos] - p_td.oer->eag[eag_pos-1] - 1;
+        eag_pos++;
+      } else if (get_at(p_td.oer->p[i])->is_bound()) {
+        const Erroneous_values_t* err_vals = p_err_descr->next_field_err_values(p_td.oer->p[i], values_idx);
+        const Erroneous_descriptor_t* emb_descr = p_err_descr->next_field_emb_descr(p_td.oer->p[i], edescr_idx);
+        if (-1 != p_err_descr->omit_before && p_err_descr->omit_before > i) {
+          continue;
+        }
+        boolean need_length = TRUE;
+        if (NULL != err_vals && NULL != err_vals->before) {
+          if (NULL == err_vals->before->errval) {
+            TTCN_error("internal error: erroneous before value missing");
+          }
+          if (err_vals->before->raw) {
+            err_vals->before->errval->OER_encode_negtest_raw(tmp_buf);
+          } else {
+            if (NULL == err_vals->before->type_descr) {
+              TTCN_error("internal error: erroneous before typedescriptor missing");
+            }
+            // it's an extra field
+            err_vals->before->errval->OER_encode(*(err_vals->before->type_descr), tmp_buf);
+          }
+        }
+        
+        if (NULL != err_vals && NULL != err_vals->value) {
+          if (NULL != err_vals->value->errval) {
+            if (err_vals->value->raw) {
+              err_vals->value->errval->OER_encode_negtest_raw(p_buf);
+            } else {
+              if (NULL == err_vals->value->type_descr) {
+                TTCN_error("internal error: erroneous before typedescriptor missing");
+              }
+              err_vals->value->errval->OER_encode(*(err_vals->value->type_descr), tmp_buf);
+            }
+          } else {
+            need_length = FALSE;
+          }
+        } else {
+          if (NULL != fld_descr(p_td.oer->p[i])->oer || get_at(p_td.oer->p[i])->is_present()) {
+            if (NULL != emb_descr) {
+              get_at(p_td.oer->p[i])->OER_encode_negtest(emb_descr, *fld_descr(p_td.oer->p[i]), tmp_buf);
+            } else {
+              if (!get_at(p_td.oer->p[i])->is_present()) {
+                need_length = FALSE;
+              }
+              get_at(p_td.oer->p[i])->OER_encode(*fld_descr(p_td.oer->p[i]), tmp_buf);
+            }
+          }
+        }
+
+        if (NULL != err_vals && NULL != err_vals->after) {
+          if (NULL == err_vals->after->errval) {
+            TTCN_error("internal error: erroneous after value missing");
+          }
+          if (err_vals->after->raw) {
+            err_vals->after->errval->OER_encode_negtest_raw(tmp_buf);
+          } else {
+            if (NULL == err_vals->after->type_descr) {
+              TTCN_error("internal error: erroneous before typedescriptor missing");
+            }
+            // it's an extra field
+            err_vals->after->errval->OER_encode(*(err_vals->after->type_descr), tmp_buf);
+          }
+        }
+        if (need_length) {
+          encode_oer_length(tmp_buf.get_len(), p_buf, FALSE);
+          p_buf.put_buf(tmp_buf);
+        }
+        tmp_buf.clear();
+        
+        if (-1 != p_err_descr->omit_after && p_err_descr->omit_after <= i) {
+          break;
+        }
+      }
+    }
+  }
   return 0;
 }
   
-int Record_Type::OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf, OER_struct& p_oer) {
+int Record_Type::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, OER_struct& p_oer) {
   int field_count = get_count();
+  
+  const unsigned char* uc = p_buf.get_read_data();
+  bool has_extension = false;
+  size_t act_pos = 0;
   size_t nof_opt = 0;
+  int limit = field_count;
+  if (p_td.oer->extendable) {
+    // First bit 1 if there are extensions
+    if (uc[0] & 0x80) {
+      has_extension = true;
+    }
+    act_pos++;
+    nof_opt++;
+    limit = p_td.oer->nr_of_root_comps;
+  }
+  
   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);
+  for (int i = 0; i < limit; i++) {
+    boolean is_default_field = default_indexes && (default_indexes[next_default_idx].index==p_td.oer->p[i]);
     if (is_default_field) {
       next_default_idx++;
     }
-    if (get_at(i)->is_optional() || is_default_field) {
+    if (get_at(p_td.oer->p[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);
+  for (int i = 0; i < limit; ++i) {
+    boolean is_default_field = default_indexes && (default_indexes[next_default_idx].index==p_td.oer->p[i]);
     if (is_default_field) {
       next_default_idx++;
     }
-    if (get_at(i)->is_optional() || is_default_field) {
+    if (get_at(p_td.oer->p[i])->is_optional() || is_default_field) {
       if (!(uc[0] & 1 << (7-act_pos))) {
-        get_at(i)->set_to_omit();
+        get_at(p_td.oer->p[i])->set_to_omit();
       } else {
-        get_at(i)->OER_decode(*fld_descr(i), p_buf, p_oer);
+        get_at(p_td.oer->p[i])->OER_decode(*fld_descr(p_td.oer->p[i]), p_buf, p_oer);
       }
       act_pos++;
       if (act_pos == 8) {
@@ -6420,9 +6823,110 @@ int Record_Type::OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf, OE
         act_pos = 0;
       }
     } else {
-      get_at(i)->OER_decode(*fld_descr(i), p_buf, p_oer);
+      get_at(p_td.oer->p[i])->OER_decode(*fld_descr(p_td.oer->p[i]), p_buf, p_oer);
     }
   }
+  
+  // If there are extensions in the sequence
+  if (has_extension) {
+    bytes = decode_oer_length(p_buf, FALSE);
+    // uc points to the 'remaining bit' octet 
+    uc = p_buf.get_read_data();
+    p_buf.increase_pos(bytes);
+    // uc points to the extension presence bitmap
+    uc++;
+    int eag_pos = p_td.oer->eag_len == 0 ? -1 : 0;
+    act_pos = 0;
+    // Decode fields
+    for (int i = limit; i < field_count; ++i) {
+      boolean is_default_field = default_indexes && (default_indexes[next_default_idx].index==p_td.oer->p[i]);
+      if (is_default_field) {
+        next_default_idx++;
+      }
+      // If extension field is not present in the presence bitmap
+      if (!(uc[0] & 1 << (7-act_pos))) {
+        // If its an extension attribute group, handle the group as one
+        if (eag_pos != -1 && p_td.oer->eag[eag_pos] == i - limit) {
+          eag_pos++;
+          for (int j = i; j < limit + p_td.oer->eag[eag_pos]; j++) {
+            if (get_at(p_td.oer->p[j])->is_optional()) {
+              get_at(p_td.oer->p[j])->set_to_omit();
+            }
+          }
+          i += p_td.oer->eag[eag_pos] - p_td.oer->eag[eag_pos-1] - 1;
+          eag_pos++;
+        } else {
+          if (get_at(p_td.oer->p[i])->is_optional()) {
+            get_at(p_td.oer->p[i])->set_to_omit();
+          }
+        }
+      } else {
+        // Extension field or group is present
+        decode_oer_length(p_buf, FALSE);
+        if (eag_pos != -1 && p_td.oer->eag[eag_pos] == i - limit) {
+          eag_pos++;
+          nof_opt = 0;
+          // Compensate for earlier increment
+          if (is_default_field) {
+            next_default_idx--;
+          }
+          int old_next_default_idx = next_default_idx;
+          // Count optional and default fields
+          for (int j = i; j < limit + p_td.oer->eag[eag_pos]; j++) {
+            is_default_field = default_indexes && (default_indexes[next_default_idx].index==p_td.oer->p[j]);
+            if (is_default_field) {
+              next_default_idx++;
+            }
+            if (get_at(p_td.oer->p[j])->is_optional() || is_default_field) {
+              nof_opt++;
+            }
+          }
+          // uc2 points to the presence bitmap of the extension attr group
+          const unsigned char* uc2 = p_buf.get_read_data();
+          size_t act_pos2 = 0;
+          bytes = nof_opt / 8 + (nof_opt % 8 == 0 ? 0 : 1);
+          p_buf.increase_pos(bytes);
+          next_default_idx = old_next_default_idx;
+          for (int j = i; j < limit + p_td.oer->eag[eag_pos]; j++) {
+            is_default_field = default_indexes && (default_indexes[next_default_idx].index==p_td.oer->p[j]);
+            if (is_default_field) {
+              next_default_idx++;
+            }
+            if (get_at(p_td.oer->p[j])->is_optional() || is_default_field) {
+              // Field is not present
+              if (!(uc2[0] & 1 << (7-act_pos2))) {
+                if (get_at(p_td.oer->p[j])->is_optional()) {
+                  get_at(p_td.oer->p[j])->set_to_omit();
+                }
+              } else {
+                // Field is present
+                get_at(p_td.oer->p[j])->OER_decode(*fld_descr(p_td.oer->p[j]), p_buf, p_oer);
+              }
+              act_pos2++;
+              // Fetch the remaining of the presence bitmap from the next octet
+              if (act_pos2 == 8) {
+                uc2++;
+                act_pos2 = 0;
+              }
+            } else {
+              get_at(p_td.oer->p[j])->OER_decode(*fld_descr(p_td.oer->p[j]), p_buf, p_oer);
+            }
+          }
+          i += p_td.oer->eag[eag_pos] - p_td.oer->eag[eag_pos-1] - 1;
+          eag_pos++;
+        } else {
+          get_at(p_td.oer->p[i])->OER_decode(*fld_descr(p_td.oer->p[i]), p_buf, p_oer);
+        }
+      }
+      act_pos++;
+      // Fetch the remaining of the extension presence bitmap from the next octet
+      if (act_pos == 8) {
+        uc++;
+        act_pos = 0;
+      }
+    }
+  }
+  
   if (is_opentype_outermost()) {
     TTCN_EncDec_ErrorContext ec_1("While decoding opentypes: ");
     TTCN_Type_list p_typelist;
diff --git a/regression_test/OER/OER.ttcn b/regression_test/OER/OER.ttcn
index 94be9cbf6abd82f9c5b44834c7a4122402786a50..775f39a57a759f5128a809b932c31c428527b463 100644
--- a/regression_test/OER/OER.ttcn
+++ b/regression_test/OER/OER.ttcn
@@ -2056,6 +2056,12 @@
      with { extension "prototype (convert) encode(OER)" }
   
     external function dec_Union(in octetstring stream) return Union
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_UnionExtended(in UnionExtended pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_UnionExtended(in octetstring stream) return UnionExtended
      with { extension "prototype (convert) decode(OER)" }
 
  	testcase tc_union() runs on EmptyCT {
@@ -2170,6 +2176,20 @@
  			setverdict(fail, "tc_union: ", match(u, ures));
  		}
 
+        var UnionExtended u2, ures2;
+
+        u2 := {
+            f10 := 10
+        }
+        os := enc_UnionExtended(u2);
+        if (os != 'E102010A'O) {
+            setverdict(fail, "tc_union: ", match('E102010A'O, os));
+        }
+        ures2 := dec_UnionExtended(os);
+        if (u2 != ures2) {
+            setverdict(fail, "tc_union: ", match(u2, ures2));
+        }
+
  		setverdict(pass);
  	}
 
@@ -2185,6 +2205,36 @@
     external function dec_ExtensionRecord(in octetstring stream) return ExtensionRecord
      with { extension "prototype (convert) decode(OER)" }
 
+    external function enc_ExtensionRecord2(in ExtensionRecord2 pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_ExtensionRecord2(in octetstring stream) return ExtensionRecord2
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_ExtensionRecord3(in ExtensionRecord3 pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_ExtensionRecord3(in octetstring stream) return ExtensionRecord3
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_ExtensionRecord4(in ExtensionRecord4 pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_ExtensionRecord4(in octetstring stream) return ExtensionRecord4
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_ExtensionRecord5(in ExtensionRecord5 pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_ExtensionRecord5(in octetstring stream) return ExtensionRecord5
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_ExtensionRecord6(in ExtensionRecord6 pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_ExtensionRecord6(in octetstring stream) return ExtensionRecord6
+     with { extension "prototype (convert) decode(OER)" }
+
     external function enc_NoOptionalRecord(in NoOptionalRecord pdu) return octetstring
      with { extension "prototype (convert) encode(OER)" }
   
@@ -2203,6 +2253,7 @@
     external function dec_SomeOptionalRecord(in octetstring stream) return SomeOptionalRecord
      with { extension "prototype (convert) decode(OER)" }
 
+
  	testcase tc_sequence() runs on EmptyCT {
  		var octetstring os;
 
@@ -2217,17 +2268,583 @@
  			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 }
+ 		var ExtensionRecord er, erres;
+ 		er := { me := 1, me2 := 2 }
  		os := enc_ExtensionRecord(er);
- 		if (os != '0001'O) {
- 			setverdict(fail, "tc_sequence: ", match('0001'O, os));
+ 		if (os != '0001010102'O) {
+ 			setverdict(fail, "tc_sequence: ", match('0001010102'O, os));
  		}
  		erres := dec_ExtensionRecord(os);
  		if (er != erres) {
  			setverdict(fail, "tc_sequence: ", match(er, erres));
- 		}*/
+ 		}
+
+        var ExtensionRecord2 er2, erres2;
+        er2 := {
+            me := 1,
+            me2 := 2,
+            me3 := omit,
+            me4 := 4
+        }
+        os := enc_ExtensionRecord2(er2);
+        if (os != '40010101020104'O) {
+            setverdict(fail, "tc_sequence: ", match('40010101020104'O, os));
+        }
+        erres2 := dec_ExtensionRecord2(os);
+        if (not(match(log2str(er2), log2str(erres2)))) {
+            setverdict(fail, "tc_sequence: ", match(log2str(er2), log2str(erres2)));
+        }
+
+        er2 := {
+            me := 1,
+            me2 := 2,
+            me3 := omit,
+            me4 := 4,
+            f0 := 0,
+            f1 := 1,
+            f2 := 2,
+            f3 := 3,
+            f4 := 4,
+            f5 := 5,
+            f6 := 6,
+            f7 := 7,
+            f8 := 8,
+            f9 := 9
+        }
+        os := enc_ExtensionRecord2(er2);
+        if (os != 'C00101010201040305FFC0020100020101020102020103020104020105020106020107020108020109'O) {
+            setverdict(fail, "tc_sequence: ", match('C00101010201040305FFC0020100020101020102020103020104020105020106020107020108020109'O, os));
+        }
+        erres2 := dec_ExtensionRecord2(os);
+        if (not(match(log2str(er2), log2str(erres2)))) {
+            setverdict(fail, "tc_sequence: ", match(log2str(er2), log2str(erres2)));
+        }
+
+        er2 := {
+            me := 1,
+            me2 := 2,
+            me3 := omit,
+            me4 := 4,
+            f0 := 0,
+            f1 := 1,
+            f2 := omit,
+            f3 := 3,
+            f4 := 4,
+            f5 := omit,
+            f6 := 6,
+            f7 := omit,
+            f8 := 8,
+            f9 := 9,
+            f_nul := NULL
+        }
+        os := enc_ExtensionRecord2(er2);
+        if (os != 'C00101010201040305DAE002010002010102010302010402010602010802010900'O) {
+            setverdict(fail, "tc_sequence: ", match('C00101010201040305DAE002010002010102010302010402010602010802010900'O, os));
+        }
+        erres2 := dec_ExtensionRecord2(os);
+        if (not(match(log2str(er2), log2str(erres2)))) {
+            setverdict(fail, "tc_sequence: ", match(log2str(er2), log2str(erres2)));
+        }
+
+        var ExtensionRecord2 er3, erres3, erres4;
+        er3 := {
+            me := 1,
+            me2 := 2,
+            me3 := omit,
+            me4 := 4,
+            f0 := 0,
+            f1 := 1,
+            f2 := omit,
+            f3 := 3,
+            f4 := omit,
+            f5 := omit,
+            f6 := 6,
+            f7 := omit,
+            f8 := 8,
+            f_nul := NULL
+        }
+        os := enc_ExtensionRecord2(er3);
+        if (os != 'C00101010201040305D2A002010002010102010302010602010800'O) {
+            setverdict(fail, "tc_sequence: ", match('C00101010201040305D2A002010002010102010302010602010800'O, os));
+        }
+        erres3 := {
+            me := 1,
+            me2 := 2,
+            me3 := omit,
+            me4 := 4,
+            f0 := 0,
+            f1 := 1,
+            f2 := omit,
+            f3 := 3,
+            f4 := omit,
+            f5 := omit,
+            f6 := 6,
+            f7 := omit,
+            f8 := 8,
+            f9 := -,
+            f_nul := NULL
+        }
+        erres2 := dec_ExtensionRecord2(os);
+        if (not(match(log2str(erres3), log2str(erres2)))) {
+            setverdict(fail, "tc_sequence: ", match(log2str(erres3), log2str(erres2)));
+        }
+
+        var ExtensionRecord2 er4;
+        er4 := {
+            me := 1,
+            me2 := 2,
+            me3 := omit,
+            me4 := 4,
+            f0 := 0,
+            f1 := 1,
+            f2 := omit,
+            f3 := 3,
+            f6 := 6,
+            f7 := omit,
+            f8 := 8
+        }
+        os := enc_ExtensionRecord2(er4);
+        if (os != 'C00101010201040305D280020100020101020103020106020108'O) {
+            setverdict(fail, "tc_sequence: ", match('C00101010201040305D280020100020101020103020106020108'O, os));
+        }
+        erres4 := {
+            me := 1,
+            me2 := 2,
+            me3 := omit,
+            me4 := 4,
+            f0 := 0,
+            f1 := 1,
+            f2 := omit,
+            f3 := 3,
+            f4 := omit,
+            f5 := omit,
+            f6 := 6,
+            f7 := omit,
+            f8 := 8,
+            f9 := -,
+            f_nul := -
+        }
+        erres2 := dec_ExtensionRecord2(os);
+        if (not(match(log2str(erres4), log2str(erres2)))) {
+            setverdict(fail, "tc_sequence: ", match(log2str(erres4), log2str(erres2)));
+        }
+
+        var ExtensionRecord3 er5, erres5;
+        er5 := {
+            me := 1,
+            f0 := 0,
+            f1 := 1,
+            f2 := omit,
+            f3 := 3,
+            f4 := omit,
+            f5 := omit,
+            f6 := omit,
+            f7 := -,
+            f8 := 8,
+            f9 := 9,
+            f_nul := NULL
+        }
+        @try {
+            os := enc_ExtensionRecord3(er5);
+            setverdict(fail);
+        } @catch (e) {
+            setverdict(pass);
+        }
+
+        er5 := {
+            me := 1,
+            f0 := 0,
+            f1 := 1,
+            f2 := omit,
+            f3 := 3,
+            f4 := omit,
+            f5 := omit,
+            f6 := omit,
+            f7 := 7,
+            f8 := 8,
+            f9 := 9,
+            f_nul := NULL
+        }
+        os := enc_ExtensionRecord3(er5);
+        if (os != 'C0010102029C078001000101010305000107010802010900'O) {
+            setverdict(fail, "tc_sequence: ", match('C0010102029C078001000101010305000107010802010900'O, os));
+        }
+        erres5 := dec_ExtensionRecord3(os);
+        if (not(match(log2str(er5), log2str(erres5)))) {
+            setverdict(fail, "tc_sequence: ", match(log2str(er5), log2str(erres5)));
+        }
+
+        er5 := {
+            me := 1,
+            f0 := 0,
+            f1 := 1,
+            f2 := omit,
+            f3 := 3,
+            f4 := omit,
+            f5 := 5,
+            f6 := omit,
+            f7 := 7,
+            f8 := 8,
+            f9 := 9,
+            f_nul := NULL
+        }
+        os := enc_ExtensionRecord3(er5);
+        if (os != 'C001010202BC078001000101010302010505000107010802010900'O) {
+            setverdict(fail, "tc_sequence: ", match('C001010202BC078001000101010302010505000107010802010900'O, os));
+        }
+        erres5 := dec_ExtensionRecord3(os);
+        if (not(match(log2str(er5), log2str(erres5)))) {
+            setverdict(fail, "tc_sequence: ", match(log2str(er5), log2str(erres5)));
+        }
+
+        er5 := {
+            me := 1,
+            f0 := 0,
+            f1 := 1,
+            f2 := omit,
+            f3 := 3,
+            f4 := omit,
+            f5 := 5,
+            f6 := 6,
+            f7 := 7,
+            f8 := 8,
+            f9 := 9,
+            f_nul := NULL
+        }
+        os := enc_ExtensionRecord3(er5);
+        if (os != 'C001010202BC0780010001010103020105078001060107010802010900'O) {
+            setverdict(fail, "tc_sequence: ", match('C001010202BC0780010001010103020105078001060107010802010900'O, os));
+        }
+        erres5 := dec_ExtensionRecord3(os);
+        if (not(match(log2str(er5), log2str(erres5)))) {
+            setverdict(fail, "tc_sequence: ", match(log2str(er5), log2str(erres5)));
+        }
+
+        er5 := {
+            me := 1,
+            f0 := 0,
+            f1 := 1,
+            f2 := omit,
+            f3 := 3,
+            f4 := 4,
+            f5 := 5,
+            f6 := 6,
+            f7 := 7,
+            f8 := 8,
+            f9 := 9,
+            f_nul := NULL
+        }
+        os := enc_ExtensionRecord3(er5);
+        if (os != 'C001010202FC078001000101010303800104020105078001060107010802010900'O) {
+            setverdict(fail, "tc_sequence: ", match('C001010202FC078001000101010303800104020105078001060107010802010900'O, os));
+        }
+        erres5 := dec_ExtensionRecord3(os);
+        if (not(match(log2str(er5), log2str(erres5)))) {
+            setverdict(fail, "tc_sequence: ", match(log2str(er5), log2str(erres5)));
+        }
+
+        er5 := {
+            me := 1,
+            f0 := 0,
+            f1 := 1,
+            f2 := 2,
+            f3 := 3,
+            f4 := 4,
+            f5 := 5,
+            f6 := 6,
+            f7 := 7,
+            f8 := 8,
+            f9 := 9,
+            f_nul := NULL
+        }
+        os := enc_ExtensionRecord3(er5);
+        if (os != 'C001010202FC09C0010001010102010303800104020105078001060107010802010900'O) {
+            setverdict(fail, "tc_sequence: ", match('C001010202FC09C0010001010102010303800104020105078001060107010802010900'O, os));
+        }
+        erres5 := dec_ExtensionRecord3(os);
+        if (not(match(log2str(er5), log2str(erres5)))) {
+            setverdict(fail, "tc_sequence: ", match(log2str(er5), log2str(erres5)));
+        }
+
+        var ExtensionRecord4 er6, erres6;
+        er6 := {
+            me := 1,
+            f0 := 0,
+            f1 := 1,
+            f2 := 2,
+            f3 := 3,
+            f4 := 4,
+            f5 := 5,
+            f6 := 6,
+            f7 := 7,
+            f8 := 8,
+            f9 := 9,
+            f_nul := NULL
+        }
+        os := enc_ExtensionRecord4(er6);
+        if (os != 'C001010202FC09F001000101010201030380010402010507C00106010701080201090180'O) {
+            setverdict(fail, "tc_sequence: ", match('C001010202FC09F001000101010201030380010402010507C00106010701080201090180'O, os));
+        }
+        erres6 := dec_ExtensionRecord4(os);
+        if (not(match(log2str(er6), log2str(erres6)))) {
+            setverdict(fail, "tc_sequence: ", match(log2str(er6), log2str(erres6)));
+        }
+
+        er6 := {
+            me := 1,
+            f0 := 0,
+            f1 := 1,
+            f2 := 2,
+            f3 := 3,
+            f4 := 4,
+            f5 := 5,
+            f6 := omit,
+            f7 := omit,
+            f8 := 8,
+            f9 := 9,
+            f_nul := NULL
+        }
+        os := enc_ExtensionRecord4(er6);
+        if (os != 'C001010202FC09F0010001010102010303800104020105030001080201090180'O) {
+            setverdict(fail, "tc_sequence: ", match('C001010202FC09F0010001010102010303800104020105030001080201090180'O, os));
+        }
+        erres6 := dec_ExtensionRecord4(os);
+        if (not(match(log2str(er6), log2str(erres6)))) {
+            setverdict(fail, "tc_sequence: ", match(log2str(er6), log2str(erres6)));
+        }
+
+        er6 := {
+            me := 1,
+            f0 := 0,
+            f1 := 1,
+            f2 := omit,
+            f3 := 3,
+            f4 := 4,
+            f5 := 5,
+            f6 := omit,
+            f7 := omit,
+            f8 := 8,
+            f9 := 9,
+            f_nul := NULL
+        }
+        os := enc_ExtensionRecord4(er6);
+        if (os != 'C001010202FC07D001000101010303800104020105030001080201090180'O) {
+            setverdict(fail, "tc_sequence: ", match('C001010202FC07D001000101010303800104020105030001080201090180'O, os));
+        }
+        erres6 := dec_ExtensionRecord4(os);
+        if (not(match(log2str(er6), log2str(erres6)))) {
+            setverdict(fail, "tc_sequence: ", match(log2str(er6), log2str(erres6)));
+        }
+
+        er6 := {
+            me := 1,
+            f0 := 0,
+            f1 := 1,
+            f2 := omit,
+            f3 := 3,
+            f4 := 4,
+            f5 := 5,
+            f6 := omit,
+            f7 := omit,
+            f8 := 8,
+            f9 := 9,
+            f_nul := omit
+        }
+        os := enc_ExtensionRecord4(er6);
+        if (os != 'C001010202F807D00100010101030380010402010503000108020109'O) {
+            setverdict(fail, "tc_sequence: ", match('C001010202F807D00100010101030380010402010503000108020109'O, os));
+        }
+        erres6 := dec_ExtensionRecord4(os);
+        if (not(match(log2str(er6), log2str(erres6)))) {
+            setverdict(fail, "tc_sequence: ", match(log2str(er6), log2str(erres6)));
+        }
+
+
+        var ExtensionRecord5 er7, erres7, erres71;
+
+        er7 := {
+            me := 1,
+            f2 := omit
+        }
+        os := enc_ExtensionRecord5(er7);
+        if (os != '400101'O) {
+            setverdict(fail, "tc_sequence: ", match('400101'O, os));
+        }
+        erres71 := { me := 1 }
+        erres7 := dec_ExtensionRecord5(os);
+        if (not(match(log2str(erres7), log2str(erres71)))) {
+            setverdict(fail, "tc_sequence: ", match(log2str(erres7), log2str(erres71)));
+        }
+
+        er7 := {
+            me := 1,
+            f0 := 0,
+            f1 := 1,
+            f2 := 2,
+            f3 := 3,
+            f4 := 4,
+            f5 := 5,
+            f6 := 6,
+            f7 := 7,
+            f8 := 8,
+            f9 := 9,
+            f_nul := NULL
+        }
+        os := enc_ExtensionRecord5(er7);
+        if (os != 'C001010206C016FFC001000101010201030104010501060107010801090180'O) {
+            setverdict(fail, "tc_sequence: ", match('C001010206C016FFC001000101010201030104010501060107010801090180'O, os));
+        }
+        erres7 := dec_ExtensionRecord5(os);
+        if (not(match(log2str(er7), log2str(erres7)))) {
+            setverdict(fail, "tc_sequence: ", match(log2str(er7), log2str(erres7)));
+        }
+
+        er7 := {
+            me := 1,
+            f0 := 0,
+            f1 := 1,
+            f2 := omit,
+            f3 := 3,
+            f4 := 4,
+            f5 := omit,
+            f6 := omit,
+            f7 := omit,
+            f8 := 8,
+            f9 := omit,
+            f_nul := NULL
+        }
+        os := enc_ExtensionRecord5(er7);
+        if (os != 'C001010206C00CD880010001010103010401080180'O) {
+            setverdict(fail, "tc_sequence: ", match('C001010206C00CD880010001010103010401080180'O, os));
+        }
+        erres7 := dec_ExtensionRecord5(os);
+        if (not(match(log2str(er7), log2str(erres7)))) {
+            setverdict(fail, "tc_sequence: ", match(log2str(er7), log2str(erres7)));
+        }
+
+        var ExtensionRecord6 er8, erres8;
+        er8 := {
+            me := 1,
+            f0 := 0,
+            f1 := 1,
+            f2 := 2,
+            f3 := 3,
+            f4 := 4,
+            f5 := 5,
+            f6 := 6,
+            f7 := 7,
+            f8 := 8,
+            f9 := 9,
+            f_nul := NULL
+        }
+        os := enc_ExtensionRecord6(er8);
+        if (os != 'C001010302FFE0038001000380010103800102038001030380010403800105038001060380010703800108038001090180'O) {
+            setverdict(fail, "tc_sequence: ", match('C001010302FFE0038001000380010103800102038001030380010403800105038001060380010703800108038001090180'O, os));
+        }
+        erres8 := dec_ExtensionRecord6(os);
+        if (not(match(log2str(er8), log2str(erres8)))) {
+            setverdict(fail, "tc_sequence: ", match(log2str(er8), log2str(erres8)));
+        }
+
+        er8 := {
+            me := 1,
+            f0 := 0,
+            f1 := 1,
+            f2 := omit,
+            f3 := 3,
+            f4 := 4,
+            f5 := omit,
+            f6 := omit,
+            f7 := omit,
+            f8 := 8,
+            f9 := omit,
+            f_nul := NULL
+        }
+        os := enc_ExtensionRecord6(er8);
+        if (os != 'C001010302D8A003800100038001010380010303800104038001080180'O) {
+            setverdict(fail, "tc_sequence: ", match('C001010302D8A003800100038001010380010303800104038001080180'O, os));
+        }
+        erres8 := dec_ExtensionRecord6(os);
+        if (not(match(log2str(er8), log2str(erres8)))) {
+            setverdict(fail, "tc_sequence: ", match(log2str(er8), log2str(erres8)));
+        }
+
+        er8 := {
+            me := 1,
+            f0 := 0,
+            f1 := 1,
+            f2 := omit,
+            f3 := 3,
+            f4 := 4,
+            f5 := omit,
+            f6 := omit,
+            f7 := omit,
+            f8 := 8,
+            f9 := omit,
+            f_nul := NULL,
+            f10 := 10
+        }
+        os := enc_ExtensionRecord6(er8);
+        if (os != 'C001010302D8B00380010003800101038001030380010403800108018002010A'O) {
+            setverdict(fail, "tc_sequence: ", match('C001010302D8B00380010003800101038001030380010403800108018002010A'O, os));
+        }
+        erres8 := dec_ExtensionRecord6(os);
+        if (not(match(log2str(er8), log2str(erres8)))) {
+            setverdict(fail, "tc_sequence: ", match(log2str(er8), log2str(erres8)));
+        }
+
+        er8 := {
+            me := 1,
+            f0 := 0,
+            f1 := 1,
+            f2 := omit,
+            f3 := 3,
+            f4 := 4,
+            f5 := omit,
+            f6 := omit,
+            f7 := omit,
+            f8 := 8,
+            f9 := omit,
+            f_nul := NULL,
+            f10 := 10,
+            f11 := 11,
+            f12 := 12
+        }
+        os := enc_ExtensionRecord6(er8);
+        if (os != 'C001010302D8B80380010003800101038001030380010403800108018002010A04010B010C'O) {
+            setverdict(fail, "tc_sequence: ", match('C001010302D8B80380010003800101038001030380010403800108018002010A04010B010C'O, os));
+        }
+        erres8 := dec_ExtensionRecord6(os);
+        if (not(match(log2str(er8), log2str(erres8)))) {
+            setverdict(fail, "tc_sequence: ", match(log2str(er8), log2str(erres8)));
+        }
+
+        er8 := {
+            me := 1,
+            f0 := 0,
+            f1 := 1,
+            f2 := omit,
+            f3 := 3,
+            f4 := 4,
+            f5 := omit,
+            f6 := omit,
+            f7 := omit,
+            f8 := 8,
+            f9 := omit,
+            f_nul := NULL,
+            f10 := 10,
+            f11 := 11,
+            f12 := 12,
+            f13 := 13
+        }
+        os := enc_ExtensionRecord6(er8);
+        if (os != 'C001010302D8BC0380010003800101038001030380010403800108018002010A04010B010C02010D'O) {
+            setverdict(fail, "tc_sequence: ", match('C001010302D8BC0380010003800101038001030380010403800108018002010A04010B010C02010D'O, os));
+        }
+        erres8 := dec_ExtensionRecord6(os);
+        if (not(match(log2str(er8), log2str(erres8)))) {
+            setverdict(fail, "tc_sequence: ", match(log2str(er8), log2str(erres8)));
+        }
 
  		var NoOptionalRecord nr, nrres;
 
@@ -2547,6 +3164,12 @@
      with { extension "prototype (convert) encode(OER)" }
   
     external function dec_MySet(in octetstring stream) return MySet
+     with { extension "prototype (convert) decode(OER)" }
+
+    external function enc_MySetExtended(in MySetExtended pdu) return octetstring
+     with { extension "prototype (convert) encode(OER)" }
+  
+    external function dec_MySetExtended(in octetstring stream) return MySetExtended
      with { extension "prototype (convert) decode(OER)" }
 
  	testcase tc_set() runs on EmptyCT {
@@ -2571,6 +3194,65 @@
  			setverdict(fail, "tc_set: ", match(ms, msres));
  		}
 
+        var MySetExtended ms2, msres2;
+
+        ms2 := {
+            r1 := 3.14,
+            f1 := 1,
+            f2 := 2,
+            f3 := 3,
+            f4 := 4, 
+            f5 := 5,
+            f6 := 6
+        }
+        os := enc_MySetExtended(ms2);
+        if (os != '400102010401030106010508033331342E452D320101'O) {
+            setverdict(fail, "tc_set: ", match('400102010401030106010508033331342E452D320101'O, os));
+        }
+        msres2 := dec_MySetExtended(os);
+        if (log2str(ms2) != log2str(msres2)) {
+            setverdict(fail, "tc_set: ", match(log2str(ms2), log2str(msres2)));
+        }
+
+        ms2 := {
+            r1 := 3.14,
+            f1 := 1,
+            f2 := 2,
+            f3 := 3,
+            f4 := 4, 
+            f5 := 5,
+            f6 := 6,
+            f7 := 7
+        }
+        os := enc_MySetExtended(ms2);
+        if (os != 'C00102010401030106010508033331342E452D320101020680020107'O) {
+            setverdict(fail, "tc_set: ", match('C00102010401030106010508033331342E452D320101020680020107'O, os));
+        }
+        msres2 := dec_MySetExtended(os);
+        if (log2str(ms2) != log2str(msres2)) {
+            setverdict(fail, "tc_set: ", match(log2str(ms2), log2str(msres2)));
+        }
+
+        ms2 := {
+            r1 := 3.14,
+            f1 := 1,
+            f2 := 2,
+            f3 := 3,
+            f4 := 4, 
+            f5 := 5,
+            f6 := 6,
+            f7 := 7,
+            f8 := 8
+        }
+        os := enc_MySetExtended(ms2);
+        if (os != 'C00102010401030106010508033331342E452D3201010206C0020107020108'O) {
+            setverdict(fail, "tc_set: ", match('C00102010401030106010508033331342E452D3201010206C0020107020108'O, os));
+        }
+        msres2 := dec_MySetExtended(os);
+        if (log2str(ms2) != log2str(msres2)) {
+            setverdict(fail, "tc_set: ", match(log2str(ms2), log2str(msres2)));
+        }
+
  		setverdict(pass);
  	}
 
diff --git a/regression_test/OER/Types.asn b/regression_test/OER/Types.asn
index 413f2c438373fd790acbbd7c2b556f3e921eecc8..8d3d4072389b2b4d1868e26d26003732e19be4c6 100644
--- a/regression_test/OER/Types.asn
+++ b/regression_test/OER/Types.asn
@@ -242,9 +242,96 @@ OptionalRecord ::= SEQUENCE {
 }
 
 ExtensionRecord ::= SEQUENCE {
-	me MyEnum,
+	me INTEGER,
+	me2 INTEGER,
+	...
+}
+
+ExtensionRecord2 ::= SEQUENCE {
+	me INTEGER DEFAULT 5,
+	me2 INTEGER,
+	me3 INTEGER OPTIONAL,
+	me4 INTEGER,
+	...,
+	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,
+	f-nul NULL
+}
+
+ExtensionRecord3 ::= SEQUENCE {
+	me INTEGER DEFAULT 5,
+	...,
+	[[f0 INTEGER DEFAULT 5,
+	f1 INTEGER,
+	f2 INTEGER OPTIONAL,
+	f3 INTEGER]],
+	[[f4 INTEGER OPTIONAL]],
+	f5 INTEGER OPTIONAL,
+	[[f6 INTEGER OPTIONAL,
+	f7 INTEGER,
+	f8 INTEGER]],
+	f9 INTEGER DEFAULT 2,
+	[[f-nul NULL]]
+}
+
+ExtensionRecord4 ::= SEQUENCE {
+	me INTEGER DEFAULT 5,
+	...,
+	[[f0 INTEGER DEFAULT 5,
+	f1 INTEGER DEFAULT 5,
+	f2 INTEGER OPTIONAL,
+	f3 INTEGER DEFAULT 5]],
+	[[f4 INTEGER OPTIONAL]],
+	f5 INTEGER OPTIONAL,
+	[[f6 INTEGER OPTIONAL,
+	f7 INTEGER OPTIONAL,
+	f8 INTEGER]],
+	f9 INTEGER OPTIONAL,
+	[[f-nul NULL OPTIONAL]]
+}
+
+ExtensionRecord5 ::= SEQUENCE {
+	me INTEGER DEFAULT 5,
 	...,
-	f INTEGER
+	[[f0 INTEGER DEFAULT 5,
+	f1 INTEGER DEFAULT 5,
+	f2 INTEGER OPTIONAL,
+	f3 INTEGER DEFAULT 5,
+	f4 INTEGER OPTIONAL,
+	f5 INTEGER OPTIONAL,
+	f6 INTEGER OPTIONAL,
+	f7 INTEGER OPTIONAL,
+	f8 INTEGER DEFAULT 4,
+	f9 INTEGER OPTIONAL]],
+	[[f-nul NULL OPTIONAL]]
+}
+
+ExtensionRecord6 ::= SEQUENCE {
+	me INTEGER DEFAULT 5,
+	...,
+	[[f0 INTEGER DEFAULT 5]],
+	[[f1 INTEGER DEFAULT 5]],
+	[[f2 INTEGER OPTIONAL]],
+	[[f3 INTEGER DEFAULT 5]],
+	[[f4 INTEGER OPTIONAL]],
+	[[f5 INTEGER OPTIONAL]],
+	[[f6 INTEGER OPTIONAL]],
+	[[f7 INTEGER OPTIONAL]],
+	[[f8 INTEGER DEFAULT 4]],
+	[[f9 INTEGER OPTIONAL]],
+	[[f-nul NULL OPTIONAL]],
+	f10 INTEGER,
+	[[f11 INTEGER,
+	f12 INTEGER]],
+	f13 INTEGER
 }
 
 EmptyRecord ::= SEQUENCE {
@@ -278,6 +365,20 @@ Union ::= CHOICE {
 	f9 [PRIVATE 3] Unsigned1byteInt
 }
 
+UnionExtended ::= 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,
+	...,
+	f10 [PRIVATE 33] INTEGER
+}
+
 MySet ::= SET {
 	r1 [PRIVATE 2] [PRIVATE 7] REAL,
 	f1 [PRIVATE 4] INTEGER,
@@ -288,6 +389,19 @@ MySet ::= SET {
 	f6 [1] INTEGER
 }
 
+MySetExtended ::= 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,
+	...,
+	f7 [5] INTEGER,
+	[[f8 [9] INTEGER]]
+}
+
 MyRecordOf ::= SEQUENCE OF SomeOptionalRecord
 
 MySetOf ::= SET OF MySet
diff --git a/regression_test/negativeTest/Makefile b/regression_test/negativeTest/Makefile
index 45185d0be095e51aa5cad95782fc2f580a5aa6e4..1553eabeca19ec933968347ada748e310c3f1c7a 100644
--- a/regression_test/negativeTest/Makefile
+++ b/regression_test/negativeTest/Makefile
@@ -44,7 +44,7 @@ NegTest_RAW_Types.ttcn NegTest_RAW_Testcases.ttcn \
 www_XmlTest_org_negativeTest_XML_Types.ttcn NegTest_XML_Testcases.ttcn XSD.ttcn UsefulTtcn3Types.ttcn \
 NegTest_JSON.ttcn NegTest_Update.ttcn NegTest_OER.ttcn
 
-ASN1_MODULES = Types.asn NegTestTypes.asn
+ASN1_MODULES = Types.asn NegTestTypes.asn NegTestTypes2.asn
 
 GENERATED_SOURCES = $(TTCN3_MODULES:.ttcn=.cc) $(ASN1_MODULES:.asn=.cc)
 GENERATED_HEADERS = $(TTCN3_MODULES:.ttcn=.hh) $(ASN1_MODULES:.asn=.hh)
diff --git a/regression_test/negativeTest/NegTestTypes.asn b/regression_test/negativeTest/NegTestTypes.asn
index fcffefca048f1ee4ef2e966b62fdbb2e803c6d35..8683979a12bfcc728bd7cc7800849ac9df37086c 100644
--- a/regression_test/negativeTest/NegTestTypes.asn
+++ b/regression_test/negativeTest/NegTestTypes.asn
@@ -341,4 +341,11 @@ MyUnionComplexTypes ::= CHOICE {
   sofreal MySeqOfReal
 }
 
+MyUnionExtended ::= CHOICE {
+  b BOOLEAN,
+  n NULL,
+  ...,
+  i INTEGER
+}
+
 END
diff --git a/regression_test/negativeTest/NegTestTypes2.asn b/regression_test/negativeTest/NegTestTypes2.asn
new file mode 100644
index 0000000000000000000000000000000000000000..43be27826237b8ce01ad73fd014af12b76be785a
--- /dev/null
+++ b/regression_test/negativeTest/NegTestTypes2.asn
@@ -0,0 +1,27 @@
+--/////////////////////////////////////////////////////////////////////////////
+-- Copyright (c) 2000-2017 Ericsson Telecom AB
+-- All rights reserved. This program and the accompanying materials
+-- are made available under the terms of the Eclipse Public License v1.0
+-- which accompanies this distribution, and is available at
+-- http://www.eclipse.org/legal/epl-v10.html
+--
+-- Contributors:
+--   Szabo, Bence Janos
+--
+--/////////////////////////////////////////////////////////////////////////////
+NegTestTypes2
+DEFINITIONS
+AUTOMATIC TAGS
+::= BEGIN
+IMPORTS ;
+
+
+ExtensionRecord ::= SEQUENCE {
+  me INTEGER DEFAULT 5,
+  ...,
+  f0 INTEGER DEFAULT 5,
+  f1 INTEGER DEFAULT 5,
+  f2 INTEGER OPTIONAL
+}
+
+END
diff --git a/regression_test/negativeTest/NegTest_OER.ttcn b/regression_test/negativeTest/NegTest_OER.ttcn
index 605ea3b1ddd4ae72606e29fe31d490abc926a79e..e2284621c18a2ffa7e2a8cb2ad97af2facf84847 100644
--- a/regression_test/negativeTest/NegTest_OER.ttcn
+++ b/regression_test/negativeTest/NegTest_OER.ttcn
@@ -14,6 +14,7 @@
 module NegTest_OER {
 
 import from NegTestTypes all;
+import from NegTestTypes2 all;
 
 type component CT {}
 
@@ -39,6 +40,12 @@ external function f_enc_MySeqOfInt(in MySeqOfInt x) return octetstring
 external function f_enc_MyUnionBasicTypes(in MyUnionBasicTypes x) return octetstring
   with { extension "prototype(convert) encode(OER)" }
 
+external function f_enc_MyUnionExtended(in MyUnionExtended x) return octetstring
+  with { extension "prototype(convert) encode(OER)" }
+
+external function f_enc_ExtensionRecord(in ExtensionRecord x) return octetstring
+  with { extension "prototype(convert) encode(OER)" }
+
 /************* Erroneous values *************/
 const MySeqBool msb1 := { b := false } with { erroneous(b) "value := true" };
 const MySeqBool msb2 := { b := false } with { erroneous(b) "value := integer:1" };
@@ -78,6 +85,64 @@ const MyUnionBasicTypes mubt2 := { i := 1 } with {erroneous(i) "value := MyChars
 const MyUnionBasicTypes mubt3 := { i := 1 } with {erroneous(i) "value := omit"};
 const MyUnionBasicTypes mubt4 := { i := 1 } with {erroneous(i) "value(raw) := 'ABCD'O"};
 
+const MyUnionExtended mue1 := { i := 1 } with {erroneous(i) "value := 2"};
+const MyUnionExtended mue2 := { i := 1 } with {erroneous(i) "value(raw) := 'ABCD'O"};
+
+const ExtensionRecord er1 := {
+            me := 1,
+            f0 := 1
+} with {erroneous(f0) "value := 3"}
+
+const ExtensionRecord er2 := {
+            me := 1,
+            f0 := 1
+} with {erroneous(f0) "value := 3"
+        erroneous(f0) "after(raw) := 'AABB'O"}
+
+const ExtensionRecord er3 := {
+            me := 1,
+            f0 := 1
+} with {erroneous(f0) "value := 3"
+        erroneous(f0) "before(raw) := 'AABB'O"}
+
+const ExtensionRecord er4 := {
+            me := 1,
+            f0 := 1,
+            f1 := 2,
+            f2 := omit
+} with {erroneous(f0) "value := 3"
+        erroneous(f2) "value := 2"}
+
+const ExtensionRecord er5 := {
+            me := 1,
+            f0 := 1,
+            f1 := 2,
+            f2 := omit
+} with {erroneous(f0) "value := 3"
+        erroneous(f2) "value(raw) := 'ABCD'O"}
+
+const ExtensionRecord er6 := {
+            me := 1,
+            f0 := 1,
+            f1 := 2,
+            f2 := omit
+} with {erroneous(f0) "value := 3"
+        erroneous(f1) "value := omit"}
+
+const ExtensionRecord er7 := {
+            me := 1,
+            f0 := 1,
+            f1 := 2,
+            f2 := omit
+} with {erroneous(f1) "before := omit all"}
+
+const ExtensionRecord er8 := {
+            me := 1,
+            f0 := 1,
+            f1 := 2,
+            f2 := 3
+} with {erroneous(f0) "after := omit all"}
+
 /******** Test cases for records ********/
 testcase tc_record_change_value() runs on CT {
   var octetstring res := f_enc_msb(msb1);
@@ -241,9 +306,63 @@ testcase tc_union_change_value() runs on CT {
   log(res);
   if ('ABCD'O == res) { setverdict(pass); }
   else { setverdict(fail, res); }
+
+  res := f_enc_MyUnionExtended(mue1);
+  log(res);
+  if ('02020102'O == res) { setverdict(pass); }
+  else { setverdict(fail, res); }
+
+  res := f_enc_MyUnionExtended(mue2);
+  log(res);
+  if ('ABCD'O == res) { setverdict(pass); }
+  else { setverdict(fail, res); }
+}
+
+testcase tc_extension_record() runs on CT {
+  var octetstring res := f_enc_ExtensionRecord(er1);
+  log(res);
+  if ('C00101020580020103'O == res) { setverdict(pass); }
+  else { setverdict(fail, res); }
+
+  res := f_enc_ExtensionRecord(er2);
+  log(res);
+  if ('C00101020580040103AABB'O == res) { setverdict(pass); }
+  else { setverdict(fail, res); }
+
+  res := f_enc_ExtensionRecord(er3);
+  log(res);
+  if ('C0010102058004AABB0103'O == res) { setverdict(pass); }
+  else { setverdict(fail, res); }
+
+  res := f_enc_ExtensionRecord(er4);
+  log(res);
+  if ('C001010205E0020103020102020102'O == res) { setverdict(pass); }
+  else { setverdict(fail, res); }
+
+  res := f_enc_ExtensionRecord(er5);
+  log(res);
+  if ('C001010205E0020103020102ABCD00'O == res) { setverdict(pass); }
+  else { setverdict(fail, res); }
+
+  res := f_enc_ExtensionRecord(er6);
+  log(res);
+  if ('C00101020580020103'O == res) { setverdict(pass); }
+  else { setverdict(fail, res); }
+
+  res := f_enc_ExtensionRecord(er7);
+  log(res);
+  if ('C00205C0020102'O == res) { setverdict(pass); }
+  else { setverdict(fail, res); }
+
+  res := f_enc_ExtensionRecord(er8);
+  log(res);
+  if ('C001010205E0020101'O == res) { setverdict(pass); }
+  else { setverdict(fail, res); }
+
 }
 
 
+
 /*************** Control part ***************/
 control {
   execute(tc_record_change_value());
@@ -259,6 +378,8 @@ control {
   execute(tc_record_of_insert());
 
   execute(tc_union_change_value());
+
+  execute(tc_extension_record());
 }
 
 }
diff --git a/usrguide/referenceguide.doc b/usrguide/referenceguide.doc
index fd3d6b5c78b124931fed40039e2e6f83aa9fc173..7bdead365fc986f8c08b970edde399b4c18a4339 100644
Binary files a/usrguide/referenceguide.doc and b/usrguide/referenceguide.doc differ