diff --git a/compiler2/ttcn3/AST_ttcn3.cc b/compiler2/ttcn3/AST_ttcn3.cc
index 1c37fdf5357ad33441dfdbc76d3271e718fd8699..f31abf996ec521d201a0971f606c6f57619d424c 100644
--- a/compiler2/ttcn3/AST_ttcn3.cc
+++ b/compiler2/ttcn3/AST_ttcn3.cc
@@ -1211,7 +1211,7 @@ namespace Ttcn {
     return component_defs->has_ass_withId(p_id)
       || parent_scope->has_ass_withId(p_id);
   }
-
+  
   // =================================
   // ===== FriendMod
   // =================================
@@ -6231,7 +6231,7 @@ namespace Ttcn {
     if (!my_module) FATAL_ERROR("Def_Function::get_runs_on_scope()");
     return my_module->get_runs_on_scope(comptype);
   }
-
+  
   void Def_Function::chk()
   {
     if (checked) return;
@@ -6662,10 +6662,13 @@ namespace Ttcn {
           }
         }
         else {
-          if (Common::Type::CT_XER == encoding_type
-            && input_type->get_type_refd_last()->is_untagged()) {
-            // "untagged" on the (toplevel) input type will have no effect.
-            warning("UNTAGGED encoding attribute is ignored on top-level type");
+          if (Common::Type::CT_XER == encoding_type) {
+            Type* last = input_type->get_type_refd_last();
+            if (last->is_untagged() &&
+              last->get_typetype() == Type::T_CHOICE_A || last->get_typetype() == Type::T_CHOICE_T) {
+              // "untagged" on the (toplevel) input type will have no effect unless it is union
+              warning("UNTAGGED encoding attribute is ignored on top-level type");
+            }
           }
           if (Common::Type::CT_CUSTOM == encoding_type ||
               Common::Type::CT_PER == encoding_type) {
diff --git a/compiler2/union.c b/compiler2/union.c
index 7bf83ffb3d611ac57b82578fe42ea1331f6050ab..3223e47d0600ec2dfe79371486c63a0062cb88ac 100644
--- a/compiler2/union.c
+++ b/compiler2/union.c
@@ -1520,7 +1520,9 @@ void defUnionClass(struct_def const *sdef, output_struct *output)
       "  if (is_exer(p_flavor)) flavor_1 &= ~XER_RECOF;\n"
       "  if (!(p_flavor & XER_LIST)) flavor_2 |= FROM_UNION_USETYPE;\n"
       "  boolean omit_tag = begin_xml(p_td, p_buf, flavor_1, p_indent, FALSE, "
-      "(collector_fn)&%s::collect_ns%s, flavor_2);\n"
+      "(collector_fn)&%s::collect_ns%s, flavor_2 | THIS_UNION);\n"
+      // Top level union can be untagged, so don't increase the indentation
+      "  int p_indent_tmp = (is_exer(p_flavor) && p_indent == 0 && (p_td.xer_bits & UNTAGGED)) ? p_indent : p_indent + (!p_indent || !omit_tag);\n"
       , sdef->name
       , sdef->xerUseTypeAttr ? ", type_atr" : ", 0");
     src = mputprintf(src,
@@ -1531,7 +1533,7 @@ void defUnionClass(struct_def const *sdef, output_struct *output)
       src = mputprintf(src, "  case %s_%s:\n"
 	"    ec_1.set_msg(\"%s': \");\n"
 	"    field_%s->XER_encode(%s_xer_, p_buf, flavor_0, "
-	"flavor_2, p_indent + (!p_indent || !omit_tag), 0);\n"
+	"flavor_2, p_indent_tmp, 0);\n"
 	"    break;\n",
 	selection_prefix, sdef->elements[i].name,
 	sdef->elements[i].dispname,
@@ -1546,7 +1548,7 @@ void defUnionClass(struct_def const *sdef, output_struct *output)
       src = mputstr(src, "  if (p_buf.get_data()[p_buf.get_len()-1] != '\\n') flavor_1 |= SIMPLE_TYPE;\n");
     }
     src = mputstr(src,
-      "  end_xml(p_td, p_buf, flavor_1, p_indent, 0);\n"
+      "  end_xml(p_td, p_buf, flavor_1, p_indent, 0, flavor_2 | THIS_UNION);\n"
       "  return (int)p_buf.get_len() - encoded_length;\n"
       "}\n\n");
       
@@ -1739,7 +1741,6 @@ void defUnionClass(struct_def const *sdef, output_struct *output)
       "  int rd_ok=1, xml_depth=-1;\n"
       "%s%s"
       "  unsigned long xerbits = p_td.xer_bits;\n"
-      "  if (p_flavor & XER_TOPLEVEL) xerbits &= ~UNTAGGED;\n"
       "  if (xerbits & USE_TYPE_ATTR) p_flavor &= ~XER_RECOF;\n"
       "  boolean own_tag = !(e_xer && ((xerbits & (ANY_ELEMENT | UNTAGGED)) "
       "|| (p_flavor & (USE_NIL|(e_xer ? XER_LIST : XER_RECOF)))));\n"
diff --git a/core/Basetype.cc b/core/Basetype.cc
index eba72a6c2e21f481c6147f2e23419a35de46fe39..3d1386ae8ad27783b9955886b93f33d71fe960d5 100644
--- a/core/Basetype.cc
+++ b/core/Basetype.cc
@@ -235,7 +235,9 @@ int Base_Type::begin_xml(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
   collector_fn collector, const char *type_atr, unsigned int flavor2) const
 {
   const int exer = is_exer(flavor);
-  int omit_tag = (indent != 0) // can never omit the tag at the toplevel
+  int omit_tag =
+    // can never omit the tag at the toplevel, except when the type is union
+    (indent != 0 || (flavor2 & THIS_UNION))
     && ( ((flavor & XER_RECOF) // can remove the tag even if not EXER
       && !(exer && (flavor & BXER_EMPTY_ELEM))) // except 26.6, 26.7
       || (exer /*&& */
@@ -335,10 +337,12 @@ int Base_Type::begin_xml(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
 }
 
 void Base_Type::end_xml  (const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
-  unsigned int flavor, int indent, boolean empty) const
+  unsigned int flavor, int indent, boolean empty, unsigned int flavor2) const
 {
   int exer = is_exer(flavor);
-  boolean omit_tag = (indent != 0) // can never omit the tag at the toplevel
+  boolean omit_tag =
+    // can never omit the tag at the toplevel, except when the type is union
+    (indent != 0 || (flavor2 & THIS_UNION))
     && ( ((flavor & XER_RECOF) // can remove the tag even if not EXER
       && !(exer && (flavor & BXER_EMPTY_ELEM))) // except 26.6, 26.7
       || (exer /*&& */
diff --git a/core/Basetype.hh b/core/Basetype.hh
index 3fb85a51606dc20032d71242a2290d465864ccdc..b927adaf832ff80ac0386afef470f2187090fc4e 100644
--- a/core/Basetype.hh
+++ b/core/Basetype.hh
@@ -588,7 +588,7 @@ public:
    * @param[in]  empty true if an empty-element tag is needed
    */
   VIRTUAL_IF_RUNTIME_2 void end_xml  (const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
-    unsigned int flavor, int indent, boolean empty) const;
+    unsigned int flavor, int indent, boolean empty, unsigned int flavor2 = 0) const;
   
   /** Encode JSON.
    * @return encoded length
diff --git a/core/XER.hh b/core/XER.hh
index e4838ab779c38d0665f4078009ee044541b5c653..5904edfbaae9f114d8aeef1af36fb98792ad363e 100644
--- a/core/XER.hh
+++ b/core/XER.hh
@@ -107,7 +107,8 @@ enum XER_flavor {
 
 enum XER_flavor2 {
     USE_NIL_PARENT_TAG = 1U << 0, // Content field has attribute that was read by parent
-    FROM_UNION_USETYPE = 1U << 1 // When the parent of a useUnion field is a union with useType
+    FROM_UNION_USETYPE = 1U << 1, // When the parent of a useUnion field is a union with useType
+    THIS_UNION = 1U << 2 // When the type is a union
 };
 
 /** WHITESPACE actions.
diff --git a/regression_test/XML/EXER-whitepaper/Untagged.ttcnpp b/regression_test/XML/EXER-whitepaper/Untagged.ttcnpp
index a30132a8adf8a185d33930d213727c158e226cdb..ba4930d3d8175159bc1084016ff7d3a23ad6a9fa 100644
--- a/regression_test/XML/EXER-whitepaper/Untagged.ttcnpp
+++ b/regression_test/XML/EXER-whitepaper/Untagged.ttcnpp
@@ -9,6 +9,7 @@
  *   Balasko, Jeno
  *   Baranyi, Botond
  *   Raduly, Csaba
+ *   Szabo, Bence Janos
  *
  ******************************************************************************/
 module Untagged {
@@ -696,7 +697,94 @@ testcase decode_ut_recof() runs on UTA
   CHECK_DECODE(exer_dec_recof, s_recof, r_recof, c_recof);
 }
 
+// ------- untagged top level union
 
+type integer MyInt
+with {
+  variant "element";
+}
+
+type charstring MyChar
+with {
+  variant "element";
+}
+
+type union UntaggedUnion {
+  MyInt i,
+  MyChar c
+} with {
+  variant "untagged";
+}
+
+DECLARE_EXER_ENCODERS(UntaggedUnion, untunion);
+
+const UntaggedUnion c_untunion := { i := 44 };
+
+const universal charstring s_untunion := "<i>44</i>\n\n";
+
+testcase encode_ut_union() runs on UTA
+{
+  CHECK_METHOD(exer_enc_untunion, c_untunion, s_untunion);
+}
+
+testcase decode_ut_union() runs on UTA
+{
+  CHECK_DECODE(exer_dec_untunion, s_untunion, UntaggedUnion, c_untunion);
+}
+
+// ------- untagged top level record of union
+type record of UntaggedUnion UntaggedRecofUnion
+with {
+  variant "untagged";
+}
+
+
+DECLARE_EXER_ENCODERS(UntaggedRecofUnion, untunionrecof);
+
+const UntaggedRecofUnion c_untunionrecof := { { i := 44 }, {c := "asdf"} };
+
+const universal charstring s_untunionrecof :=
+"<UntaggedRecofUnion>\n"&
+"\t<i>44</i>\n"&
+"\t<c>asdf</c>\n"&
+"</UntaggedRecofUnion>\n\n";
+
+testcase encode_ut_union_recof() runs on UTA
+{
+  CHECK_METHOD(exer_enc_untunionrecof, c_untunionrecof, s_untunionrecof);
+}
+
+testcase decode_ut_union_recof() runs on UTA
+{
+  CHECK_DECODE(exer_dec_untunionrecof, s_untunionrecof, UntaggedRecofUnion, c_untunionrecof);
+}
+
+// ------- untagged top level union with nested untagged union
+
+type union UntaggedUnion2 {
+  UntaggedUnion unt,
+  MyInt i,
+  MyChar c
+} with {
+  variant "untagged";
+  variant (unt) "untagged";
+}
+
+DECLARE_EXER_ENCODERS(UntaggedUnion2, untunion2);
+
+const UntaggedUnion2 c_untunion2 := { unt := { i := 44 } };
+
+const universal charstring s_untunion2 := "<i>44</i>\n\n";
+
+testcase encode_ut_union2() runs on UTA
+{
+  CHECK_METHOD(exer_enc_untunion2, c_untunion2, s_untunion2);
+}
+
+testcase decode_ut_union2() runs on UTA
+{
+  CHECK_DECODE(exer_dec_untunion2, s_untunion2, UntaggedUnion2, c_untunion2);
+}
 
 /* * * * * * * * * * * Run it! * * * * * * * * * * */
 
@@ -736,6 +824,15 @@ control {
 
   execute(encode_ut_recof());
   execute(decode_ut_recof());
+
+  execute(encode_ut_union());
+  execute(decode_ut_union());
+
+  execute(encode_ut_union2());
+  execute(decode_ut_union2());
+
+  execute(encode_ut_union_recof());
+  execute(decode_ut_union_recof());
 }
 
 }
diff --git a/regression_test/XML/EXER-whitepaper/Untagged1.ttcnpp b/regression_test/XML/EXER-whitepaper/Untagged1.ttcnpp
index 20aeabe378d8ee558f8fdfa740a9c64f640362c5..31e703b8ca56368303438a6e5efa97fafa0dd9a6 100644
--- a/regression_test/XML/EXER-whitepaper/Untagged1.ttcnpp
+++ b/regression_test/XML/EXER-whitepaper/Untagged1.ttcnpp
@@ -8,6 +8,7 @@
  * Contributors:
  *   Balasko, Jeno
  *   Raduly, Csaba
+ *   Szabo, Bence Janos
  *
  ******************************************************************************/
 module Untagged1 {
@@ -336,7 +337,7 @@ testcase tc_dec_ints() runs on Unt
   CHECK_DECODE(exer_dec_ints, estr_twoints, Ints, twoints);
 }
 
-// Untagged at toplevel (ignored) for union
+// not Untagged at toplevel for union
 // HM71472
 type union Choice
 {
@@ -345,7 +346,6 @@ type union Choice
 }
 with {
   variant "element"
-  variant "untagged"
   variant "namespace as 'foo:bar' prefix 'baz'";
 }
 
@@ -375,6 +375,83 @@ testcase tc_dec_choice() runs on Unt
   CHECK_DECODE(exer_dec_ch, estr_itg, Choice, itg);
 }
 
+// Untagged at toplevel for union
+// HM71472
+type union Choice2
+{
+  integer answer,
+  charstring s
+}
+with {
+  variant "element"
+  variant "untagged"
+  // the namespace as variant will be not visible because it will be lost due to
+  // untagged
+  variant "namespace as 'foo:bar' prefix 'baz'";
+}
+
+DECLARE_XER_ENCODERS(Choice2, ch2);
+DECLARE_EXER_ENCODERS(Choice2, ch2);
+
+const Choice2 itg2 := { answer := 42 };
+const universal charstring bstr_itg2 :=
+"<Choice2>\n" &
+"\t<answer>42</answer>\n" &
+"</Choice2>\n\n";
+const universal charstring estr_itg2 :=
+"<answer>42</answer>\n\n";
+
+
+testcase tc_enc_choice2() runs on Unt
+{
+  CHECK_METHOD(bxer_enc_ch2, itg2, bstr_itg2);
+  CHECK_METHOD(exer_enc_ch2, itg2, estr_itg2);
+}
+
+testcase tc_dec_choice2() runs on Unt
+{
+  CHECK_DECODE(bxer_dec_ch2, bstr_itg2, Choice2, itg2);
+  CHECK_DECODE(exer_dec_ch2, estr_itg2, Choice2, itg2);
+}
+
+// Untagged at toplevel for union
+// HM71472
+type union Choice3
+{
+  integer answer,
+  charstring s
+}
+with {
+  variant "element"
+  variant "untagged"
+  variant (answer) "namespace as 'foo:bar' prefix 'baz'";
+  variant (answer) "element";
+}
+
+DECLARE_XER_ENCODERS(Choice3, ch3);
+DECLARE_EXER_ENCODERS(Choice3, ch3);
+
+const Choice3 itg3 := { answer := 42 };
+const universal charstring bstr_itg3 :=
+"<Choice3>\n" &
+"\t<answer>42</answer>\n" &
+"</Choice3>\n\n";
+const universal charstring estr_itg3 :=
+"<baz:answer xmlns:baz='foo:bar'>42</baz:answer>\n\n";
+
+
+testcase tc_enc_choice3() runs on Unt
+{
+  CHECK_METHOD(bxer_enc_ch3, itg3, bstr_itg3);
+  CHECK_METHOD(exer_enc_ch3, itg3, estr_itg3);
+}
+
+testcase tc_dec_choice3() runs on Unt
+{
+  CHECK_DECODE(bxer_dec_ch3, bstr_itg3, Choice3, itg3);
+  CHECK_DECODE(exer_dec_ch3, estr_itg3, Choice3, itg3);
+}
+
 // HM80553
 
 type record AddRequest
@@ -476,6 +553,12 @@ control {
   execute(tc_enc_choice());
   execute(tc_dec_choice());
 
+  execute(tc_enc_choice2());
+  execute(tc_dec_choice2());
+  
+  execute(tc_enc_choice3());
+  execute(tc_dec_choice3());
+
   execute(tc_enc_widget());
   execute(tc_dec_widget());
 }