diff --git a/compiler2/record.c b/compiler2/record.c
index b1d3cdf7d4ae7c1e08ce6a1ca984ab915bc4242e..4cf831439dc711528e87a7f775e8e8bb61e5f068 100644
--- a/compiler2/record.c
+++ b/compiler2/record.c
@@ -3041,6 +3041,13 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
         "  }\n"
         , sdef->elements[i].name);
     }
+    if (!sdef->elements[i].isOptional) {
+      src = mputprintf(src,
+        "  if (field_%s.is_bound()) {\n"
+        "    p_flavor &= ~XER_OPTIONAL;\n"
+        "  }\n"
+        , sdef->elements[i].name);
+    }
   } /* next field */
   
   if (i == start_at + num_attributes) {
@@ -3117,6 +3124,10 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
     if (!sdef->elements[i].isOptional) {
       src = mputprintf(src,
         "  if (!field_%s.is_bound()) {\n"
+        "    if (p_flavor & XER_OPTIONAL) {\n"
+        "      clean_up();\n"
+        "      return -1;\n"
+        "    }\n"
         "    TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG,\n"
         "      \"No data found for non-optional field '%s'\");\n"
         "  }\n"
diff --git a/compiler2/record_of.c b/compiler2/record_of.c
index 1cd8f7be523ed1d24540b49f971e6e9a5bddd81d..828cd66de89fb62683f737322434ca40eeaed3a4 100644
--- a/compiler2/record_of.c
+++ b/compiler2/record_of.c
@@ -1428,6 +1428,9 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output)
       /* The call to the non-const operator[] creates a new element object,
        * then we call its XER_decode with the temporary XML reader. */
       "      (*this)[val_ptr->n_elements].XER_decode(*p_td.oftype_descr, reader_2, p_flavor, p_flavor2, 0);\n"
+      "      if ((*this)[val_ptr->n_elements - 1].is_bound()) {\n"
+      "        p_flavor &= ~XER_OPTIONAL;\n"
+      "      }\n"
       "      if (p_flavor & EXIT_ON_ERROR && !(*this)[val_ptr->n_elements - 1].is_bound()) {\n"
       "        if (1 == val_ptr->n_elements) {\n"
       // Failed to decode even the first element
diff --git a/core/ASN_CharacterString.cc b/core/ASN_CharacterString.cc
index fb49217c5055826fc1a7075f605ac71085b6ab4c..4b91fc63a4579a25bda9c1aac37b2b533c260545 100644
--- a/core/ASN_CharacterString.cc
+++ b/core/ASN_CharacterString.cc
@@ -3394,6 +3394,11 @@ int CHARACTER_STRING::XER_decode(const XERdescriptor_t& p_td,
   for (; success == 1; success = reader.Read()) {
     type = reader.NodeType();
     if (XML_READER_TYPE_ELEMENT == type) {
+      // If our parent is optional and there is an unexpected tag then return and
+      // we stay unbound.
+      if ((flavor & XER_OPTIONAL) && !check_name((const char*)reader.LocalName(), p_td, exer)) {
+        return -1;
+      }
       verify_name(reader, p_td, exer);
       depth = reader.Depth();
       reader.Read();
diff --git a/core/ASN_EmbeddedPDV.cc b/core/ASN_EmbeddedPDV.cc
index 8f4b7f22ca0890b724ce4f9db722acfab9992603..c5d4e55aee75b1d8c6ba5676207538cdae68b232 100644
--- a/core/ASN_EmbeddedPDV.cc
+++ b/core/ASN_EmbeddedPDV.cc
@@ -3413,6 +3413,11 @@ int EMBEDDED_PDV::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
   for (success = reader.Ok(); success == 1; success = reader.Read()) {
     type = reader.NodeType();
     if (type==XML_READER_TYPE_ELEMENT) {
+      // If our parent is optional and there is an unexpected tag then return and
+      // we stay unbound.
+      if ((flavor & XER_OPTIONAL) && !check_name((const char*)reader.LocalName(), p_td, exer)) {
+        return -1;
+      }
       verify_name(reader, p_td, exer);
       depth = reader.Depth();
       reader.Read();
diff --git a/core/ASN_External.cc b/core/ASN_External.cc
index c1690ce25b4aec0069196763720192a8ff6cd188..2ba329dc83ef6d7933984a38831a97f792e991a8 100644
--- a/core/ASN_External.cc
+++ b/core/ASN_External.cc
@@ -603,6 +603,11 @@ namespace { /* anonymous namespace */
     for (; success == 1; success = reader.Read()) {
       int type = reader.NodeType();
       if (XML_READER_TYPE_ELEMENT == type) {
+        // If our parent is optional and there is an unexpected tag then return and
+        // we stay unbound.
+        if ((flavor & XER_OPTIONAL) && !check_name((const char*)reader.LocalName(), p_td, exer)) {
+          return -1;
+        }
         verify_name(reader, p_td, exer);
         depth = reader.Depth();
 	reader.Read();
diff --git a/core/ASN_Null.cc b/core/ASN_Null.cc
index 107d47585469f7247a49a6ad3249d05d3b3c6734..b857580844b5bebf73149119dc4d9ab328081ce6 100644
--- a/core/ASN_Null.cc
+++ b/core/ASN_Null.cc
@@ -266,6 +266,11 @@ int ASN_NULL::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
   for (; success == 1; success = reader.Read()) {
     int type = reader.NodeType();
     if (XML_READER_TYPE_ELEMENT == type) {
+      // If our parent is optional and there is an unexpected tag then return and
+      // we stay unbound.
+      if ((flavor & XER_OPTIONAL) && !check_name((const char*)reader.LocalName(), p_td, exer)) {
+        return -1;
+      }
       verify_name(reader, p_td, exer);
       depth = reader.Depth();
       break;
diff --git a/core/Bitstring.cc b/core/Bitstring.cc
index 571b342424b382148e2e5bda19934e59019fc395..f0e6ce518c008958ec6529e3c3a60881b5f5cf9d 100644
--- a/core/Bitstring.cc
+++ b/core/Bitstring.cc
@@ -1104,6 +1104,11 @@ int BITSTRING::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
     for (; success == 1; success = reader.Read()) {
       type = reader.NodeType();
       if (XML_READER_TYPE_ELEMENT == type) {
+        // If our parent is optional and there is an unexpected tag then return and
+        // we stay unbound.
+        if ((flavor & XER_OPTIONAL) && !check_name((const char*)reader.LocalName(), p_td, exer)) {
+          return -1;
+        }
         verify_name(reader, p_td, exer);
         depth = reader.Depth();
         if (reader.IsEmptyElement()) {
diff --git a/core/Boolean.cc b/core/Boolean.cc
index 4faa62f051fada2d53d4a73234cd0131feec5b68..ab68746175717c5d3b9ceba0d10493ef3f315f8f 100644
--- a/core/Boolean.cc
+++ b/core/Boolean.cc
@@ -663,6 +663,11 @@ int BOOLEAN::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
       type = reader.NodeType();
       if (!notag && depth == -1) {
         if (XML_READER_TYPE_ELEMENT == type) {
+          // If our parent is optional and there is an unexpected tag then return and
+          // we stay unbound.
+          if ((flavor & XER_OPTIONAL) && !check_name((const char*)reader.LocalName(), p_td, exer)) {
+            return -1;
+          }
           verify_name(reader, p_td, exer);
           depth = reader.Depth();
 
diff --git a/core/Charstring.cc b/core/Charstring.cc
index f2994c9c770c31d39202beecdc589fab346fcbc7..5d3240fb9f1d256bfd024a98cc6a5f899792ccab 100644
--- a/core/Charstring.cc
+++ b/core/Charstring.cc
@@ -1372,6 +1372,11 @@ int CHARSTRING::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
     for (; success == 1; success = reader.Read()) {
       int type = reader.NodeType();
       if (XML_READER_TYPE_ELEMENT == type) {
+        // If our parent is optional and there is an unexpected tag then return and
+        // we stay unbound.
+        if ((flavor & XER_OPTIONAL) && !check_name((const char*)reader.LocalName(), p_td, exer)) {
+          return -1;
+        }
         verify_name(reader, p_td, exer);
         if (reader.IsEmptyElement()) { // has no text, needs special processing
           if (exer && p_td.dfeValue != 0) {
diff --git a/core/Float.cc b/core/Float.cc
index 721420353ed6498e369a1363a30e03ddf8cdc83a..e01479804506c5fc2cb6d5bce07fc881b07afcff 100644
--- a/core/Float.cc
+++ b/core/Float.cc
@@ -989,6 +989,11 @@ tagless:
     for (; success == 1; success = reader.Read()) {
       int type = reader.NodeType();
       if (XML_READER_TYPE_ELEMENT == type) {
+        // If our parent is optional and there is an unexpected tag then return and
+        // we stay unbound.
+        if ((flavor & XER_OPTIONAL) && !check_name((const char*)reader.LocalName(), p_td, exer)) {
+          return -1;
+        }
         verify_name(reader, p_td, exer);
         if (reader.IsEmptyElement()) {
           if (exer && p_td.dfeValue != 0) {
diff --git a/core/Hexstring.cc b/core/Hexstring.cc
index 639c5e30816846bb40e4dfde082dee98159b3ec4..eb0595d66f28ce0e6440fda62bffba35327a8bc0 100644
--- a/core/Hexstring.cc
+++ b/core/Hexstring.cc
@@ -937,6 +937,11 @@ int HEXSTRING::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
    if (own_tag) for (; success == 1; success = reader.Read()) {
     type = reader.NodeType();
     if (XML_READER_TYPE_ELEMENT == type) {
+      // If our parent is optional and there is an unexpected tag then return and
+      // we stay unbound.
+      if ((flavor & XER_OPTIONAL) && !check_name((const char*)reader.LocalName(), p_td, exer)) {
+        return -1;
+      }
       verify_name(reader, p_td, exer);
       depth = reader.Depth();
       if (reader.IsEmptyElement()) {
diff --git a/core/Integer.cc b/core/Integer.cc
index f84fe0f59996d617011f3ff4fd8026e364044238..4a0e88edc2dabea3eac1ad7f3e1bbfe1f346f3ef 100644
--- a/core/Integer.cc
+++ b/core/Integer.cc
@@ -1647,6 +1647,11 @@ tagless:
     for (; success == 1; success = reader.Read()) {
       type = reader.NodeType();
       if (XML_READER_TYPE_ELEMENT == type) {
+        // If our parent is optional and there is an unexpected tag then return and
+        // we stay unbound.
+        if ((flavor & XER_OPTIONAL) && !check_name((const char*)reader.LocalName(), p_td, exer)) {
+          return -1;
+        }
         verify_name(reader, p_td, exer);
         if (reader.IsEmptyElement()) {
           if (exer && p_td.dfeValue != 0) {
diff --git a/core/Objid.cc b/core/Objid.cc
index dd09fd65778b8220476f3cd799356603f0e85864..fb9f997ef8e4d123fc8b2e0fc483bd1d8309c77a 100644
--- a/core/Objid.cc
+++ b/core/Objid.cc
@@ -566,6 +566,11 @@ int OBJID::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
   for (; success == 1; success = reader.Read()) {
     int type = reader.NodeType();
     if (XML_READER_TYPE_ELEMENT == type) {
+      // If our parent is optional and there is an unexpected tag then return and
+      // we stay unbound.
+      if ((flavor & XER_OPTIONAL) && !check_name((const char*)reader.LocalName(), p_td, exer)) {
+        return -1;
+      }
       verify_name(reader, p_td, exer);
       depth = reader.Depth();
       break;
diff --git a/core/Octetstring.cc b/core/Octetstring.cc
index b652ed43e8db6197de8b5b03f709917a3fd41ec0..1aa836e988bba5b9ec027b67ddf227e1bc924ad0 100644
--- a/core/Octetstring.cc
+++ b/core/Octetstring.cc
@@ -975,6 +975,11 @@ int OCTETSTRING::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
    if (own_tag) for (; success == 1; success = reader.Read()) {
     type = reader.NodeType();
     if (XML_READER_TYPE_ELEMENT == type) {
+      // If our parent is optional and there is an unexpected tag then return and
+      // we stay unbound.
+      if ((flavor & XER_OPTIONAL) && !check_name((const char*)reader.LocalName(), p_td, exer)) {
+        return -1;
+      }
       verify_name(reader, p_td, exer);
       depth = reader.Depth();
       if (reader.IsEmptyElement()) {
diff --git a/core/Optional.hh b/core/Optional.hh
index 8182f7ef0e835af033662e60dadd2001c756dcf1..df8a1ac446ab5b2a1fe7332b2184600d95676248 100644
--- a/core/Optional.hh
+++ b/core/Optional.hh
@@ -1102,7 +1102,8 @@ OPTIONAL<T_type>::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
           found_it:
           set_to_present();
           //success = reader.Read(); // move to next thing TODO should it loop till an element ?
-          optional_value->XER_decode(p_td, reader, flavor, flavor2, emb_val);
+          // Pass XER_OPTIONAL to flavor, to sign that we are optional
+          optional_value->XER_decode(p_td, reader, flavor | XER_OPTIONAL, flavor2, emb_val);
           if (!optional_value->is_bound()) {
             set_to_omit();
           }
diff --git a/core/Universal_charstring.cc b/core/Universal_charstring.cc
index a826ff1d4c97f190721e2dd3003ade5c1205c48d..4d9957f067b38f89a1de1d2865f6b0363fc9faf0 100644
--- a/core/Universal_charstring.cc
+++ b/core/Universal_charstring.cc
@@ -2148,6 +2148,11 @@ int UNIVERSAL_CHARSTRING::XER_decode(const XERdescriptor_t& p_td,
       if (!omit_tag) for (; success == 1; success = reader.Read()) {
         int type = reader.NodeType();
         if (XML_READER_TYPE_ELEMENT == type) {
+          // If our parent is optional and there is an unexpected tag then return and
+          // we stay unbound.
+          if ((flavor & XER_OPTIONAL) && !check_name((const char*)reader.LocalName(), p_td, exer)) {
+            return -1;
+          }
           verify_name(reader, p_td, exer);
           if (reader.IsEmptyElement()) {
             if (exer && p_td.dfeValue != 0) {
diff --git a/core/Verdicttype.cc b/core/Verdicttype.cc
index 82a47649865a32e3cddde01c71e440f900b58a4f..fdbb3e3d7a8c6ef5cb31ef5fe4c373e3cef5f7fc 100644
--- a/core/Verdicttype.cc
+++ b/core/Verdicttype.cc
@@ -332,6 +332,12 @@ int VERDICTTYPE::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader
     if (name_tag)      for (; rd_ok == 1; rd_ok = p_reader.Read()) {
         type = p_reader.NodeType();
         if (XML_READER_TYPE_ELEMENT == type) {
+          // If our parent is optional and there is an unexpected tag then return and
+          // we stay unbound.
+          if ((p_flavor & XER_OPTIONAL) && !check_name((const char*)p_reader.LocalName(), p_td, e_xer)) {
+            return -1;
+          }
+          verify_name(p_reader, p_td, e_xer);
           rd_ok = p_reader.Read();
           break;
         }
diff --git a/core/XER.hh b/core/XER.hh
index efc41a4afeff486793f48cb2f1a0a817d207a67f..c2bea32e094f664c2e9e84c1194e3537052d4d5b 100644
--- a/core/XER.hh
+++ b/core/XER.hh
@@ -57,7 +57,6 @@ enum XER_flavor {
   XER_EXTENDED        = 1U << 2, /**< Extended XER */
   DEF_NS_PRESENT      = 1U << 3, // 0x08
   DEF_NS_SQUASHED     = 1U << 4, // 0x10
-  XER_MASK            = 0x1FU,   /**< All the "real" XER flavors plus DEF_NS */
 
   /* Additional flags, for the parent to pass information to its children
    * (when the parent affects the child, e.g. LIST) */
@@ -100,7 +99,10 @@ enum XER_flavor {
   EXIT_ON_ERROR  = 1U << 29, /* 0x20000000 clean up and exit instead of throwing
   a decoding error, used on alternatives of a union with USE-UNION */
   XER_OPTIONAL   = 1U << 30, // 0x40000000 is an optional field of a record or set
-  BLOCKED        = 1U << 31  // 0x80000000 either ABSTRACT or BLOCK
+  BLOCKED        = 1U << 31,  // 0x80000000 either ABSTRACT or BLOCK
+  
+  /**< All the "real" XER flavors plus DEF_NS + XER_OPTIONAL*/
+  XER_MASK            = 0x1FU | XER_OPTIONAL
 };
 
 enum XER_flavor2 {
diff --git a/core2/Basetype2.cc b/core2/Basetype2.cc
index c62c657d5962b6a570ba7e8a57bf8e9817c13e24..695fdff6de0a1aae65ec6cc459dc8e7e6e2eff44 100644
--- a/core2/Basetype2.cc
+++ b/core2/Basetype2.cc
@@ -2399,6 +2399,9 @@ int Record_Of_Type::XER_decode(const XERdescriptor_t& p_td,
             ec_1.set_msg("%d: ", get_nof_elements());
             /* The call to the non-const get_at() creates the element */
             get_at(get_nof_elements())->XER_decode(*p_td.oftype_descr, reader, flavor, flavor2, emb_val);
+            if (get_at(get_nof_elements()-1)->is_bound()) {
+              flavor &= ~XER_OPTIONAL;
+            }
           }
           if (0 != emb_val && !own_tag && get_nof_elements() > 1 && !(p_td.oftype_descr->xer_bits & UNTAGGED)) {
             ++emb_val->embval_index;
@@ -5589,7 +5592,7 @@ int Record_Type::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
         }
       } // not empty element
     }
-    else { // not USE-ORDER, simpler code      
+    else { // not USE-ORDER, simpler code   
       if (usenil_attribute) {
         reader.MoveToElement(); // value absent, nothing more to do
       } else {
@@ -5642,6 +5645,10 @@ int Record_Type::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
               if (tag_closed)       new_flavor |= PARENT_CLOSED;
 
               get_at(i)->XER_decode(*xer_descr(i), reader, new_flavor, flavor2, emb_val);
+              if (!get_at(i)->is_optional() && get_at(i)->is_bound()) {
+                // Remove XER_OPTIONAL when we found a non optional field which is bound
+                flavor &= ~XER_OPTIONAL;
+              }
             }
           }
           if (!get_at(i)->is_present()) {
@@ -5683,6 +5690,12 @@ int Record_Type::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
   // Check if every non-optional field has been set
   for (i = 0; i < field_cnt; ++i) {
     if (!get_at(i)->is_optional() && !get_at(i)->is_bound()) {
+      if (flavor & XER_OPTIONAL) {
+        // If there is a non optional field which is unbound and we are optional
+        // then set to omit. Test: RecordOmit
+        clean_up();
+        return -1;
+      }
       TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG,
         "No data found for non-optional field '%s'", fld_name(i));
     }
diff --git a/regression_test/XML/Makefile b/regression_test/XML/Makefile
index f8187f37b9079c8f27a41f033a420b7ea7e42344..d0433baeadea48fefd5a7eba09034e372aebaf78 100644
--- a/regression_test/XML/Makefile
+++ b/regression_test/XML/Makefile
@@ -29,7 +29,8 @@ endif
 
 XDIRS := $(wildcard $(SHADOWED)) xsdConverter \
 HM60295 HN15589 HQ30408 HR49727 HU13380 $(RT2_ONLY) \
-XmlWorkflow tpdValidTest AbstractBlock UseNilLong AttributeFormDefault
+XmlWorkflow tpdValidTest AbstractBlock UseNilLong AttributeFormDefault \
+RecordOmit
 
 # List of fake targets:
 .PHONY: all dep clean run $(XDIRS) $(addsuffix /, $(XDIRS)) profile
diff --git a/regression_test/XML/RecordOmit/Makefile b/regression_test/XML/RecordOmit/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..232dcf8723e08c951563cae74dca17513d2957df
--- /dev/null
+++ b/regression_test/XML/RecordOmit/Makefile
@@ -0,0 +1,208 @@
+##############################################################################
+# Copyright (c) 2000-2016 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
+#
+##############################################################################
+TOPDIR := ../..
+include   ../../Makefile.regression
+
+ORIG ?= .
+
+ifdef SRCDIR
+ORIGSRC := $(ABS_SRC)
+#$(warning yes SRC, $(ORIGSRC))
+else
+ORIGSRC := $(ORIG)
+#$(warning no SRC, $(ORIGSRC))
+endif
+
+# WARNING! This Makefile can be used with GNU make only.
+# Other versions of make may report syntax errors in it.
+
+#
+# Do NOT touch this line...
+#
+.PHONY: all check clean dep objects preprocess
+.SUFFIXES: .d
+
+#
+# Set these variables...
+#
+
+# C preprocessor used for TTCN-3 files:
+CPP = cpp
+
+# Flags for the C++ preprocessor (and makedepend as well):
+CPPFLAGS += -D$(PLATFORM)
+
+# Flags for the C++ compiler: (-Wall already in)
+CXXFLAGS += -g -W -Wformat=2
+
+# Flags for the linker:
+#LDFLAGS += -g -rdynamic
+WIN32_LIBS += -liconv
+FREEBSD_LIBS += -liconv
+
+# Local flags for Titan (can be overridden from the environment or commandline)
+TTCNFLAGS += -b -r -x
+
+# Flags for the TTCN-3 and ASN.1 compiler
+# (common flags already set in Makefile.regression)
+COMPILER_FLAGS += $(TTCNFLAGS)
+
+# $(sort ) also eliminates duplicates
+COMPILER_FLAGS := $(sort $(COMPILER_FLAGS))
+
+# Execution mode: (either ttcn3 or ttcn3-parallel)
+TTCN3_LIB := ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX)
+
+#
+# You may change these variables. Add your files if necessary...
+#
+
+# TTCN-3 modules to preprocess:
+TTCN3_PP_MODULES := $(wildcard $(ORIGSRC)/../RecordOmit/*.ttcnpp)
+
+# Files to include in TTCN-3 preprocessed modules:
+TTCN3_INCLUDES := $(TOP_SRC)/XML/macros.ttcnin
+
+# ASN.1 modules of this project:
+ASN1_MODULES :=
+
+# TTCN-3 source files generated by the C preprocessor:
+PREPROCESSED_TTCN3_MODULES := $(TTCN3_PP_MODULES:.ttcnpp=.ttcn)
+
+
+# TTCN-3 modules of this project:
+ALL_TTCN3_MODULES    := $(wildcard $(ORIGSRC)/../RecordOmit/*.ttcn)
+# Eliminate preprocessed modules
+TTCN3_MODULES := $(filter-out $(PREPROCESSED_TTCN3_MODULES), $(ALL_TTCN3_MODULES))
+TTCN3_MODULES += $(TOP_SRC)/iconv/converter.ttcn
+
+# C++ source & header files generated from the TTCN-3 & ASN.1 modules of
+# this project:
+GENERATED_SOURCES := $(notdir $(TTCN3_MODULES:.ttcn=.cc) $(PREPROCESSED_TTCN3_MODULES:.ttcn=.cc) $(ASN1_MODULES:.asn=.cc))
+GENERATED_HEADERS := $(GENERATED_SOURCES:.cc=.hh)
+ifdef CODE_SPLIT
+GENERATED_SOURCES := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), .cc _seq.cc _set.cc  _seqof.cc _setof.cc _union.cc))
+else ifdef SPLIT_TO_SLICES
+POSTFIXES := $(foreach file, $(SPLIT_TO_SLICES), $(addsuffix $(file), _part_))
+POSTFIXES := $(foreach file, $(POSTFIXES), $(addprefix $(file), .cc))
+GENERATED_SOURCES2 := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), $(POSTFIXES)))
+GENERATED_SOURCES += $(GENERATED_SOURCES2)
+endif
+
+
+# C/C++ Source & header files of Test Ports, external functions and
+# other modules:
+USER_SOURCES := iconver.cc
+USER_HEADERS := $(USER_SOURCES:.cc=.hh)
+
+# Object files of this project that are needed for the executable test suite:
+OBJECTS = $(GENERATED_SOURCES:.cc=.o) $(USER_SOURCES:.cc=.o)
+
+# The name of the executable test suite:
+TARGET = RecordOmit$(RT2_SUFFIX)$(EXESUFFIX)
+
+
+#
+# Rules for building the executable...
+#
+
+all: $(TARGET) ;
+
+target: $(TARGET) ;
+
+objects: $(OBJECTS) ;
+
+ifeq ($(findstring dynamic,$(TTCN3_LIB)),)
+# not dynamic
+CORELIB_BINARY := $(TTCN3_DIR)/lib/lib$(TTCN3_LIB).a
+else
+CORELIB_BINARY := $(TTCN3_DIR)/lib/lib$(TTCN3_LIB).so
+endif
+
+$(TARGET): $(OBJECTS) $(CORELIB_BINARY)
+	$(CXX) $(LDFLAGS) -o $@ $(OBJECTS) \
+	-L$(TTCN3_DIR)/lib -l$(TTCN3_LIB) \
+	-L$(OPENSSL_DIR)/lib -lcrypto \
+	$($(PLATFORM)_LIBS) \
+	|| $(TTCN3_DIR)/bin/titanver $(OBJECTS)
+
+.cc.o .c.o:
+	@echo '(C++)' $<; $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $<
+
+.cc.d .c.d:
+	@echo Creating dependency file for '$<'; set -e; \
+	$(CXX) -MM $(CPPFLAGS) $(CXXFLAGS) $< \
+	| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
+	[ -s $@ ] || rm -f $@
+
+%.ttcn: %.ttcnpp $(TTCN3_INCLUDES)
+	$(CPP) -x c -nostdinc $(CPPFLAGS_TTCN3) $< $@
+
+preprocess: $(PREPROCESSED_TTCN3_MODULES) ;
+
+$(GENERATED_SOURCES) $(GENERATED_HEADERS): compile
+	@if [ ! -f $@ ]; then $(RM) compile; $(MAKE) compile; fi
+
+#
+############################################################################
+#
+
+compile: $(TTCN3_MODULES) $(PREPROCESSED_TTCN3_MODULES) $(ASN1_MODULES) $(firstword $(TTCN3_COMPILER))
+	$(TTCN3_COMPILER) $(COMPILER_FLAGS) $(filter-out $(TTCN3_COMPILER), $^)
+	touch $@
+
+clean:
+	-$(RM) $(TARGET) $(OBJECTS) $(GENERATED_HEADERS) \
+	$(GENERATED_SOURCES) $(PREPROCESSED_TTCN3_MODULES) compile \
+	tags *.log *.stackdump
+
+distclean: clean
+	-$(RM) $(DEPFILES)
+
+#
+# Add your rules here if necessary...
+#
+
+install:
+	@echo You cannot be serious!
+
+re:
+	rm -f compile
+
+RUN := $(shell which colortitan 2>/dev/null)
+ifeq ($(firstword $(RUN)),no)
+# stupid /bin/which on Solaris writes errors to stdout instead of stderr
+RUN :=
+endif
+
+run: $(TARGET)
+	$(RUN) ./$^
+
+debug:
+	$(MAKE) run RUN='gdb --args'
+
+vpath %.cc $(TOP_SRC)/iconv
+
+
+dep: ;
+
+DEPFILES := $(OBJECTS:.o=.d)
+
+ifeq (,$(findstring n,$(MAKEFLAGS)))
+ifeq (,$(filter clean distclean,$(MAKECMDGOALS)))
+-include $(DEPFILES)
+endif
+endif
+
+ifdef SRCDIR
+$(foreach src, $(USER_SOURCES), $(eval vpath $(src) $(ABS_SRC)))
+endif
diff --git a/regression_test/XML/RecordOmit/RecordOmit.ttcnpp b/regression_test/XML/RecordOmit/RecordOmit.ttcnpp
new file mode 100644
index 0000000000000000000000000000000000000000..5151bacf1984632a01a9e3850ab678aa13093b54
--- /dev/null
+++ b/regression_test/XML/RecordOmit/RecordOmit.ttcnpp
@@ -0,0 +1,219 @@
+/******************************************************************************
+ * Copyright (c) 2000-2016 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:
+ *   Bence Janos Szabo – initial implementation
+ *
+ ******************************************************************************/
+module RecordOmit {
+modulepar boolean RecordOmit_verbose := false;
+#define verbose RecordOmit_verbose
+#include "../macros.ttcnin"
+
+type component CT {};
+
+type record FirstRecordOpt
+{
+  record {
+    charstring foo optional,
+    charstring bar
+  } sequence optional,
+  boolean b
+}
+with {
+  variant "element";
+  variant (sequence) "untagged";
+};
+
+DECLARE_EXER_ENCODERS(FirstRecordOpt, firstrec);
+
+const FirstRecordOpt c_omit := { sequence := omit, b := true };
+
+const universal charstring c_result_omit_e := "<FirstRecordOpt>\n\t<b>true</b>\n</FirstRecordOpt>\n\n"
+
+const FirstRecordOpt c_not_omit := { sequence := { foo := "foo", bar := "bar"}, b := true};
+
+const universal charstring c_result_not_omit_e := "<FirstRecordOpt>\n\t<foo>foo</foo>\n\t<bar>bar</bar>\n\t<b>true</b>\n</FirstRecordOpt>\n\n";
+
+testcase tc_enc_first_record() runs on CT {
+	CHECK_METHOD(exer_enc_firstrec, c_omit, c_result_omit_e);
+	CHECK_METHOD(exer_enc_firstrec, c_not_omit, c_result_not_omit_e);
+}
+
+testcase tc_dec_first_record() runs on CT {
+	CHECK_DECODE(exer_dec_firstrec, c_result_omit_e, FirstRecordOpt, c_omit);
+	CHECK_DECODE(exer_dec_firstrec, c_result_not_omit_e, FirstRecordOpt, c_not_omit);
+}
+
+//-----------------------------------------------------------------------------
+
+type record MiddleRecordOpt
+{
+  boolean first optional,
+  record {
+    charstring foo optional,
+    charstring bar
+  } sequence optional,
+  boolean b
+}
+with {
+  variant "element";
+  variant (sequence) "untagged";
+};
+
+DECLARE_EXER_ENCODERS(MiddleRecordOpt, middlerec);
+
+const MiddleRecordOpt c_omit_middle := { first := omit, sequence := omit, b := true };
+
+const universal charstring c_result_omit_middle_e := "<MiddleRecordOpt>\n\t<b>true</b>\n</MiddleRecordOpt>\n\n"
+
+const MiddleRecordOpt c_not_omit_middle := { first := omit, sequence := { foo := "foo", bar := "bar"}, b := true};
+
+const universal charstring c_result_not_omit_middle_e := "<MiddleRecordOpt>\n\t<foo>foo</foo>\n\t<bar>bar</bar>\n\t<b>true</b>\n</MiddleRecordOpt>\n\n";
+
+const MiddleRecordOpt c_omit_middle2 := { first := true, sequence := omit, b := true };
+
+const universal charstring c_result_omit_middle2_e := "<MiddleRecordOpt>\n\t<first>true</first>\n\t<b>true</b>\n</MiddleRecordOpt>\n\n"
+
+testcase tc_enc_middle_record() runs on CT {
+	CHECK_METHOD(exer_enc_middlerec, c_omit_middle, c_result_omit_middle_e);
+	CHECK_METHOD(exer_enc_middlerec, c_not_omit_middle, c_result_not_omit_middle_e);
+	CHECK_METHOD(exer_enc_middlerec, c_omit_middle2, c_result_omit_middle2_e);
+}
+
+testcase tc_dec_middle_record() runs on CT {
+	CHECK_DECODE(exer_dec_middlerec, c_result_omit_middle_e, MiddleRecordOpt, c_omit_middle);
+	CHECK_DECODE(exer_dec_middlerec, c_result_not_omit_middle_e, MiddleRecordOpt, c_not_omit_middle);
+	CHECK_DECODE(exer_dec_middlerec, c_result_omit_middle2_e, MiddleRecordOpt, c_omit_middle2);
+}
+
+//-----------------------------------------------------------------------------
+
+type record AllTypesInRecord
+{
+  record {
+  	boolean bool optional,
+    bitstring bs optional,
+    octetstring os optional,
+    hexstring hs optional,
+    integer i optional,
+    float f optional,
+    charstring cs optional,
+    universal charstring us optional,
+    boolean end
+  } sequence optional,
+  boolean b
+}
+with {
+  variant "element";
+  variant (sequence) "untagged";
+};
+
+DECLARE_EXER_ENCODERS(AllTypesInRecord, allrec);
+
+const AllTypesInRecord c_omit_allrec := { sequence := omit, b := true };
+
+const universal charstring c_result_omit_allrec_e := "<AllTypesInRecord>\n\t<b>true</b>\n</AllTypesInRecord>\n\n"
+
+testcase tc_enc_alltype_record() runs on CT {
+	CHECK_METHOD(exer_enc_allrec, c_omit_allrec, c_result_omit_allrec_e);
+}
+
+testcase tc_dec_alltype_record() runs on CT {
+	CHECK_DECODE(exer_dec_allrec, c_result_omit_allrec_e, AllTypesInRecord, c_omit_allrec);
+}
+
+//-----------------------------------------------------------------------------
+
+type record UnionUntagged
+{
+  union {
+  	boolean bool,
+    bitstring bs,
+    octetstring os,
+    hexstring hs,
+    integer i,
+    float f,
+    charstring cs,
+    universal charstring us,
+    boolean end
+  } choice optional,
+  boolean b
+}
+with {
+  variant "element";
+  variant (choice) "untagged";
+};
+
+DECLARE_EXER_ENCODERS(UnionUntagged, union);
+
+const UnionUntagged c_omit_union := { choice := omit, b := true };
+
+const universal charstring c_result_omit_union_e := "<UnionUntagged>\n\t<b>true</b>\n</UnionUntagged>\n\n"
+
+testcase tc_enc_union() runs on CT {
+	CHECK_METHOD(exer_enc_union, c_omit_union, c_result_omit_union_e);
+}
+
+testcase tc_dec_union() runs on CT {
+	CHECK_DECODE(exer_dec_union, c_result_omit_union_e, UnionUntagged, c_omit_union);
+}
+
+
+
+type record Inner {
+	charstring a
+}
+with {
+  variant "untagged";
+}
+
+type record RecordOfRecordUntagged
+{
+  record of Inner sequence optional,
+  boolean b
+}
+with {
+  variant "element";
+};
+
+DECLARE_EXER_ENCODERS(RecordOfRecordUntagged, recordof);
+
+const RecordOfRecordUntagged c_omit_recordof := { sequence := omit, b := true };
+
+const universal charstring c_result_omit_recordof_e := "<RecordOfRecordUntagged>\n\t<b>true</b>\n</RecordOfRecordUntagged>\n\n"
+
+testcase tc_enc_recordof() runs on CT {
+	CHECK_METHOD(exer_enc_recordof, c_omit_recordof, c_result_omit_recordof_e);
+}
+
+testcase tc_dec_recordof() runs on CT {
+	CHECK_DECODE(exer_dec_recordof, c_result_omit_recordof_e, RecordOfRecordUntagged, c_omit_recordof);
+}
+
+
+
+control {
+	execute(tc_enc_first_record());
+	execute(tc_dec_first_record());
+
+	execute(tc_enc_middle_record());
+	execute(tc_dec_middle_record());
+
+	execute(tc_enc_alltype_record());
+	execute(tc_dec_alltype_record());
+
+	execute(tc_enc_union());
+	execute(tc_dec_union());
+
+	execute(tc_enc_recordof());
+	execute(tc_dec_recordof());
+}
+
+} with {
+encode "XML";
+}