diff --git a/compiler2/Setting.cc b/compiler2/Setting.cc
index 7ac8fc6e8e6828dc0699cc46d3dc0dbb67fce6bd..01b8a0908922f93786e40e7166bf779222752ba2 100644
--- a/compiler2/Setting.cc
+++ b/compiler2/Setting.cc
@@ -963,6 +963,10 @@ namespace Common {
     return false;
   }
 
+  bool ReferenceChain::is_error_reporting_on() const {
+    return report_error;
+  }
+
   void ReferenceChain::set_error_reporting(bool enable) {
     report_error = enable;
   }
diff --git a/compiler2/Setting.hh b/compiler2/Setting.hh
index a105bbe173d4f7964fdbbe347ae4dc6f22e9d109..e59ce8cb8fe9e7cc444b704cea2c6dc706535c7a 100644
--- a/compiler2/Setting.hh
+++ b/compiler2/Setting.hh
@@ -823,6 +823,8 @@ public:
     /** Adds a new string. Returns true on success or false if \a s already
      * exists on chain. */
     bool add(const string& s);
+    /** Returns the state of the automatic error reporting. */
+    bool is_error_reporting_on() const;
     /** Turns on or off the automatic error reporting. */
     void set_error_reporting(bool enable);
     /** Returns the number of errors found after the last
diff --git a/compiler2/Type_chk.cc b/compiler2/Type_chk.cc
index 06d791a99ef35473412c132133127ac80516f2c4..740a12a0c58cc9744008d128dd9f049052262222 100644
--- a/compiler2/Type_chk.cc
+++ b/compiler2/Type_chk.cc
@@ -3846,8 +3846,14 @@ void Type::chk_recursions(ReferenceChain& refch)
     break;
   case T_CHOICE_A:
   case T_CHOICE_T: {
-    refch.set_error_reporting(false);
-    refch.mark_error_state();
+    // we could be inside a different union that has already turned error reporting off;
+    // don't report anything in that case, let the first union handle it
+    bool error_reporting_not_handled = refch.is_error_reporting_on();
+    if (error_reporting_not_handled) {
+      refch.set_error_reporting(false);
+      refch.mark_error_state();
+    }
+
     for (size_t i = 0; i < t->get_nof_comps(); ++i) {
       refch.mark_state();
       CompField* cf = t->get_comp_byIndex(i);
@@ -3855,12 +3861,14 @@ void Type::chk_recursions(ReferenceChain& refch)
       refch.prev_state();
     }
 
-    if (refch.nof_errors() == t->get_nof_comps()) {
-      refch.report_errors();
-    }
+    if (error_reporting_not_handled) {
+      if (refch.nof_errors() == t->get_nof_comps()) {
+        refch.report_errors();
+      }
 
-    refch.prev_error_state();
-    refch.set_error_reporting(true);
+      refch.prev_error_state();
+      refch.set_error_reporting(true);
+    }
     break;
   }
   case T_ANYTYPE:
diff --git a/compiler2/asn1/AST_asn1.cc b/compiler2/asn1/AST_asn1.cc
index a130ffbeb0c483bc3c965733d3465c557826c853..7e50c502611c726ba85f496f82dd04d3b844ee00 100644
--- a/compiler2/asn1/AST_asn1.cc
+++ b/compiler2/asn1/AST_asn1.cc
@@ -1472,12 +1472,17 @@ namespace Asn {
             && (t_ref->refers_to_st(Setting::S_T, refch)
                 || t_ref->refers_to_st(Setting::S_VS, refch))
             ) {
-      Type *t_type=new Type(Type::T_REFD, t_ref);
-      t_type->set_location(*t_ref);
-      ass=new Ass_T(id->clone(), ass_pard, t_type);
-      ass_pard=0;
-      right=0;
-      asstype=A_TYPE;
+      // 't_ref->refers_to_st()' could have already completed the classification
+      // of this assignment (in case of recursive types);
+      // only create a new type and type assignment, if they're not already set
+      if (ass == NULL) {
+        Type *t_type=new Type(Type::T_REFD, t_ref);
+        t_type->set_location(*t_ref);
+        ass=new Ass_T(id->clone(), ass_pard, t_type);
+        ass_pard=0;
+        right=0;
+        asstype=A_TYPE;
+      }
     }
     else if(id->isvalid_asn_objsetref()
             && (t_ref=dynamic_cast<Ref_simple*>(left))
diff --git a/compiler2/asn1/Ref.cc b/compiler2/asn1/Ref.cc
index 4aba5b6021a6b9c969f386fc736100c44169e35e..02897f680598cb819cd82c8c13899cb276acf6dc 100644
--- a/compiler2/asn1/Ref.cc
+++ b/compiler2/asn1/Ref.cc
@@ -105,6 +105,7 @@ namespace Asn {
       block=0;
       return 0;
     }
+
     Ass_pard *ass_pard=parass->get_ass_pard();
     if(!ass_pard) {
       /* error: this is not a parameterized assignment */
@@ -190,6 +191,11 @@ namespace Asn {
     const Identifier& new_ass_id = new_ass->get_id();
     const string& new_ass_dispname = new_ass_id.get_dispname();
 
+    ref_ds=new Ref_defd_simple(new Identifier(my_mod->get_modid()),
+                               new Identifier(new_ass_id));
+    ref_ds->set_fullname(get_fullname());
+    ref_ds->set_my_scope(my_mod);
+
     asss->set_right_scope(my_scope);
     asss->set_parent_scope(parass->get_my_scope());
     asss->set_parent_scope_gen(my_scope);
@@ -203,15 +209,11 @@ namespace Asn {
     new_ass->set_location(*this);
     new_ass->set_dontgen();
     new_ass->chk();
-    
+
     if (Common::Assignment::A_TYPE == new_ass->get_asstype()) {
       new_ass->get_Type()->set_pard_type_instance();
     }
-    
-    ref_ds=new Ref_defd_simple(new Identifier(my_mod->get_modid()),
-                               new Identifier(new_ass_id));
-    ref_ds->set_fullname(get_fullname());
-    ref_ds->set_my_scope(my_mod);
+
     return ref_ds;
   }
 
diff --git a/compiler2/subtype.cc b/compiler2/subtype.cc
index 88722dcbaad7e225273a1623508dae71e167b615..23a7c3bdf8c5f478422edf3522a1833aa741438c 100644
--- a/compiler2/subtype.cc
+++ b/compiler2/subtype.cc
@@ -190,6 +190,8 @@ SubtypeConstraint::SubtypeConstraint(subtype_t st)
   case ST_SETOF:
     recof_st = NULL;
     break;
+  case ST_ERROR:
+    break;
   default:
     FATAL_ERROR("SubtypeConstraint::SubtypeConstraint()");
   }
diff --git a/compiler2/ttcn3/AST_ttcn3.cc b/compiler2/ttcn3/AST_ttcn3.cc
index 723cba45e9394879bef0de188ffec925501122c7..b6d65da136ab45a59572e8bd7c878ff701c8eaf5 100644
--- a/compiler2/ttcn3/AST_ttcn3.cc
+++ b/compiler2/ttcn3/AST_ttcn3.cc
@@ -4037,7 +4037,7 @@ namespace Ttcn {
   Def_Const::Def_Const(Identifier *p_id, Type *p_type, Value *p_value)
     : Definition(A_CONST, p_id)
   {
-    if (!p_type || !p_value) FATAL_ERROR("Ttcn::Def_Const::Def_Const()");
+    if (!p_type) FATAL_ERROR("Ttcn::Def_Const::Def_Const()");
     type=p_type;
     type->set_ownertype(Type::OT_CONST_DEF, this);
     value=p_value;
@@ -4059,14 +4059,18 @@ namespace Ttcn {
   {
     Definition::set_fullname(p_fullname);
     type->set_fullname(p_fullname + ".<type>");
-    value->set_fullname(p_fullname);
+    if (value != NULL) {
+      value->set_fullname(p_fullname);
+    }
   }
 
   void Def_Const::set_my_scope(Scope *p_scope)
   {
     Definition::set_my_scope(p_scope);
     type->set_my_scope(p_scope);
-    value->set_my_scope(p_scope);
+    if (value != NULL) {
+      value->set_my_scope(p_scope);
+    }
   }
 
   Setting *Def_Const::get_Setting()
@@ -4101,8 +4105,14 @@ namespace Ttcn {
       id->get_dispname().c_str());
     type->set_genname(_T_, get_genname());
     type->chk();
-    value->set_my_governor(type);
-    type->chk_this_value_ref(value);
+
+    if (value != NULL) {
+      value->set_my_governor(type);
+      type->chk_this_value_ref(value);
+    }
+    else if (!my_scope->is_class_scope()) {
+      error("Missing initial value");
+    }
     checked=true;
     if (w_attrib_path) {
       w_attrib_path->chk_global_attrib(true);
@@ -4134,20 +4144,20 @@ namespace Ttcn {
         t->get_typename().c_str());
       break;
     default:
-      value_under_check = true;
-        type->chk_this_value(value, 0, Type::EXPECTED_STATIC_VALUE, WARNING_FOR_INCOMPLETE,
-        OMIT_NOT_ALLOWED, SUB_CHK, has_implicit_omit_attr());
-      value_under_check = false;
-      erroneous_attrs = chk_erroneous_attr(w_attrib_path, type, get_my_scope(),
-        get_fullname(), false);
-      if (erroneous_attrs) value->add_err_descr(NULL, erroneous_attrs->get_err_descr());
-    {
-      ReferenceChain refch(type, "While checking embedded recursions");
-      value->chk_recursions(refch);
-    }
+      if (value != NULL) {
+        value_under_check = true;
+          type->chk_this_value(value, 0, Type::EXPECTED_STATIC_VALUE, WARNING_FOR_INCOMPLETE,
+          OMIT_NOT_ALLOWED, SUB_CHK, has_implicit_omit_attr());
+        value_under_check = false;
+        erroneous_attrs = chk_erroneous_attr(w_attrib_path, type, get_my_scope(),
+          get_fullname(), false);
+        if (erroneous_attrs) value->add_err_descr(NULL, erroneous_attrs->get_err_descr());
+        ReferenceChain refch(type, "While checking embedded recursions");
+        value->chk_recursions(refch);
+      }
       break;
     }
-    if (!semantic_check_only) {
+    if (!semantic_check_only && value != NULL) {
       value->set_genname_prefix("const_");
       value->set_genname_recursive(get_genname());
       value->set_code_section(GovernedSimple::CS_PRE_INIT);
@@ -4167,7 +4177,9 @@ namespace Ttcn {
       return false;
     }
     Def_Const *p_def_const = dynamic_cast<Def_Const*>(p_def);
-    if (!p_def_const) FATAL_ERROR("Def_Const::chk_identical()");
+    if (p_def_const == NULL || value == NULL || p_def_const->value == NULL) {
+      FATAL_ERROR("Def_Const::chk_identical()");
+    }
     if (!type->is_identical(p_def_const->type)) {
       const char *dispname_str = id->get_dispname().c_str();
       type->error("Local constant `%s' has type `%s', but the constant "
@@ -4193,15 +4205,20 @@ namespace Ttcn {
     const_def cdef;
     Code::init_cdef(&cdef);
     bool in_class = my_scope->is_class_scope();
-    type->generate_code_object(&cdef, value, in_class);
-    if (value->is_unfoldable()) {
-    cdef.post = update_location_object(cdef.post);
-    cdef.post = value->generate_code_init(cdef.post,
-      value->get_lhs_name().c_str());
-    } else {
-    cdef.init = update_location_object(cdef.init);
-    cdef.init = value->generate_code_init(cdef.init,
-      value->get_lhs_name().c_str());
+    if (value != NULL) {
+      type->generate_code_object(&cdef, value, in_class);
+      if (value->is_unfoldable()) {
+      cdef.post = update_location_object(cdef.post);
+      cdef.post = value->generate_code_init(cdef.post,
+        value->get_lhs_name().c_str());
+      } else {
+      cdef.init = update_location_object(cdef.init);
+      cdef.init = value->generate_code_init(cdef.init,
+        value->get_lhs_name().c_str());
+      }
+    }
+    else {
+      type->generate_code_object(&cdef, my_scope, get_genname(), "const_", false, false, true);
     }
     Code::merge_cdef(target, &cdef, in_class);
     Code::free_cdef(&cdef);
@@ -4214,6 +4231,9 @@ namespace Ttcn {
 
   char *Def_Const::generate_code_str(char *str)
   {
+    if (value == NULL) {
+      FATAL_ERROR("Def_Const::generate_code_str");
+    }
     const string& t_genname = get_genname();
     const char *genname_str = t_genname.c_str();
     if (value->has_single_expr()) {
@@ -4237,6 +4257,9 @@ namespace Ttcn {
 
   void Def_Const::ilt_generate_code(ILT *ilt)
   {
+    if (value == NULL) {
+      FATAL_ERROR("Def_Const::ilt_generate_code");
+    }
     const string& t_genname = get_genname();
     const char *genname_str = t_genname.c_str();
     char*& def=ilt->get_out_def();
@@ -4257,7 +4280,9 @@ namespace Ttcn {
   {
     DEBUG(level, "Constant: %s @%p", id->get_dispname().c_str(), static_cast<const void*>(this));
     type->dump(level + 1);
-    value->dump(level + 1);
+    if (value != NULL) {
+      value->dump(level + 1);
+    }
   }
 
   // =================================
@@ -4733,7 +4758,7 @@ namespace Ttcn {
     body(p_body), template_restriction(p_template_restriction),
     gen_restriction_check(false)
   {
-    if (!p_type || !p_body) FATAL_ERROR("Ttcn::Def_Template::Def_Template()");
+    if (!p_type) FATAL_ERROR("Ttcn::Def_Template::Def_Template()");
     type->set_ownertype(Type::OT_TEMPLATE_DEF, this);
     if (fp_list) fp_list->set_my_def(this);
   }
@@ -4758,7 +4783,9 @@ namespace Ttcn {
     if (fp_list) fp_list->set_fullname(p_fullname + ".<formal_par_list>");
     if (derived_ref)
       derived_ref->set_fullname(p_fullname + ".<derived_reference>");
-    body->set_fullname(p_fullname);
+    if (body != NULL) {
+      body->set_fullname(p_fullname);
+    }
   }
 
   void Def_Template::set_my_scope(Scope *p_scope)
@@ -4771,8 +4798,12 @@ namespace Ttcn {
     if (derived_ref) derived_ref->set_my_scope(&bridgeScope);
     if (fp_list) {
       fp_list->set_my_scope(&bridgeScope);
-      body->set_my_scope(fp_list);
-    } else body->set_my_scope(&bridgeScope);
+      if (body != NULL) {
+        body->set_my_scope(fp_list);
+      }
+    } else if (body != NULL) {
+      body->set_my_scope(&bridgeScope);
+    }
   }
 
   Setting *Def_Template::get_Setting()
@@ -4827,21 +4858,29 @@ namespace Ttcn {
       fp_list->chk(asstype);
       if (local_scope) error("Parameterized local template `%s' not supported",
         id->get_dispname().c_str());
-      body->set_formalparlist(fp_list);
+      if (body != NULL) {
+        body->set_formalparlist(fp_list);
+      }
     }
 
     // Merge the elements of "all from" into the list
-    body->flatten(false);
+    if (body != NULL) {
+      body->flatten(false);
 
-    body->set_my_governor(type);
+      body->set_my_governor(type);
 
-    if (body->get_templatetype() == Template::CSTR_PATTERN &&
-      type->get_type_refd_last()->get_typetype() == Type::T_USTR) {
-      body->set_templatetype(Template::USTR_PATTERN);
-      body->get_ustr_pattern()->set_pattern_type(PatternString::USTR_PATTERN);
+      if (body->get_templatetype() == Template::CSTR_PATTERN &&
+        type->get_type_refd_last()->get_typetype() == Type::T_USTR) {
+        body->set_templatetype(Template::USTR_PATTERN);
+        body->get_ustr_pattern()->set_pattern_type(PatternString::USTR_PATTERN);
+      }
+
+      type->chk_this_template_ref(body);
+    }
+    else if (!my_scope->is_class_scope()) {
+      error("Missing template body");
     }
 
-    type->chk_this_template_ref(body);
     Type *t = type->get_type_refd_last();
     if (t->get_typetype() == Type::T_PORT) {
       error("Template cannot be defined for port type `%s'",
@@ -4851,66 +4890,70 @@ namespace Ttcn {
       error("Template cannot be defined for class type `%s'",
         t->get_typename().c_str());
     }
+    type->chk_this_template_incorrect_field();
     chk_modified();
     chk_recursive_derivation();
-    type->chk_this_template_generic(body,
-      derived_ref != NULL ? INCOMPLETE_ALLOWED : WARNING_FOR_INCOMPLETE,
-      OMIT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK,
-      IMPLICIT_OMIT == has_implicit_omit_attr() ? IMPLICIT_OMIT : NOT_IMPLICIT_OMIT, 0);
-    type->chk_this_template_incorrect_field();
-    erroneous_attrs = chk_erroneous_attr(w_attrib_path, type, get_my_scope(),
-      get_fullname(), false);
-    if (erroneous_attrs) body->add_err_descr(NULL, erroneous_attrs->get_err_descr());
 
-    {
-      ReferenceChain refch(type, "While checking embedded recursions");
-      body->chk_recursions(refch);
-    }
-    if (template_restriction!=TR_NONE) {
-      Error_Context ec(this, "While checking template restriction `%s'",
-                       Template::get_restriction_name(template_restriction));
-      gen_restriction_check =
-        body->chk_restriction("template definition", template_restriction, body);
-      if (fp_list && template_restriction!=TR_PRESENT) {
-        size_t nof_fps = fp_list->get_nof_fps();
-        for (size_t i=0; i<nof_fps; i++) {
-          FormalPar* fp = fp_list->get_fp_byIndex(i);
-          // if formal par is not template then skip restriction checking,
-          // templates can have only `in' parameters
-          if (fp->get_asstype()!=A_PAR_TEMPL_IN) continue;
-          template_restriction_t fp_tr = fp->get_template_restriction();
-          switch (template_restriction) {
-          case TR_VALUE:
-          case TR_OMIT:
-            switch (fp_tr) {
+    if (body != NULL) {
+      type->chk_this_template_generic(body,
+        derived_ref != NULL ? INCOMPLETE_ALLOWED : WARNING_FOR_INCOMPLETE,
+        OMIT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK,
+        IMPLICIT_OMIT == has_implicit_omit_attr() ? IMPLICIT_OMIT : NOT_IMPLICIT_OMIT, 0);
+      erroneous_attrs = chk_erroneous_attr(w_attrib_path, type, get_my_scope(),
+        get_fullname(), false);
+      if (erroneous_attrs) body->add_err_descr(NULL, erroneous_attrs->get_err_descr());
+      {
+        ReferenceChain refch(type, "While checking embedded recursions");
+        body->chk_recursions(refch);
+      }
+
+      if (template_restriction!=TR_NONE) {
+        Error_Context ec(this, "While checking template restriction `%s'",
+                         Template::get_restriction_name(template_restriction));
+        gen_restriction_check =
+          body->chk_restriction("template definition", template_restriction, body);
+        if (fp_list && template_restriction!=TR_PRESENT) {
+          size_t nof_fps = fp_list->get_nof_fps();
+          for (size_t i=0; i<nof_fps; i++) {
+            FormalPar* fp = fp_list->get_fp_byIndex(i);
+            // if formal par is not template then skip restriction checking,
+            // templates can have only `in' parameters
+            if (fp->get_asstype()!=A_PAR_TEMPL_IN) continue;
+            template_restriction_t fp_tr = fp->get_template_restriction();
+            switch (template_restriction) {
             case TR_VALUE:
             case TR_OMIT:
-              // allowed
-              break;
-            case TR_PRESENT:
-              fp->error("Formal parameter with template restriction `%s' "
-                "not allowed here", Template::get_restriction_name(fp_tr));
-              break;
-            case TR_NONE:
-              fp->error("Formal parameter without template restriction "
-                "not allowed here");
+              switch (fp_tr) {
+              case TR_VALUE:
+              case TR_OMIT:
+                // allowed
+                break;
+              case TR_PRESENT:
+                fp->error("Formal parameter with template restriction `%s' "
+                  "not allowed here", Template::get_restriction_name(fp_tr));
+                break;
+              case TR_NONE:
+                fp->error("Formal parameter without template restriction "
+                  "not allowed here");
+                break;
+              default:
+                FATAL_ERROR("Ttcn::Def_Template::chk()");
+              }
               break;
             default:
               FATAL_ERROR("Ttcn::Def_Template::chk()");
             }
-            break;
-          default:
-            FATAL_ERROR("Ttcn::Def_Template::chk()");
           }
         }
       }
-    }
-    if (!semantic_check_only) {
-      if (fp_list) fp_list->set_genname(t_genname);
-      body->set_genname_prefix("template_");
-      body->set_genname_recursive(t_genname);
-      body->set_code_section(fp_list ? GovernedSimple::CS_INLINE :
-        GovernedSimple::CS_POST_INIT);
+
+      if (!semantic_check_only) {
+        if (fp_list) fp_list->set_genname(t_genname);
+        body->set_genname_prefix("template_");
+        body->set_genname_recursive(t_genname);
+        body->set_code_section(fp_list ? GovernedSimple::CS_INLINE :
+          GovernedSimple::CS_POST_INIT);
+      }
     }
 
   }
@@ -4974,7 +5017,9 @@ namespace Ttcn {
       return;
     }
     base_template = dynamic_cast<Def_Template*>(ass);
-    if (!base_template) FATAL_ERROR("Def_Template::chk_modified()");
+    if (base_template == NULL || body == NULL) {
+      FATAL_ERROR("Def_Template::chk_modified()");
+    }
     Type *base_type = base_template->get_Type();
     TypeCompatInfo info_base(my_scope->get_scope_mod(), type, base_type, true,
                              false, true);
@@ -5091,7 +5136,7 @@ namespace Ttcn {
   void Def_Template::generate_code(output_struct *target, bool)
   {
     type->generate_code(target);
-    if (body->get_err_descr() != NULL && body->get_err_descr()->has_descr(NULL)) {
+    if (body != NULL && body->get_err_descr() != NULL && body->get_err_descr()->has_descr(NULL)) {
         target->functions.post_init = body->get_err_descr()->generate_code_init_str(
           NULL, target->functions.post_init, body->get_lhs_name());
     }
@@ -5188,56 +5233,61 @@ namespace Ttcn {
       const_def cdef;
       Code::init_cdef(&cdef);
       bool in_class = my_scope->is_class_scope();
-      type->generate_code_object(&cdef, body, in_class);
-      cdef.init = update_location_object(cdef.init);
-      if (base_template) {
-        // modified template
-        if (base_template->my_scope->get_scope_mod_gen() ==
-            my_scope->get_scope_mod_gen()) {
-          // if the base template is in the same module its body has to be
-          // initialized first
-          cdef.init = base_template->body->generate_code_init(cdef.init,
-            base_template->body->get_lhs_name().c_str());
+      if (body != NULL) {
+        type->generate_code_object(&cdef, body, in_class);
+        cdef.init = update_location_object(cdef.init);
+        if (base_template) {
+          // modified template
+          if (base_template->my_scope->get_scope_mod_gen() ==
+              my_scope->get_scope_mod_gen()) {
+            // if the base template is in the same module its body has to be
+            // initialized first
+            cdef.init = base_template->body->generate_code_init(cdef.init,
+              base_template->body->get_lhs_name().c_str());
+          }
+          if (use_runtime_2 && body->get_needs_conversion()) {
+            Type *body_type = body->get_my_governor()->get_type_refd_last();
+            Type *base_type = base_template->body->get_my_governor()
+              ->get_type_refd_last();
+            if (!body_type || !base_type)
+              FATAL_ERROR("Def_Template::generate_code()");
+            const string& tmp_id = body->get_temporary_id();
+            const char *tmp_id_str = tmp_id.c_str();
+            // base template initialization
+            cdef.init = mputprintf(cdef.init,
+              "%s %s;\n"
+              "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
+              "and `%s' are not compatible at run-time\");\n"
+              "%s = %s;\n",
+              body_type->get_genname_template(my_scope).c_str(), tmp_id_str,
+              TypeConv::get_conv_func(base_type, body_type, my_scope
+              ->get_scope_mod()).c_str(), tmp_id_str, base_template
+              ->get_genname_from_scope(my_scope).c_str(), base_type
+              ->get_typename().c_str(), body_type->get_typename().c_str(),
+              body->get_lhs_name().c_str(), tmp_id_str);
+          } else {
+            cdef.init = mputprintf(cdef.init, "%s = %s;\n",
+              body->get_lhs_name().c_str(),
+              base_template->get_genname_from_scope(my_scope).c_str());
+          }
         }
-        if (use_runtime_2 && body->get_needs_conversion()) {
-          Type *body_type = body->get_my_governor()->get_type_refd_last();
-          Type *base_type = base_template->body->get_my_governor()
-            ->get_type_refd_last();
-          if (!body_type || !base_type)
-            FATAL_ERROR("Def_Template::generate_code()");
-          const string& tmp_id = body->get_temporary_id();
-          const char *tmp_id_str = tmp_id.c_str();
-          // base template initialization
-          cdef.init = mputprintf(cdef.init,
-            "%s %s;\n"
-            "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
-            "and `%s' are not compatible at run-time\");\n"
-            "%s = %s;\n",
-            body_type->get_genname_template(my_scope).c_str(), tmp_id_str,
-            TypeConv::get_conv_func(base_type, body_type, my_scope
-            ->get_scope_mod()).c_str(), tmp_id_str, base_template
-            ->get_genname_from_scope(my_scope).c_str(), base_type
-            ->get_typename().c_str(), body_type->get_typename().c_str(),
-            body->get_lhs_name().c_str(), tmp_id_str);
-        } else {
-          cdef.init = mputprintf(cdef.init, "%s = %s;\n",
-            body->get_lhs_name().c_str(),
-            base_template->get_genname_from_scope(my_scope).c_str());
+        if (use_runtime_2 && TypeConv::needs_conv_refd(body))
+          cdef.init = TypeConv::gen_conv_code_refd(cdef.init,
+            body->get_lhs_name().c_str(), body);
+        else
+          cdef.init = body->generate_code_init(cdef.init,
+            body->get_lhs_name().c_str());
+        if (template_restriction != TR_NONE && gen_restriction_check)
+          cdef.init = Template::generate_restriction_check_code(cdef.init,
+            body->get_lhs_name().c_str(), template_restriction);
+        if (body->get_err_descr() != NULL && body->get_err_descr()->has_descr(NULL)) {
+          cdef.init = mputprintf(cdef.init, "%s.set_err_descr(&%s_%lu_err_descr);\n",
+            body->get_lhs_name().c_str(), body->get_lhs_name().c_str(),
+            static_cast<unsigned long>( body->get_err_descr()->get_descr_index(NULL) ));
         }
       }
-      if (use_runtime_2 && TypeConv::needs_conv_refd(body))
-        cdef.init = TypeConv::gen_conv_code_refd(cdef.init,
-          body->get_lhs_name().c_str(), body);
-      else
-        cdef.init = body->generate_code_init(cdef.init,
-          body->get_lhs_name().c_str());
-      if (template_restriction != TR_NONE && gen_restriction_check)
-        cdef.init = Template::generate_restriction_check_code(cdef.init,
-          body->get_lhs_name().c_str(), template_restriction);
-      if (body->get_err_descr() != NULL && body->get_err_descr()->has_descr(NULL)) {
-        cdef.init = mputprintf(cdef.init, "%s.set_err_descr(&%s_%lu_err_descr);\n",
-          body->get_lhs_name().c_str(), body->get_lhs_name().c_str(),
-          static_cast<unsigned long>( body->get_err_descr()->get_descr_index(NULL) ));
+      else { // no template body
+        type->generate_code_object(&cdef, my_scope, get_genname(), "template_", true, false, true);
       }
       char*& header = in_class ? target->header.class_defs : target->header.global_vars;
       header = mputstr(header, cdef.decl);
@@ -5255,6 +5305,9 @@ namespace Ttcn {
 
   char *Def_Template::generate_code_str(char *str)
   {
+    if (body == NULL) {
+      FATAL_ERROR("Def_Template::generate_code_str");
+    }
     if (fp_list) {
       const char *dispname_str = id->get_dispname().c_str();
       NOTSUPP("Code generation for parameterized local template `%s'",
@@ -5322,6 +5375,9 @@ namespace Ttcn {
 
   void Def_Template::ilt_generate_code(ILT *ilt)
   {
+    if (body == NULL) {
+      FATAL_ERROR("Def_Template::ilt_generate_code");
+    }
     char*& def=ilt->get_out_def();
     char*& init=ilt->get_out_branches();
     if (fp_list) {
@@ -5361,7 +5417,9 @@ namespace Ttcn {
       DEBUG(level + 1, "restriction: %s",
         Template::get_restriction_name(template_restriction));
     type->dump(level + 1);
-    body->dump(level + 1);
+    if (body != NULL) {
+      body->dump(level + 1);
+    }
   }
 
   // =================================
@@ -7032,7 +7090,6 @@ namespace Ttcn {
         " in clause 16.1.4 of the TTCN-3 core language standard (ES 201 873-1)",
         id->get_dispname().c_str());
     }
-    ClassTypeBody* my_class = my_scope->get_scope_class();
 
     // `runs on' clause and `port' clause are mutually exclusive
     if (runs_on_ref && port_ref) {
diff --git a/compiler2/ttcn3/compiler.y b/compiler2/ttcn3/compiler.y
index 4719104158dd8befd6b65aef49ba677a19423d52..497705f0b25b64873f72db4be05ddc266335a814 100644
--- a/compiler2/ttcn3/compiler.y
+++ b/compiler2/ttcn3/compiler.y
@@ -2015,12 +2015,12 @@ DynamicMatch
 %left '*' '/' ModKeyword RemKeyword
 %left UnarySign
 
-%expect 92
+%expect 93
 
 %start GrammarRoot
 
 /*
-XXX Source of conflicts (92 S/R):
+XXX Source of conflicts (93 S/R):
 
 1.) 13 conflicts in one state
 The Expression after 'return' keyword is optional in ReturnStatement.
@@ -2028,7 +2028,7 @@ For 13 tokens the parser cannot decide whether the token is a part of
 the return expression (shift) or it is the beginning of the next statement
 (reduce).
 
-2.) 14 distinct states, each with one conflict caused by token '['
+2.) 15 distinct states, each with one conflict caused by token '['
 The local definitions in altsteps can be followed immediately by the guard
 expression. When the parser sees the '[' token it cannot decide whether it
 belongs to the local definition as array dimension or array subreference
@@ -2048,6 +2048,7 @@ The situations are the following:
 - var t v := this.function(...) <here> [
 - var t v := super.function(...) <here> [
 - var t v := value<subrefs> <here> [
+- const t c <here> [
 
 3.) 1 conflict
 The sequence identifier.objid can be either the beginning of a module name
@@ -3926,6 +3927,13 @@ SingleConstDef: // 90
     $$.initial_value = $4;
     $$.yyloc = @$;
   }
+| IDentifier optArrayDef
+  {
+    $$.id = $1;
+    $$.arrays = $2;
+    $$.initial_value = NULL;
+    $$.yyloc = @$;
+  }
 ;
 
 FunctionTypeDef:
@@ -3975,6 +3983,11 @@ TemplateDef: // 93
     $$ = new Def_Template($2, $4.name, $4.type, $4.fp_list, $5, $7);
     $$->set_location(infile, @$);
   }
+| TemplateKeyword optTemplateRestriction optLazyOrFuzzyModifier BaseTemplate
+  {
+    $$ = new Def_Template($2, $4.name, $4.type, $4.fp_list, NULL, NULL);
+    $$->set_location(infile, @$);
+  }
 ;
 
 BaseTemplate: // 94
@@ -4003,7 +4016,7 @@ DerivedDef: // 97
 ;
 
 optTemplateFormalParList:
-  /* empty */ optError { $$ = 0; }
+  /* empty */ { $$ = 0; }
 | '(' TemplateFormalParList optError ')'
   {
     $$ = $2;