diff --git a/compiler2/Code.cc b/compiler2/Code.cc
index aaeca10944df27b80c83c9826c1460a08a7e2a46..67f1911eb949f845eb7a69603274df3a86ae21ef 100644
--- a/compiler2/Code.cc
+++ b/compiler2/Code.cc
@@ -83,7 +83,8 @@ namespace Common {
       output->intervals.static_function_bodies = NULL;
     }
     output->temp.constructor_init = NULL;
-    output->temp.constructor = NULL;
+    output->temp.constructor_preamble = NULL;
+    output->temp.constructor_block = NULL;
   }
 
   void Code::merge_output(output_struct *dest, output_struct *src)
@@ -180,7 +181,7 @@ namespace Common {
     Free(output->intervals.static_conversion_function_bodies);
     Free(output->intervals.static_function_bodies);
     Free(output->temp.constructor_init);
-    Free(output->temp.constructor);
+    Free(output->temp.constructor_preamble);
     init_output(output, TRUE);
   }
 
@@ -199,9 +200,9 @@ namespace Common {
     header = mputstr(header, cdef->decl);
     char*& source = in_class ? dest->temp.constructor_init : dest->source.global_vars;
     source = mputstr(source, cdef->def);
-    char*& pre_init = in_class ? dest->temp.constructor : dest->functions.pre_init;
+    char*& pre_init = in_class ? dest->temp.constructor_preamble : dest->functions.pre_init;
     pre_init = mputstr(pre_init, cdef->init);
-    char*& post_init = in_class ? dest->temp.constructor : dest->functions.post_init;
+    char*& post_init = in_class ? dest->temp.constructor_preamble : dest->functions.post_init;
     post_init = mputstr(post_init, cdef->post);
   }
 
diff --git a/compiler2/Identifier.cc b/compiler2/Identifier.cc
index 3ba27aa3ffa5181b85ff7523e806aa49129287a8..905bd39688adcc5e7772f6430c4b11a30873283c 100644
--- a/compiler2/Identifier.cc
+++ b/compiler2/Identifier.cc
@@ -458,7 +458,6 @@ namespace Common {
     {"bitand_", "bitand", "bitand"},
     {"bitor_", "bitor", "bitor"},
     {"bool_", "bool", "bool"},
-    {"class_", "class", "class"},
     {"compl_", "compl", "compl"},
     {"delete_", "delete", "delete"},
     {"double_", "double", "double"},
@@ -500,12 +499,14 @@ namespace Common {
     {"case__", "case", "case_"},
     {"catch__", "catch", "catch_"},
     {"char__", "char", "char_"},
+    {"class__", "class", "class_"},
     {"const__", "const", "const_"},
     {"continue__", "continue", "continue_"},
     {"default__", "default", "default_"},
     {"do__", "do", "do_"},
     {"else__", "else", "else_"},
     {"false__", "false", "false_"},
+    {"finally__", "finally", "finally_"},
     {"float__", "float", "float_"},
     {"for__", "for", "for_"},
     {"goto__", "goto", "goto_"},
@@ -698,6 +699,7 @@ namespace Common {
     {"INTEGER", "INTEGER", "integer"},
     {"ISO646String", "ISO646String", 0},
     {"NumericString", "NumericString", 0},
+    {"OBJECT", 0, "object"},
     {"OBJID", "OBJECT IDENTIFIER", "objid"},
     {"OCTETSTRING", "OCTET STRING", "octetstring"},
     {"ObjectDescriptor", "ObjectDescriptor", 0},
@@ -726,6 +728,7 @@ namespace Common {
     {"INTEGER_", 0, "INTEGER"},
     {"ISO646String_", 0, "ISO646String"},
     {"NumericString_", 0, "NumericString"},
+    {"OBJECT_", "OBJECT", "OBJECT"},
     {"OBJID_", "OBJID", "OBJID"},
     {"OCTETSTRING_", "OCTETSTRING", "OCTETSTRING"},
     {"ObjectDescriptor_", 0, "ObjectDescriptor"},
diff --git a/compiler2/ttcn3/AST_ttcn3.cc b/compiler2/ttcn3/AST_ttcn3.cc
index 7daa287e20445ad3bcd1e13626044d759b91fa88..650c29264d5c21b6eee02d984853f347727b5ac2 100644
--- a/compiler2/ttcn3/AST_ttcn3.cc
+++ b/compiler2/ttcn3/AST_ttcn3.cc
@@ -749,6 +749,15 @@ namespace Ttcn {
     ref_usage_found();
     Common::Assignment *ass = get_refd_assignment();
     if (!ass) FATAL_ERROR("Reference::generate_code()");
+    string const_prefix; // empty by default
+    if (gen_const_prefix) {
+      if (ass->get_asstype() == Common::Assignment::A_CONST) {
+        const_prefix = "const_";
+      }
+      else if (ass->get_asstype() == Common::Assignment::A_TEMPLATE) {
+        const_prefix = "template_";
+      }
+    }
     if (parlist) {
       // reference without parameters to a template that has only default formal parameters.
       // if @lazy: nothing to do, it's a C++ function call just like in case of Ref_pard::generate_code()
@@ -761,7 +770,7 @@ namespace Ttcn {
       expr->expr = mputstr(expr->expr,
         LazyFuzzyParamData::in_lazy_or_fuzzy() ?
         LazyFuzzyParamData::add_ref_genname(ass, my_scope).c_str() :
-        ass->get_genname_from_scope(my_scope).c_str());
+        (const_prefix + ass->get_genname_from_scope(my_scope)).c_str());
     }
     if (subrefs.get_nof_refs() > 0) subrefs.generate_code(expr, ass);
   }
@@ -1037,6 +1046,19 @@ namespace Ttcn {
     if (ass && check_parlist && !params_checked) {
       params_checked = true;
       FormalParList *fplist = ass->get_FormalParList();
+      if (fplist == NULL && ass->get_asstype() == Common::Assignment::A_TYPE) {
+        Def_Type* def = dynamic_cast<Def_Type*>(ass);
+        if (def == NULL) {
+          FATAL_ERROR("Ref_pard::get_refd_assignment");
+        }
+        Type* type = def->get_Type();
+        if (type->get_typetype() == Common::Type::T_CLASS) {
+          // if the referred assignment is a class type, then the reference and
+          // its parameters are meant for the constructor instead
+          fplist = type->get_class_type_body()->get_constructor()->
+            get_FormalParList();
+        }
+      }
       if (fplist) {
         Error_Context cntxt(params, "In actual parameter list of %s",
           ass->get_description().c_str());
@@ -3491,7 +3513,7 @@ namespace Ttcn {
     chk();
     return type;
   }
-
+  
   void Def_Type::chk()
   {
     if (checked) return;
@@ -4843,7 +4865,7 @@ namespace Ttcn {
       header = mputstr(header, cdef.decl);
       char*& source = in_class ? target->temp.constructor_init : target->source.global_vars;
       source = mputstr(source, cdef.def);
-      char*& init = in_class ? target->temp.constructor : target->functions.post_init;
+      char*& init = in_class ? target->temp.constructor_preamble : target->functions.post_init;
       init = mputstr(init, cdef.init);
       Code::free_cdef(&cdef);
     }
@@ -5109,7 +5131,7 @@ namespace Ttcn {
     Code::merge_cdef(target, &cdef, in_class);
     Code::free_cdef(&cdef);
     if (initial_value) {
-      char*& init = in_class ? target->temp.constructor :
+      char*& init = in_class ? target->temp.constructor_preamble :
         target->functions.init_comp;
       init = initial_value->generate_code_init(init,
         initial_value->get_lhs_name().c_str());
@@ -5324,7 +5346,7 @@ namespace Ttcn {
     Code::merge_cdef(target, &cdef, in_class);
     Code::free_cdef(&cdef);
     if (initial_value) {
-      char*& init = in_class ? target->temp.constructor :
+      char*& init = in_class ? target->temp.constructor_preamble :
         target->functions.init_comp;
       if (Common::Type::T_SEQOF == initial_value->get_my_governor()->get_typetype() ||
           Common::Type::T_ARRAY == initial_value->get_my_governor()->get_typetype()) {
@@ -5684,11 +5706,11 @@ namespace Ttcn {
     bool in_class = my_scope->is_class_scope();
     char*& header = in_class ? target->header.class_defs :
       target->header.global_vars;
-    char*& source = in_class ? target->temp.constructor :
+    char*& source = in_class ? target->temp.constructor_preamble :
       target->source.global_vars;
-    char*& pre_init = in_class ? target->temp.constructor :
+    char*& pre_init = in_class ? target->temp.constructor_preamble :
       target->functions.pre_init;
-    char*& post_init = in_class ? target->temp.constructor :
+    char*& post_init = in_class ? target->temp.constructor_preamble :
       target->functions.post_init;
     if (dimensions) {
       // timer array
@@ -8490,6 +8512,8 @@ namespace Ttcn {
     if (p_fp_list == NULL || block == NULL) {
       FATAL_ERROR("Def_Constructor::Def_Constructor");
     }
+    fp_list->set_my_def(this);
+    block->set_my_def(this);
   }
   
   Def_Constructor::~Def_Constructor()
@@ -8499,7 +8523,7 @@ namespace Ttcn {
     delete block;
   }
   
-  Def_Constructor *Def_Constructor::clone() const
+  Def_Constructor* Def_Constructor::clone() const
   {
     FATAL_ERROR("Def_Constructor::clone");
   }
@@ -8516,13 +8540,14 @@ namespace Ttcn {
 
   void Def_Constructor::set_my_scope(Scope* p_scope)
   {
-    //bridgeScope.set_parent_scope(p_scope);
-    //bridgeScope.set_scopeMacro_name(id->get_dispname());
+    bridgeScope.set_parent_scope(p_scope);
+    bridgeScope.set_scopeMacro_name(id->get_dispname());
 
-    //Definition::set_my_scope(&bridgeScope);
-    Definition::set_my_scope(p_scope); // TODO
+    Definition::set_my_scope(&bridgeScope);
+    
+    fp_list->set_my_scope(&bridgeScope);
     if (base_call != NULL) {
-      base_call->set_my_scope(p_scope);
+      base_call->set_my_scope(fp_list);
     }
     block->set_my_scope(fp_list);
   }
@@ -8535,12 +8560,36 @@ namespace Ttcn {
   
   void Def_Constructor::chk()
   {
-    // TODO
+    if (checked) {
+      return;
+    }
+    checked = true;
+    
+    Error_Context cntxt(this, "In constructor definition");
+    
+    fp_list->chk(asstype);
+    
+    if (base_call != NULL) {
+      Common::Assignment* base_type_ass = base_call->get_refd_assignment(true);
+      // TODO
+    }
+    
+    block->chk();
+    
+    if (!semantic_check_only) {
+      // prefix 'create' with the class name when forming parameter names
+      // to avoid collisions in the generated code
+      fp_list->set_genname(my_scope->get_scope_class()->get_id()->get_name() +
+        string("_") + get_genname());
+      block->set_code_section(GovernedSimple::CS_INLINE);
+    }
   }
   
   void Def_Constructor::generate_code(output_struct *target, bool clean_up)
   {
-    // TODO
+    fp_list->generate_code_defval(target);
+    target->temp.constructor_block = block->generate_code(target->temp.constructor_block,
+      target->header.global_vars, target->source.global_vars);
   }
   
   void Def_Constructor::set_parent_path(WithAttribPath* p_path)
@@ -8609,6 +8658,21 @@ namespace Ttcn {
       FATAL_ERROR("Ttcn::FormalPar::FormalPar(): invalid parameter type");
     defval.ti = p_defval;
   }
+  
+  FormalPar::FormalPar(const FormalPar& p)
+  : Definition(p.asstype, p.id->clone()), type(p.type->clone()), my_parlist(0),
+    used_as_lvalue(false), template_restriction(p.template_restriction),
+    eval(p.eval), defval_generated(false), usage_found(false)
+  {
+    type->set_ownertype(Type::OT_FORMAL_PAR, this);
+    checked = p.checked;
+    if (checked) {
+      defval.ap = p.defval.ap != NULL ? p.defval.ap->clone() : NULL;
+    }
+    else {
+      defval.ti = p.defval.ti != NULL ? p.defval.ti->clone() : NULL;
+    }
+  }
 
   FormalPar::~FormalPar()
   {
@@ -8619,7 +8683,7 @@ namespace Ttcn {
 
   FormalPar* FormalPar::clone() const
   {
-    FATAL_ERROR("FormalPar::clone");
+    return new FormalPar(*this);
   }
 
   void FormalPar::set_fullname(const string& p_fullname)
@@ -9599,6 +9663,15 @@ namespace Ttcn {
   // =================================
   // ===== FormalParList
   // =================================
+  
+  FormalParList::FormalParList(const FormalParList& p)
+  : Scope(), Location(), pars_v(), pars_m(), min_nof_pars(0), my_def(0),
+    checked(false), is_startable(false)
+  {
+    for (size_t i = 0; i < p.pars_v.size(); ++i) {
+      add_fp(p.pars_v[i]->clone());
+    }
+  }
 
   FormalParList::~FormalParList()
   {
@@ -9610,7 +9683,7 @@ namespace Ttcn {
 
   FormalParList *FormalParList::clone() const
   {
-    FATAL_ERROR("FormalParList::clone");
+    return new FormalParList(*this);
   }
 
   void FormalParList::set_fullname(const string& p_fullname)
@@ -10313,6 +10386,31 @@ namespace Ttcn {
     if (!a) FATAL_ERROR("ActualPar::ActualPar()");
     act = a;
   }
+  
+  ActualPar::ActualPar(const ActualPar& p)
+  : Node(), selection(p.selection), my_scope(p.my_scope),
+    gen_restriction_check(p.gen_restriction_check),
+    gen_post_restriction_check(p.gen_post_restriction_check)
+  {
+    switch(selection) {
+    case AP_ERROR:
+      break;
+    case AP_VALUE:
+      val = p.val->clone();
+      break;
+    case AP_TEMPLATE:
+      temp = p.temp->clone();
+      break;
+    case AP_REF:
+      ref = p.ref->clone();
+      break;
+    case AP_DEFAULT:
+      act = p.act;
+      break;
+    default:
+      FATAL_ERROR("ActualPar::ActualPar()");
+    }
+  }
 
   ActualPar::~ActualPar()
   {
@@ -10337,7 +10435,7 @@ namespace Ttcn {
 
   ActualPar *ActualPar::clone() const
   {
-    FATAL_ERROR("ActualPar::clone");
+    return new ActualPar(*this);
   }
 
   void ActualPar::set_fullname(const string& p_fullname)
diff --git a/compiler2/ttcn3/AST_ttcn3.hh b/compiler2/ttcn3/AST_ttcn3.hh
index fa1eb6cd2c2c607b3004df5129c7eb95829a0846..117ba2a322534de7421d45ad85d5406cee1648ce 100644
--- a/compiler2/ttcn3/AST_ttcn3.hh
+++ b/compiler2/ttcn3/AST_ttcn3.hh
@@ -91,7 +91,7 @@ namespace Ttcn {
      *  runtime checks for out and inout parameters after the call */
     template_restriction_t gen_post_restriction_check;
   private:
-    /** Copy constructor not implemented */
+    /** Copy constructor */
     ActualPar(const ActualPar& p);
     /** %Assignment disabled */
     ActualPar& operator=(const ActualPar& p);
@@ -325,10 +325,11 @@ namespace Ttcn {
    */
   class Reference : public Ref_base {
     ActualParList *parlist;
+    bool gen_const_prefix;
   public:
     Reference(Identifier *p_id);
     Reference(Identifier *p_modid, Identifier *p_id)
-      : Ref_base(p_modid, p_id), parlist(0) { }
+      : Ref_base(p_modid, p_id), parlist(0), gen_const_prefix(false) { }
     ~Reference();
     virtual Reference *clone() const;
     virtual void set_my_scope(Scope* p_scope);
@@ -336,6 +337,7 @@ namespace Ttcn {
     virtual Common::Assignment *get_refd_assignment(bool check_parlist = true);
     virtual const Identifier* get_modid();
     virtual const Identifier* get_id();
+    void set_gen_const_prefix() { gen_const_prefix = true; }
     /** Checks whether \a this points to a variable or value parameter.
      * Returns the type of the respective variable or variable field or NULL
      * in case of error. */
@@ -1751,7 +1753,7 @@ namespace Ttcn {
     
     StatementBlock* block;
     
-    //NameBridgingScope bridgeScope;
+    NameBridgingScope bridgeScope;
     
     /// Copy constructor disabled
     Def_Constructor(const Def_Constructor& p);
@@ -1764,7 +1766,8 @@ namespace Ttcn {
     virtual Def_Constructor* clone() const;
     virtual void set_fullname(const string& p_fullname);
     virtual void set_my_scope(Scope* p_scope);
-    virtual FormalParList *get_FormalParList();
+    virtual FormalParList* get_FormalParList();
+    virtual Ref_pard* get_base_call() const { return base_call; }
     virtual void chk();
     virtual void generate_code(output_struct *target, bool clean_up = false);
     virtual void set_parent_path(WithAttribPath* p_path);
diff --git a/compiler2/ttcn3/Statement.cc b/compiler2/ttcn3/Statement.cc
index 0363c48f064109cd2e6151ec5feaa82c09c22038..dd5764afe1de9aac8390e2047402166627beace1 100644
--- a/compiler2/ttcn3/Statement.cc
+++ b/compiler2/ttcn3/Statement.cc
@@ -3248,6 +3248,10 @@ error:
   void Statement::chk_assignment()
   {
     Error_Context cntxt(this, "In variable assignment");
+    Definition* sb_def = my_sb->get_my_def();
+    if (sb_def != NULL && sb_def->get_asstype() == Common::Assignment::A_CONSTRUCTOR) {
+      ass->set_in_contructor();
+    }
     ass->chk();
   }
 
@@ -8754,14 +8758,16 @@ error:
 
   Assignment::Assignment(Reference *p_ref, Template *p_templ)
     : asstype(ASS_UNKNOWN), ref(p_ref), templ(p_templ), self_ref(false),
-      template_restriction(TR_NONE), gen_restriction_check(false)
+      template_restriction(TR_NONE), gen_restriction_check(false),
+      in_constructor(false)
   {
     if(!ref || !templ) FATAL_ERROR("Ttcn::Assignment::Assignment");
   }
 
   Assignment::Assignment(Reference *p_ref, Value *p_val)
     : asstype(ASS_VAR), ref(p_ref), val(p_val), self_ref(false),
-      template_restriction(TR_NONE), gen_restriction_check(false)
+      template_restriction(TR_NONE), gen_restriction_check(false),
+      in_constructor(false)
   {
     if(!ref || !val) FATAL_ERROR("Ttcn::Assignment::Assignment");
   }
@@ -8863,6 +8869,14 @@ error:
     case Common::Assignment::A_PAR_VAL_IN:
       t_ass->use_as_lvalue(*ref);
       // no break
+    case Common::Assignment::A_CONST:
+      if (t_ass->get_asstype() == Common::Assignment::A_CONST &&
+          !in_constructor) {
+        ref->error("Reference to a variable or template variable was expected "
+          "instead of %s", t_ass->get_description().c_str());
+        goto error;
+      }
+      // no break
     case Common::Assignment::A_VAR:
     case Common::Assignment::A_PAR_VAL_OUT:
     case Common::Assignment::A_PAR_VAL_INOUT:
@@ -8881,6 +8895,14 @@ error:
     case Common::Assignment::A_PAR_TEMPL_IN:
       t_ass->use_as_lvalue(*ref);
       // no break
+    case Common::Assignment::A_TEMPLATE:
+      if (t_ass->get_asstype() == Common::Assignment::A_TEMPLATE &&
+          !in_constructor) {
+        ref->error("Reference to a variable or template variable was expected "
+          "instead of %s", t_ass->get_description().c_str());
+        goto error;
+      }
+      // no break
     case Common::Assignment::A_VAR_TEMPLATE: {
       Type::typetype_t tt = t_ass->get_Type()->get_typetype();
       switch (tt) {
@@ -9180,6 +9202,9 @@ error:
         const char *type_genname_str = type_genname.c_str();
         expression_struct expr;
         Code::init_expr(&expr);
+        if (in_constructor) {
+          ref->set_gen_const_prefix();
+        }
         ref->generate_code(&expr);
 
         if (rhs_copied) {
@@ -9218,6 +9243,9 @@ error:
           // C++ equivalent of RHS is a single expression.
           expression_struct expr;
           Code::init_expr(&expr);
+          if (in_constructor) {
+            ref->set_gen_const_prefix();
+          }
           ref->generate_code(&expr);// vu.s()
           if (rhs_copied) {
             str = mputprintf(str, "%s = %s;\n",
@@ -9233,8 +9261,12 @@ error:
         }
         else {
           // The LHS is a single identifier.
-          const string& rhs_name = ref->get_refd_assignment()
-            ->get_genname_from_scope(ref->get_my_scope());
+          Common::Assignment* refd_ass = ref->get_refd_assignment();
+          string rhs_name = refd_ass->get_genname_from_scope(ref->get_my_scope());
+          if (in_constructor &&
+              refd_ass->get_asstype() == Common::Assignment::A_CONST) {
+            rhs_name = string("const_") + rhs_name;
+          }
           if (val->can_use_increment(ref)) {
             switch (val->get_optype()) {
             case Value::OPTYPE_ADD:
@@ -9275,6 +9307,9 @@ error:
         const char *tmp_id_str = tmp_id.c_str();
         expression_struct expr;
         Code::init_expr(&expr);
+        if (in_constructor) {
+          ref->set_gen_const_prefix();
+        }
         ref->generate_code(&expr);
 
         if (rhs_copied) {
@@ -9319,6 +9354,9 @@ error:
             // check.  Skipped if conversion needed.
             expression_struct expr;
             Code::init_expr(&expr);
+            if (in_constructor) {
+              ref->set_gen_const_prefix();
+            }
             ref->generate_code(&expr);
             if (rhs_copied) {
               str = mputprintf(str, "%s = %s;\n",
@@ -9336,8 +9374,12 @@ error:
         }
         else {
           // LHS is a single identifier
-          const string& rhs_name = ref->get_refd_assignment()
-            ->get_genname_from_scope(ref->get_my_scope());
+          Common::Assignment* refd_ass = ref->get_refd_assignment();
+          string rhs_name = refd_ass->get_genname_from_scope(ref->get_my_scope());
+          if (in_constructor &&
+              refd_ass->get_asstype() == Common::Assignment::A_TEMPLATE) {
+            rhs_name = string("template_") + rhs_name;
+          }
           if (Common::Type::T_SEQOF == templ->get_my_governor()->get_typetype() ||
               Common::Type::T_ARRAY == templ->get_my_governor()->get_typetype()) {
             str = mputprintf(str, "%s.remove_all_permutations();\n", (rhs_copied ? rhs_copy : rhs_name).c_str());
diff --git a/compiler2/ttcn3/Statement.hh b/compiler2/ttcn3/Statement.hh
index 680c05a922357afa1bbe101551e89edf8eed4f6b..c69ce269cee129b60621c43302e8d100f8882f97 100644
--- a/compiler2/ttcn3/Statement.hh
+++ b/compiler2/ttcn3/Statement.hh
@@ -952,6 +952,7 @@ namespace Ttcn {
     template_restriction_t template_restriction;
     /** set in chk(), used by code generation */
     bool gen_restriction_check;
+    bool in_constructor;
 
     Assignment(const Assignment& p);
     Assignment& operator=(const Assignment& p);
@@ -965,6 +966,7 @@ namespace Ttcn {
     virtual void set_my_scope(Scope *p_scope);
     virtual void set_fullname(const string& p_fullname);
     virtual void dump(unsigned int level) const;
+    void set_in_contructor() { in_constructor = true; }
   private:
     void chk_unknown_ass();
     void chk_var_ass();
diff --git a/compiler2/ttcn3/Ttcnstuff.cc b/compiler2/ttcn3/Ttcnstuff.cc
index b46e06a04eca3fd61661a511388294788f79d19e..5264f12257b507614d287a76581807eb1aed1210 100644
--- a/compiler2/ttcn3/Ttcnstuff.cc
+++ b/compiler2/ttcn3/Ttcnstuff.cc
@@ -24,6 +24,8 @@
 #include "Attributes.hh"
 #include <errno.h>
 #include "Statement.hh"
+#include "Templatestuff.hh"
+#include "TtcnTemplate.hh"
 
 // implemented in coding_attrib_p.y
 extern Ttcn::ExtensionAttributes * parse_extattributes(
@@ -2985,7 +2987,8 @@ namespace Ttcn {
                                Definitions* p_members, StatementBlock* p_finally_block)
   : Scope(), Location(), class_id(p_class_id), external(p_external), final(p_final), abstract(p_abstract),
     base_type(p_base_type), runs_on_ref(p_runs_on_ref), mtc_ref(p_mtc_ref), system_ref(p_system_ref),
-    members(p_members), finally_block(p_finally_block), checked(false)
+    members(p_members), finally_block(p_finally_block), constructor(NULL), checked(false),
+    default_constructor(false)
   {
     if (members == NULL) {
       FATAL_ERROR("ClassTypeBody::ClassTypeBody");
@@ -3004,6 +3007,8 @@ namespace Ttcn {
     system_ref = p.system_ref != NULL ? p.system_ref->clone() : NULL;
     members = p.members->clone();
     finally_block = p.finally_block != NULL ? p.finally_block->clone() : NULL;
+    default_constructor = p.default_constructor;
+    constructor = default_constructor ? p.constructor->clone() : p.constructor;
     checked = p.checked;
   }
   
@@ -3020,6 +3025,9 @@ namespace Ttcn {
     delete mtc_ref;
     delete runs_on_ref;
     delete system_ref;
+    if (default_constructor) {
+      delete constructor;
+    }
   }
   
   void ClassTypeBody::set_fullname(const string& p_fullname)
@@ -3058,10 +3066,10 @@ namespace Ttcn {
     if (system_ref != NULL) {
       system_ref->set_my_scope(p_scope);
     }
-    //members->set_my_scope(p_scope);
-    /*if (finally_block != NULL) {
-      finally_block->set_my_scope(p_scope);
-    }*/
+    members->set_parent_scope(this);
+    if (finally_block != NULL) {
+      finally_block->set_parent_scope(this);
+    }
   }
   
   void ClassTypeBody::dump(unsigned level) const
@@ -3088,6 +3096,12 @@ namespace Ttcn {
       "Has" : "Doesn't have");
   }
   
+  Def_Constructor* ClassTypeBody::get_constructor()
+  {
+    chk();
+    return constructor;
+  }
+  
   bool ClassTypeBody::is_parent_class(const ClassTypeBody* p_class) const
   {
     if (this == p_class) {
@@ -3193,12 +3207,87 @@ namespace Ttcn {
       // TODO
     }
 
-    members->set_parent_scope(this);
     members->chk_uniq();
     members->chk();
+    
+    for (size_t i = 0; i < members->get_nof_asss(); ++i) {
+      Common::Assignment* ass = members->get_ass_byIndex(i);
+      if (ass->get_asstype() == Common::Assignment::A_CONSTRUCTOR) {
+        // TODO: check for multiple constructors, or is that handled by previous checks?
+        constructor = dynamic_cast<Def_Constructor*>(ass);
+        if (constructor == NULL) {
+          FATAL_ERROR("ClassTypeBody::chk");
+        }
+        break;
+      }
+    }
+    
+    if (constructor == NULL) {
+      // create a default constructor
+      Ref_pard* base_call = NULL;
+      FormalParList* fp_list = NULL;
+      if (base_type != NULL) {
+        ClassTypeBody* base_class = base_type->get_type_refd_last()->
+          get_class_type_body();
+        FormalParList* base_fp_list = base_class->get_constructor()->
+          get_FormalParList();
+        fp_list = base_fp_list->clone();
+        ParsedActualParameters* parsed_ap_list = new ParsedActualParameters();
+        for (size_t i = 0; i < base_fp_list->get_nof_fps(); ++i) {
+          // the actual parameters are references to the formal parameters of
+          // the base constructor (also present in this constructor)
+          Reference* ref = new Reference(NULL,
+            base_fp_list->get_fp_byIndex(i)->get_id().clone());
+          Common::Value* val = new Value(Common::Value::V_REFD, ref);
+          Template* temp = new Template(val);
+          TemplateInstance* ti = new TemplateInstance(NULL, NULL, temp);
+          parsed_ap_list->add_ti(ti);
+        }
+        base_call = new Ref_pard(base_class->get_scope_mod()->get_modid().clone(),
+          base_class->get_id()->clone(), parsed_ap_list);
+      }
+      else {
+        fp_list = new FormalParList;
+      }
+      StatementBlock* block = new StatementBlock();
+      for (size_t i = 0; i < members->get_nof_asss(); ++i) {
+        Common::Assignment* member = members->get_ass_byIndex(i);
+        bool is_template = false;
+        switch (member->get_asstype()) {
+        case Common::Assignment::A_TEMPLATE:
+        case Common::Assignment::A_VAR_TEMPLATE:
+          is_template = true;
+          // no break
+        case Common::Assignment::A_CONST:
+        case Common::Assignment::A_VAR: {
+          // add a formal parameter for this member
+          Common::Identifier* id = new Common::Identifier(
+            Common::Identifier::ID_TTCN, string("p_") + member->get_id().get_ttcnname());
+          FormalPar* fp = new FormalPar(is_template ?
+            Common::Assignment::A_PAR_TEMPL_IN : Common::Assignment::A_PAR_VAL_IN,
+            member->get_Type()->clone(), id, NULL);
+          fp_list->add_fp(fp);
+          // add a statement, that assigns the parameter's value to the member
+          Reference* ref_lhs = new Reference(NULL, member->get_id().clone());
+          Reference* ref_rhs = new Reference(NULL, id->clone());
+          Common::Value* val_rhs = new Value(Common::Value::V_REFD, ref_rhs);
+          Template* temp_rhs = new Template(val_rhs);
+          Assignment* par_ass = new Assignment(ref_lhs, temp_rhs);
+          Statement* stmt = new Statement(Statement::S_ASSIGNMENT, par_ass);
+          block->add_stmt(stmt);
+          break; }
+        default:
+          break;
+        }
+      }
+      constructor = new Def_Constructor(fp_list, base_call, block);
+      constructor->set_my_scope(this);
+      constructor->set_fullname(get_fullname() + ".<default_constructor>");
+      constructor->chk();
+      default_constructor = true;
+    }
 
     if (finally_block != NULL) {
-      finally_block->set_parent_scope(this);
       finally_block->chk();
     }
   }
@@ -3214,18 +3303,45 @@ namespace Ttcn {
       target->header.class_defs = mputprintf(target->header.class_defs,
         "class %s : public %s {\n",
         class_id->get_name().c_str(), base_type_name.c_str());
+      
       // members
       members->generate_code(target);
+      if (default_constructor) {
+        target->source.methods = mputstr(target->source.methods,
+          "/* default constructor */\n");
+        // code has not been generated for the constructor yet, since it's not
+        // in 'members' in this case
+        constructor->generate_code(target);
+      }
       
       // constructor
+      char* formal_par_list_str = NULL;
+      expression_struct_t base_call_expr;
+      Code::init_expr(&base_call_expr);
+      Ref_pard* base_call = constructor->get_base_call();
+      if (base_call != NULL) {
+        base_call->generate_code(&base_call_expr);
+      }
+      // generate code for the base call first, so the formal parameter list
+      // knows which parameters are used and which aren't
+      formal_par_list_str = constructor->get_FormalParList()->generate_code(
+        memptystr());
+      if (base_call_expr.expr == NULL) {
+        base_call_expr.expr = mprintf("%s()", base_type_name.c_str());
+      }
       target->header.class_defs = mputprintf(target->header.class_defs,
         "public:\n"
-        "%s();\n", class_id->get_name().c_str());
+        "%s(%s);\n",
+        class_id->get_name().c_str(),
+        formal_par_list_str != NULL ? formal_par_list_str : "");
       target->source.methods = mputprintf(target->source.methods,
-        "%s::%s()\n"
-        ": %s()",
+        "%s::%s(%s)\n"
+        ": %s",
         class_id->get_name().c_str(), class_id->get_name().c_str(),
-        base_type_name.c_str());
+        formal_par_list_str != NULL ? formal_par_list_str : "",
+        base_call_expr.expr);
+      Free(formal_par_list_str);
+      Code::free_expr(&base_call_expr);
       if (target->temp.constructor_init != NULL) {
         target->source.methods = mputstr(target->source.methods,
           target->temp.constructor_init);
@@ -3233,13 +3349,18 @@ namespace Ttcn {
         target->temp.constructor_init = NULL;
       }
       target->source.methods = mputstr(target->source.methods, "\n{\n");
-      if (target->temp.constructor != NULL) {
+      if (target->temp.constructor_preamble != NULL ||
+          target->temp.constructor_block != NULL) {
         target->source.methods = create_location_object(
           target->source.methods, "FUNCTION", class_id->get_name().c_str());
         target->source.methods = mputstr(target->source.methods,
-          target->temp.constructor);
-        Free(target->temp.constructor);
-        target->temp.constructor = NULL;
+          target->temp.constructor_preamble);
+        target->source.methods = mputstr(target->source.methods,
+          target->temp.constructor_block);
+        Free(target->temp.constructor_preamble);
+        Free(target->temp.constructor_block);
+        target->temp.constructor_preamble = NULL;
+        target->temp.constructor_block = NULL;
       }
       target->source.methods = mputstr(target->source.methods, "}\n\n");
 
diff --git a/compiler2/ttcn3/Ttcnstuff.hh b/compiler2/ttcn3/Ttcnstuff.hh
index f036abebfc7f2eb46d96e6d368ab806a891a98c0..a3a385569260f59b04b7a667fdba8eec9317cbf3 100644
--- a/compiler2/ttcn3/Ttcnstuff.hh
+++ b/compiler2/ttcn3/Ttcnstuff.hh
@@ -765,7 +765,11 @@ class ClassTypeBody : public Common::Scope, public Common::Location {
   Reference* system_ref;
   Definitions* members;
   StatementBlock* finally_block;
+  /** set during semantic analysis to either a pointer to the constructor in
+    * 'members', or the actual default constructor (if no constructor is defined) */
+  Def_Constructor* constructor;
   bool checked;
+  bool default_constructor; /// true if the class uses a default constructor
   
 public:
   ClassTypeBody(Common::Identifier* p_class_id, boolean p_external, boolean p_final,
@@ -783,6 +787,7 @@ public:
   virtual bool is_class_scope() const { return true; }
   virtual const ClassTypeBody* get_scope_class() const { return this; }
   Common::Identifier* get_id() const { return class_id; }
+  Def_Constructor* get_constructor();
   
   bool is_parent_class(const ClassTypeBody* p_class) const;
   bool has_local_ass_withId(const Identifier& p_id);
diff --git a/compiler2/ttcn3/compiler.h b/compiler2/ttcn3/compiler.h
index 8564d87cfcb71ec37db605c6ece4c546e9abf686..c4c8059b4c29ed1242503b3415131819d6bfda44 100644
--- a/compiler2/ttcn3/compiler.h
+++ b/compiler2/ttcn3/compiler.h
@@ -69,7 +69,8 @@ extern "C" {
     } functions;
     struct {
       char* constructor_init;
-      char* constructor;
+      char* constructor_preamble;
+      char* constructor_block;
     } temp;
     struct {
       size_t pre_things_size; // Size of string_literals + global_vars
diff --git a/regression_test/oop/oop.ttcn b/regression_test/oop/oop.ttcn
index e96b2a490fcdadc7ed5de5dcf8450a3fc1907164..f68960203dfb6838f2449773260102004b399b7f 100644
--- a/regression_test/oop/oop.ttcn
+++ b/regression_test/oop/oop.ttcn
@@ -17,12 +17,15 @@ type component CT {
 
 type port PT message { inout integer; } with { extension "internal" }
 
+type record of integer IntList;
+
 ///////////////////////////////////////////////////
 ///////////////////// CLASSES /////////////////////
 ///////////////////////////////////////////////////
 
 type class BaseClass runs on CT mtc CT system CT {
   public const integer m_const := 1;
+  private const IntList m_const2 := { 1, 2, 3 };
   /*protected*/ var charstring m_var;
   private template octetstring m_temp := ? length (1..4);
   public var template float m_var_temp;
@@ -33,17 +36,17 @@ type class BaseClass runs on CT mtc CT system CT {
   //public template integer m_temp_pard(integer p) := p; // parameterized template members not supported
   
   // this would also be the implicit constructor (constructors are not yet implemented):
-  create(integer p_const, charstring p_var,
-         template octetstring p_temp, template float p_var_temp,
-         PT p_port, timer p_timer) {
+  create(integer p_const, IntList p_const2, charstring p_var,
+         template octetstring p_temp, template float p_var_temp) {
     m_const := p_const;
     m_const := 2;
     m_var := p_var;
+    m_const2[2] := p_const2[0];
     m_temp := p_temp;
     m_temp := *;
     m_var_temp := p_var_temp;
-    m_port := p_port;
-    m_timer := p_timer;
+    //m_port := p_port;
+    //m_timer := p_timer;
   }
   
   public function f(in integer x) return integer {
@@ -60,16 +63,16 @@ finally {
   log(m_var);
 }
 
-type class SubClass extends BaseClass {
-  const octetstring m_const2 := 'AB'O; // the parser currently doesn't accept constants without initial value
-  
-  create(integer p_const := 1, charstring p_var,
-         template octetstring p_temp, template float p_var_temp,
-         PT p_port, timer p_timer)
-         : BaseClass(p_const, p_var, p_temp, p_var_temp, p_port, p_timer) {
-    m_const2 := 'FFFF'O;
+type class SubClass extends BaseClass {  
+  create(integer p_const := 1, IntList p_const2, charstring p_var,
+         template octetstring p_temp, template float p_var_temp)
+         : BaseClass(p_const, p_const2, p_var, p_temp, p_var_temp) {
+    m_const3 := 'FFFF'O;
+    m_var := m_var & "x";
   }
   
+  const octetstring m_const3 := 'AB'O; // the parser currently doesn't accept constants without initial value
+  
   public function f(in integer x) return integer {
     //return super.f(x) - 1; // not supported yet
     m_var := m_var & int2str(x);
@@ -78,10 +81,14 @@ type class SubClass extends BaseClass {
 }
 
 type class @final FinalClass extends SubClass {
+  private const integer m_final_const := 1;
+  private template charstring m_final_temp := ? length (1..4);
+  private var float m_final_var;
+  private var template octetstring m_final_var_temp;
   public function @final f(in integer x) return integer {
     //return super.super.f(x) + 1; // not supported yet
     m_var := m_var & int2str(x);
-    return x + 1;
+    return x + m_final_const;
   }
 }
 
@@ -94,6 +101,10 @@ type class @abstract AbstractClass {
 }
 
 type class ConcreteClass extends AbstractClass {
+  create(octetstring p_const := 'AB'O) {
+    // for compilation only, to make sure there are no name clases between parameter default values
+    log(p_const);
+  }
   public function f_abs(inout integer x) return boolean {
     x := x + 1;
     return x > 0;