diff --git a/compiler2/AST.cc b/compiler2/AST.cc
index 291f03c0382eb409a00068a51309c2287645abc8..6f4f2ad03b24fdbb9ec305ce4247a00812cf3783 100644
--- a/compiler2/AST.cc
+++ b/compiler2/AST.cc
@@ -1907,10 +1907,10 @@ namespace Common {
     return 0;
   }
 
-  bool Assignment::get_lazy_eval() const
+  param_eval_t Assignment::get_eval_type() const
   {
-    FATAL_ERROR("Common::Assignment::get_lazy_eval()");
-    return false;
+    FATAL_ERROR("Common::Assignment::get_eval_type()");
+    return NORMAL_EVAL;
   }
 
   Ttcn::FormalParList *Assignment::get_FormalParList()
@@ -1958,12 +1958,12 @@ namespace Common {
     }
     if (p_prefix) ret_val += p_prefix;
     ret_val += get_genname();
-    // add the cast to real type if its a lazy formal paramter
+    // add the cast to real type if it's a lazy or fuzzy formal parameter
     switch (asstype) {
     case A_PAR_VAL:
     case A_PAR_VAL_IN:
     case A_PAR_TEMPL_IN:
-      if (get_lazy_eval() && p_prefix==NULL) {
+      if (get_eval_type() != NORMAL_EVAL && p_prefix==NULL) {
         Type* type = get_Type();
         string type_genname = (asstype==A_PAR_TEMPL_IN) ? type->get_genname_template(p_scope) : type->get_genname_value(p_scope);
         ret_val = string("((") + type_genname + string("&)") + ret_val + string(")");
diff --git a/compiler2/AST.hh b/compiler2/AST.hh
index 4a7c5a05841a8cf24d442ecb0add82658f4661cc..4d986ab0ec465488c60ab8b664663aed82340b65 100644
--- a/compiler2/AST.hh
+++ b/compiler2/AST.hh
@@ -487,6 +487,12 @@ namespace Common {
      *  named assignments are visible. */
     virtual Assignment* get_ass_byIndex(size_t p_i) = 0;
   };
+  
+  enum param_eval_t {
+    NORMAL_EVAL,
+    LAZY_EVAL,
+    FUZZY_EVAL
+  };
 
   /**
    * Abstract class to represent different kinds of assignments.
@@ -572,7 +578,7 @@ namespace Common {
     virtual Type *get_Type();
     virtual Value *get_Value();
     virtual Ttcn::Template *get_Template();
-    virtual bool get_lazy_eval() const;
+    virtual param_eval_t get_eval_type() const;
     /** @} */
     /** Returns the formal parameter list of a TTCN-3 definition */
     virtual Ttcn::FormalParList *get_FormalParList();
diff --git a/compiler2/DebuggerStuff.cc b/compiler2/DebuggerStuff.cc
index 2fbbd2864c001a5d207ee9603bec691d9787cd19..f7505aea1ed464c7b6848a70d38123edff62f61a 100644
--- a/compiler2/DebuggerStuff.cc
+++ b/compiler2/DebuggerStuff.cc
@@ -188,16 +188,14 @@ char* generate_code_debugger_add_var(char* str, Common::Assignment* var_ass,
     current_mod = var_ass->get_my_scope()->get_scope_mod();
   }
   
-  bool is_lazy_param = false;
+  param_eval_t eval = NORMAL_EVAL;
   bool is_constant = false;
   switch (var_ass->get_asstype()) {
   case Common::Assignment::A_PAR_VAL:
   case Common::Assignment::A_PAR_VAL_IN:
   case Common::Assignment::A_PAR_TEMPL_IN: {
-    if (var_ass->get_lazy_eval()) {
-      // lazy parameters have their own printing function
-      is_lazy_param = true;
-    }
+    // lazy and fuzzy parameters have their own printing functions
+    eval = var_ass->get_eval_type();
     Ttcn::FormalPar* fpar = dynamic_cast<Ttcn::FormalPar*>(var_ass);
     is_constant = fpar == NULL || !fpar->get_used_as_lvalue();
     break; }
@@ -214,8 +212,19 @@ char* generate_code_debugger_add_var(char* str, Common::Assignment* var_ass,
   // recreate the TTCN-3 version of the type name and determine the type's 
   // printing and overwriting functions
   string type_name, print_function, set_function;
-  print_function = is_lazy_param ? "TTCN3_Debugger::print_lazy_param<" :
-    "TTCN3_Debugger::print_base_var";
+  switch (eval) {
+  case NORMAL_EVAL:
+    print_function = "TTCN3_Debugger::print_base_var";
+    break;
+  case LAZY_EVAL:
+    print_function = "TTCN3_Debugger::print_lazy_param<";
+    break;
+  case FUZZY_EVAL:
+    print_function = "TTCN3_Debugger::print_fuzzy_param";
+    break;
+  default:
+    FATAL_ERROR("generate_code_debugger_add_var");
+  }
   set_function = "TTCN3_Debugger::set_base_var";
   if (var_ass->get_asstype() == Common::Assignment::A_TIMER ||
       var_ass->get_asstype() == Common::Assignment::A_PAR_TIMER) {
@@ -238,14 +247,14 @@ char* generate_code_debugger_add_var(char* str, Common::Assignment* var_ass,
            var_type->get_typetype() != Type::T_UNRESTRICTEDSTRING) {
       var_type = var_type->get_type_refd();
     }
-    if (is_lazy_param) {
+    if (eval == LAZY_EVAL) {
       print_function += var_type->get_genname_value(current_mod);
     }
     if (var_type->get_typetype() == Type::T_PORT && var_ass->get_Dimensions() != NULL) {
       // port array
       type_name = var_type->get_dispname() +
         array_dimensions_to_string(var_ass->get_Dimensions());
-      if (!is_lazy_param) {
+      if (eval == NORMAL_EVAL) {
         print_function = string("TTCN3_Debugger::print_port_array<") +
           function_params_for_array_dims(var_ass->get_Dimensions(),
                                     var_type->get_genname_value(current_mod),
@@ -264,7 +273,7 @@ char* generate_code_debugger_add_var(char* str, Common::Assignment* var_ass,
       calculate_type_name_and_debug_functions_from_type(t, t, current_mod,
         type_name, dummy1, dummy2);
       type_name += dims_str;
-      if (!is_lazy_param) {
+      if (eval == NORMAL_EVAL) {
         switch (var_ass->get_asstype()) {
         case Common::Assignment::A_MODULEPAR_TEMP:
         case Common::Assignment::A_TEMPLATE:
@@ -295,7 +304,7 @@ char* generate_code_debugger_add_var(char* str, Common::Assignment* var_ass,
     else {
       string dummy;
       calculate_type_name_and_debug_functions_from_type(var_ass->get_Type(),
-        var_type, current_mod, type_name, is_lazy_param ? dummy : print_function,
+        var_type, current_mod, type_name, eval != NORMAL_EVAL ? dummy : print_function,
         set_function);
     }
   }
@@ -309,7 +318,7 @@ char* generate_code_debugger_add_var(char* str, Common::Assignment* var_ass,
   case Common::Assignment::A_PAR_TEMPL_INOUT:
     // add a suffix, if it's a template
     type_name += " template";
-    if (is_lazy_param) {
+    if (eval == LAZY_EVAL) {
       print_function += "_template";
     }
     break;
@@ -317,7 +326,7 @@ char* generate_code_debugger_add_var(char* str, Common::Assignment* var_ass,
     break;
   }
   
-  if (is_lazy_param) {
+  if (eval == LAZY_EVAL) {
     print_function += ">";
   }
   
diff --git a/compiler2/Type_chk.cc b/compiler2/Type_chk.cc
index 118a56b38967ccbf92dfe01078bd66060546996a..2f8e128488c5b783a14e1b203d7b760d7708a554 100644
--- a/compiler2/Type_chk.cc
+++ b/compiler2/Type_chk.cc
@@ -2947,7 +2947,7 @@ void Type::chk_Fat()
   switch (typetype) {
   case T_FUNCTION:
     u.fatref.fp_list->chk(Ttcn::Definition::A_FUNCTION);
-    u.fatref.fp_list->chk_noLazyParams();
+    u.fatref.fp_list->chk_noLazyFuzzyParams();
     if (u.fatref.is_startable && !u.fatref.fp_list->get_startability())
       u.fatref.is_startable = false;
     if (u.fatref.return_type) {
@@ -2962,11 +2962,11 @@ void Type::chk_Fat()
     break;
   case T_ALTSTEP:
     u.fatref.fp_list->chk(Ttcn::Definition::A_ALTSTEP);
-    u.fatref.fp_list->chk_noLazyParams();
+    u.fatref.fp_list->chk_noLazyFuzzyParams();
     break;
   case T_TESTCASE:
     u.fatref.fp_list->chk(Ttcn::Definition::A_TESTCASE);
-    u.fatref.fp_list->chk_noLazyParams();
+    u.fatref.fp_list->chk_noLazyFuzzyParams();
     if (u.fatref.system.ref) {
       Error_Context cntxt2(u.fatref.runs_on.ref, "In `system' clause");
       u.fatref.system.type = u.fatref.system.ref->chk_comptype_ref();
diff --git a/compiler2/Value.cc b/compiler2/Value.cc
index f3f1c912ea4ed2506c9e65ec49f575bd7c154d24..614923264e02f58496c5b790c73115de12b1cd4c 100644
--- a/compiler2/Value.cc
+++ b/compiler2/Value.cc
@@ -14428,17 +14428,17 @@ void Value::generate_code_expr_encvalue_unichar(expression_struct *expr)
   }
 
 ///////////////////////////////////////////////////////////////////////////////
-// class LazyParamData
+// class LazyFuzzyParamData
 
-    int LazyParamData::depth = 0;
-    bool LazyParamData::used_as_lvalue = false;
-    vector<string>* LazyParamData::type_vec = NULL;
-    vector<string>* LazyParamData::refd_vec = NULL;
+    int LazyFuzzyParamData::depth = 0;
+    bool LazyFuzzyParamData::used_as_lvalue = false;
+    vector<string>* LazyFuzzyParamData::type_vec = NULL;
+    vector<string>* LazyFuzzyParamData::refd_vec = NULL;
 
-    void LazyParamData::init(bool p_used_as_lvalue) {
-      if (depth<0) FATAL_ERROR("LazyParamData::init()");
+    void LazyFuzzyParamData::init(bool p_used_as_lvalue) {
+      if (depth<0) FATAL_ERROR("LazyFuzzyParamData::init()");
       if (depth==0) {
-        if (type_vec || refd_vec) FATAL_ERROR("LazyParamData::init()");
+        if (type_vec || refd_vec) FATAL_ERROR("LazyFuzzyParamData::init()");
         used_as_lvalue = p_used_as_lvalue;
         type_vec = new vector<string>;
         refd_vec = new vector<string>;
@@ -14446,9 +14446,9 @@ void Value::generate_code_expr_encvalue_unichar(expression_struct *expr)
       depth++;
     }
 
-    void LazyParamData::clean() {
-      if (depth<=0) FATAL_ERROR("LazyParamData::clean()");
-      if (!type_vec || !refd_vec) FATAL_ERROR("LazyParamData::clean()");
+    void LazyFuzzyParamData::clean() {
+      if (depth<=0) FATAL_ERROR("LazyFuzzyParamData::clean()");
+      if (!type_vec || !refd_vec) FATAL_ERROR("LazyFuzzyParamData::clean()");
       if (depth==1) {
         // type_vec
         for (size_t i=0; i<type_vec->size(); i++) delete (*type_vec)[i];
@@ -14464,17 +14464,18 @@ void Value::generate_code_expr_encvalue_unichar(expression_struct *expr)
       depth--;
     }
 
-    bool LazyParamData::in_lazy() {
-      if (depth<0) FATAL_ERROR("LazyParamData::in_lazy()");
+    bool LazyFuzzyParamData::in_lazy_or_fuzzy() {
+      if (depth<0) FATAL_ERROR("LazyFuzzyParamData::in_lazy_or_fuzzy()");
       return depth>0;
     }
 
     // returns a temporary id instead of the C++ reference to a definition
-    // stores in vectors the C++ type of the definiton, the C++ reference to the definition and if it refers to a lazy formal parameter
-    string LazyParamData::add_ref_genname(Assignment* ass, Scope* scope) {
-      if (!ass || !scope) FATAL_ERROR("LazyParamData::add_ref_genname()");
-      if (!type_vec || !refd_vec) FATAL_ERROR("LazyParamData::add_ref_genname()");
-      if (type_vec->size()!=refd_vec->size()) FATAL_ERROR("LazyParamData::add_ref_genname()");
+    // stores in vectors the C++ type of the definiton, the C++ reference to the
+    // definition and whether it refers to a lazy/fuzzy formal parameter
+    string LazyFuzzyParamData::add_ref_genname(Assignment* ass, Scope* scope) {
+      if (!ass || !scope) FATAL_ERROR("LazyFuzzyParamData::add_ref_genname()");
+      if (!type_vec || !refd_vec) FATAL_ERROR("LazyFuzzyParamData::add_ref_genname()");
+      if (type_vec->size()!=refd_vec->size()) FATAL_ERROR("LazyFuzzyParamData::add_ref_genname()");
       // store the type of the assignment
       string* type_str = new string;
       switch (ass->get_asstype()) {
@@ -14489,22 +14490,22 @@ void Value::generate_code_expr_encvalue_unichar(expression_struct *expr)
       default:
         *type_str = ass->get_Type()->get_genname_value(scope);
       }
-      // add the Lazy_Param<> part if the referenced assignment is a FormalPar with lazy_eval == true
-      bool refd_ass_is_lazy_fpar = false;
+      // add the Lazy_Fuzzy_Expr<> part if the referenced assignment is a FormalPar lazy or fuzzy
+      bool refd_ass_is_lazy_or_fuzzy_fpar = false;
       switch (ass->get_asstype()) {
       case Assignment::A_PAR_VAL:
       case Assignment::A_PAR_VAL_IN:
       case Assignment::A_PAR_TEMPL_IN:
-        refd_ass_is_lazy_fpar = ass->get_lazy_eval();
-        if (refd_ass_is_lazy_fpar) {
-          *type_str = string("Lazy_Param<") + *type_str + string(">");
+        refd_ass_is_lazy_or_fuzzy_fpar = ass->get_eval_type() != NORMAL_EVAL;
+        if (ass->get_eval_type() != NORMAL_EVAL) {
+          *type_str = string("Lazy_Fuzzy_Expr<") + *type_str + string(">");
         }
         break;
       default:
         break;
       }
       // add the "const" part if the referenced assignment is a constant thing
-      if (!refd_ass_is_lazy_fpar) {
+      if (!refd_ass_is_lazy_or_fuzzy_fpar) {
         switch (ass->get_asstype()) {
         case Assignment::A_CONST:
         case Assignment::A_OC:
@@ -14529,7 +14530,7 @@ void Value::generate_code_expr_encvalue_unichar(expression_struct *expr)
       type_vec->add(type_str);
       // store the C++ reference string
       refd_vec->add(new string(ass->get_genname_from_scope(scope,""))); // the "" parameter makes sure that no casting to type is generated into the string
-      if (refd_ass_is_lazy_fpar) {
+      if (refd_ass_is_lazy_or_fuzzy_fpar) {
         Type* refd_ass_type = ass->get_Type();
         string refd_ass_type_genname = (ass->get_asstype()==Assignment::A_PAR_TEMPL_IN) ? refd_ass_type->get_genname_template(scope) : refd_ass_type->get_genname_value(scope);
         return string("((") + refd_ass_type_genname + string("&)") + get_member_name(refd_vec->size()-1) + string(")");
@@ -14538,15 +14539,15 @@ void Value::generate_code_expr_encvalue_unichar(expression_struct *expr)
       }
     }
 
-    string LazyParamData::get_member_name(size_t idx) {
+    string LazyFuzzyParamData::get_member_name(size_t idx) {
       return string("lpm_") + Int2string(idx);
     }
 
-    string LazyParamData::get_constr_param_name(size_t idx) {
+    string LazyFuzzyParamData::get_constr_param_name(size_t idx) {
       return string("lpp_") + Int2string(idx);
     }
 
-    void LazyParamData::generate_code_for_value(expression_struct* expr, Value* val, Scope* my_scope) {
+    void LazyFuzzyParamData::generate_code_for_value(expression_struct* expr, Value* val, Scope* my_scope) {
       // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
       if (use_runtime_2 && TypeConv::needs_conv_refd(val)) {
         const string& tmp_id = val->get_temporary_id();
@@ -14562,7 +14563,7 @@ void Value::generate_code_expr_encvalue_unichar(expression_struct *expr)
       }
     }
 
-    void LazyParamData::generate_code_for_template(expression_struct* expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* my_scope) {
+    void LazyFuzzyParamData::generate_code_for_template(expression_struct* expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* my_scope) {
       // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
       if (use_runtime_2 && TypeConv::needs_conv_refd(temp->get_Template())) {
         const string& tmp_id = temp->get_Template()->get_temporary_id();
@@ -14580,43 +14581,49 @@ void Value::generate_code_expr_encvalue_unichar(expression_struct *expr)
       } else temp->generate_code(expr, gen_restriction_check);
     }
 
-    void LazyParamData::generate_code(expression_struct *expr, Value* value, Scope* scope) {
-      if (depth<=0) FATAL_ERROR("LazyParamData::generate_code()");
+    void LazyFuzzyParamData::generate_code(expression_struct *expr, Value* value, Scope* scope, boolean lazy) {
+      if (depth<=0) FATAL_ERROR("LazyFuzzyParamData::generate_code()");
       if (depth>1) {
         // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
-        // lazy parameter inside a lazy parameter, call the funcion as a normal call
-        // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
+        // lazy parameter inside a lazy parameter, call the function as a normal call
+        // wrap the calculated parameter value inside a special constructor which calculates the value of its cache immediately
         expression_struct value_expr;
         Code::init_expr(&value_expr);
         generate_code_for_value(&value_expr, value, scope);
-        // the id of the instance of Lazy_Param which will be used as the actual parameter
-        const string& lazy_param_id = value->get_temporary_id();
+        // the id of the instance of Lazy_Fuzzy_Expr, which will be used as the actual parameter
+        const string& param_id = value->get_temporary_id();
         if (value_expr.preamble) {
           expr->preamble = mputstr(expr->preamble, value_expr.preamble);
         }
-        expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
-          value->get_my_governor()->get_genname_value(scope).c_str(), lazy_param_id.c_str(),
-          value->get_my_governor()->get_genname_value(scope).c_str(), value_expr.expr);
+        expr->preamble = mputprintf(expr->preamble, "Lazy_Fuzzy_Expr<%s> %s(%s, Lazy_Fuzzy_Expr<%s>::EXPR_EVALED, %s);\n",
+          value->get_my_governor()->get_genname_value(scope).c_str(), param_id.c_str(),
+          lazy ? "FALSE" : "TRUE", value->get_my_governor()->get_genname_value(scope).c_str(), value_expr.expr);
         Code::free_expr(&value_expr);
-        expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
+        expr->expr = mputstr(expr->expr, param_id.c_str());
         return;
       }
       // only if the formal parameter is *not* used as lvalue
       if (!used_as_lvalue && value->get_valuetype()==Value::V_REFD && value->get_reference()->get_subrefs()==NULL) {
         Assignment* refd_ass = value->get_reference()->get_refd_assignment();
         if (refd_ass) {
-          bool refd_ass_is_lazy_fpar = false;
+          bool refd_ass_is_lazy_or_fuzzy_fpar = false;
           switch (refd_ass->get_asstype()) {
           case Assignment::A_PAR_VAL:
           case Assignment::A_PAR_VAL_IN:
           case Assignment::A_PAR_TEMPL_IN:
-            refd_ass_is_lazy_fpar = refd_ass->get_lazy_eval();
+            refd_ass_is_lazy_or_fuzzy_fpar = refd_ass->get_eval_type() != NORMAL_EVAL;
             break;
           default:
             break;
           }
-          if (refd_ass_is_lazy_fpar) {
-            expr->expr = mputprintf(expr->expr, "%s", refd_ass->get_genname_from_scope(scope,"").c_str());
+          if (refd_ass_is_lazy_or_fuzzy_fpar) {
+            string refd_str = refd_ass->get_genname_from_scope(scope, "");
+            if ((refd_ass->get_eval_type() == LAZY_EVAL && !lazy) ||
+                (refd_ass->get_eval_type() == FUZZY_EVAL && lazy)) {
+              expr->preamble = mputprintf(expr->preamble, "%s.change();\n", refd_str.c_str());
+              expr->postamble = mputprintf(expr->postamble, "%s.revert();\n", refd_str.c_str());
+            }
+            expr->expr = mputprintf(expr->expr, "%s", refd_str.c_str());
             return;
           }
         }
@@ -14625,49 +14632,55 @@ void Value::generate_code_expr_encvalue_unichar(expression_struct *expr)
       expression_struct value_expr;
       Code::init_expr(&value_expr);
       generate_code_for_value(&value_expr, value, scope);
-      // the id of the instance of Lazy_Param which will be used as the actual parameter
-      string lazy_param_id = value->get_temporary_id();
+      // the id of the instance of Lazy_Fuzzy_Expr, which will be used as the actual parameter
+      string param_id = value->get_temporary_id();
       string type_name = value->get_my_governor()->get_genname_value(scope);
-      generate_code_lazyparam_class(expr, value_expr, lazy_param_id, type_name);
+      generate_code_param_class(expr, value_expr, param_id, type_name, lazy);
     }
 
-    void LazyParamData::generate_code(expression_struct *expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* scope) {
-      if (depth<=0) FATAL_ERROR("LazyParamData::generate_code()");
+    void LazyFuzzyParamData::generate_code(expression_struct *expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* scope, boolean lazy) {
+      if (depth<=0) FATAL_ERROR("LazyFuzzyParamData::generate_code()");
       if (depth>1) {
         // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
-        // lazy parameter inside a lazy parameter, call the funcion as a normal call
-        // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
+        // lazy parameter inside a lazy parameter, call the function as a normal call
+        // wrap the calculated parameter value inside a special constructor which calculates the value of its cache immediately
         expression_struct tmpl_expr;
         Code::init_expr(&tmpl_expr);
         generate_code_for_template(&tmpl_expr, temp, gen_restriction_check, scope);
-        // the id of the instance of Lazy_Param which will be used as the actual parameter
-        const string& lazy_param_id = temp->get_Template()->get_temporary_id();
+        // the id of the instance of Lazy_Fuzzy_Expr which will be used as the actual parameter
+        const string& param_id = temp->get_Template()->get_temporary_id();
         if (tmpl_expr.preamble) {
           expr->preamble = mputstr(expr->preamble, tmpl_expr.preamble);
         }
-        expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
-          temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), lazy_param_id.c_str(),
-          temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), tmpl_expr.expr);
+        expr->preamble = mputprintf(expr->preamble, "Lazy_Fuzzy_Expr<%s> %s(%s, Lazy_Fuzzy_Expr<%s>::EXPR_EVALED, %s);\n",
+          temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), param_id.c_str(),
+          lazy ? "FALSE" : "TRUE", temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), tmpl_expr.expr);
         Code::free_expr(&tmpl_expr);
-        expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
+        expr->expr = mputstr(expr->expr, param_id.c_str());
         return;
       }
       // only if the formal parameter is *not* used as lvalue
       if (!used_as_lvalue && temp->get_Template()->get_templatetype()==Template::TEMPLATE_REFD && temp->get_Template()->get_reference()->get_subrefs()==NULL) {
         Assignment* refd_ass = temp->get_Template()->get_reference()->get_refd_assignment();
         if (refd_ass) {
-          bool refd_ass_is_lazy_fpar = false;
+          bool refd_ass_is_lazy_or_fuzzy_fpar = false;
           switch (refd_ass->get_asstype()) {
           case Assignment::A_PAR_VAL:
           case Assignment::A_PAR_VAL_IN:
           case Assignment::A_PAR_TEMPL_IN:
-            refd_ass_is_lazy_fpar = refd_ass->get_lazy_eval();
+            refd_ass_is_lazy_or_fuzzy_fpar = refd_ass->get_eval_type() != NORMAL_EVAL;
             break;
           default:
             break;
           }
-          if (refd_ass_is_lazy_fpar) {
-            expr->expr = mputprintf(expr->expr, "%s", refd_ass->get_genname_from_scope(scope,"").c_str());
+          if (refd_ass_is_lazy_or_fuzzy_fpar) {
+            string refd_str = refd_ass->get_genname_from_scope(scope, "");
+            if ((refd_ass->get_eval_type() == LAZY_EVAL && !lazy) ||
+                (refd_ass->get_eval_type() == FUZZY_EVAL && lazy)) {
+              expr->preamble = mputprintf(expr->preamble, "%s.change();\n", refd_str.c_str());
+              expr->postamble = mputprintf(expr->postamble, "%s.revert();\n", refd_str.c_str());
+            }
+            expr->expr = mputprintf(expr->expr, "%s", refd_str.c_str());
             return;
           }
         }
@@ -14676,33 +14689,32 @@ void Value::generate_code_expr_encvalue_unichar(expression_struct *expr)
       expression_struct tmpl_expr;
       Code::init_expr(&tmpl_expr);
       generate_code_for_template(&tmpl_expr, temp, gen_restriction_check, scope);
-      // the id of the instance of Lazy_Param which will be used as the actual parameter
-      string lazy_param_id = temp->get_Template()->get_temporary_id();
+      // the id of the instance of Lazy_Fuzzy_Expr which will be used as the actual parameter
+      string param_id = temp->get_Template()->get_temporary_id();
       string type_name = temp->get_Template()->get_my_governor()->get_genname_template(scope);
-      generate_code_lazyparam_class(expr, tmpl_expr, lazy_param_id, type_name);
+      generate_code_param_class(expr, tmpl_expr, param_id, type_name, lazy);
     }
 
-    void LazyParamData::generate_code_lazyparam_class(expression_struct *expr, expression_struct& param_expr, const string& lazy_param_id, const string& type_name) {
-      expr->preamble = mputprintf(expr->preamble, "class Lazy_Param_%s : public Lazy_Param<%s> {\n", lazy_param_id.c_str(), type_name.c_str());
-      if (type_vec->size()>0) {
-        // private members of the local class will be const references to the objects referenced by the expression
-        for (size_t i=0; i<type_vec->size(); i++) {
-          expr->preamble = mputprintf(expr->preamble, "%s& %s;\n", (*type_vec)[i]->c_str(), get_member_name(i).c_str());
-        }
-        expr->preamble = mputstr(expr->preamble, "public:\n");
-        expr->preamble = mputprintf(expr->preamble, "Lazy_Param_%s(", lazy_param_id.c_str());
-        for (size_t i=0; i<type_vec->size(); i++) {
+    void LazyFuzzyParamData::generate_code_param_class(expression_struct *expr, expression_struct& param_expr, const string& param_id, const string& type_name, boolean lazy) {
+      expr->preamble = mputprintf(expr->preamble,
+        "class Lazy_Fuzzy_Expr_%s : public Lazy_Fuzzy_Expr<%s> {\n",
+          param_id.c_str(), type_name.c_str());
+      // private members of the local class will be const references to the objects referenced by the expression
+      for (size_t i=0; i<type_vec->size(); i++) {
+        expr->preamble = mputprintf(expr->preamble, "%s& %s;\n", (*type_vec)[i]->c_str(), get_member_name(i).c_str());
+      }
+      expr->preamble = mputstr(expr->preamble, "public:\n");
+      expr->preamble = mputprintf(expr->preamble, "Lazy_Fuzzy_Expr_%s(", param_id.c_str());
+      for (size_t i=0; i<type_vec->size(); i++) {
           if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
           expr->preamble = mputprintf(expr->preamble, "%s& %s", (*type_vec)[i]->c_str(), get_constr_param_name(i).c_str());
-        }
-        expr->preamble = mputstr(expr->preamble, "): ");
-        for (size_t i=0; i<type_vec->size(); i++) {
-          if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
-          expr->preamble = mputprintf(expr->preamble, "%s(%s)", get_member_name(i).c_str(), get_constr_param_name(i).c_str());
-        }
-        expr->preamble = mputstr(expr->preamble, " {}\n");
-        expr->preamble = mputstr(expr->preamble, "private:\n");
       }
+      expr->preamble = mputprintf(expr->preamble, "): Lazy_Fuzzy_Expr(%s)", lazy ? "FALSE" : "TRUE");
+      for (size_t i=0; i<type_vec->size(); i++) {
+        expr->preamble = mputprintf(expr->preamble, ", %s(%s)", get_member_name(i).c_str(), get_constr_param_name(i).c_str());
+      }
+      expr->preamble = mputstr(expr->preamble, " {}\n");
+      expr->preamble = mputstr(expr->preamble, "private:\n");
       expr->preamble = mputstr(expr->preamble, "virtual void eval_expr() {\n");
       // use the temporary expr structure to fill the body of the eval_expr() function
       if (param_expr.preamble) {
@@ -14716,7 +14728,7 @@ void Value::generate_code_expr_encvalue_unichar(expression_struct *expr)
       expr->preamble = mputstr(expr->preamble, "}\n"
         "};\n" // end of local class definition
       );
-      expr->preamble = mputprintf(expr->preamble, "Lazy_Param_%s %s", lazy_param_id.c_str(), lazy_param_id.c_str());
+      expr->preamble = mputprintf(expr->preamble, "Lazy_Fuzzy_Expr_%s %s", param_id.c_str(), param_id.c_str());
       if (type_vec->size()>0) {
         expr->preamble = mputc(expr->preamble, '(');
         // paramteres of the constructor are references to the objects used in the expression
@@ -14727,15 +14739,15 @@ void Value::generate_code_expr_encvalue_unichar(expression_struct *expr)
         expr->preamble = mputc(expr->preamble, ')');
       }
       expr->preamble = mputstr(expr->preamble, ";\n");
-      // the instance of the local class Lazy_Param_tmp_xxx is used as the actual parameter
-      expr->expr = mputprintf(expr->expr, "%s", lazy_param_id.c_str());
+      // the instance of the local class Lazy_Fuzzy_Expr_tmp_xxx is used as the actual parameter
+      expr->expr = mputprintf(expr->expr, "%s", param_id.c_str());
     }
 
-    void LazyParamData::generate_code_ap_default_ref(expression_struct *expr, Ttcn::Ref_base* ref, Scope* scope) {
+    void LazyFuzzyParamData::generate_code_ap_default_ref(expression_struct *expr, Ttcn::Ref_base* ref, Scope* scope, boolean lazy) {
       expression_struct ref_expr;
       Code::init_expr(&ref_expr);
       ref->generate_code(&ref_expr);
-      const string& lazy_param_id = scope->get_scope_mod_gen()->get_temporary_id();
+      const string& param_id = scope->get_scope_mod_gen()->get_temporary_id();
       if (ref_expr.preamble) {
          expr->preamble = mputstr(expr->preamble, ref_expr.preamble);
       }
@@ -14754,29 +14766,31 @@ void Value::generate_code_expr_encvalue_unichar(expression_struct *expr)
       default:
         type_str = ass->get_Type()->get_genname_value(scope);
       }
-      expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
-        type_str.c_str(), lazy_param_id.c_str(), type_str.c_str(), ref_expr.expr);
+      expr->preamble = mputprintf(expr->preamble, "Lazy_Fuzzy_Expr<%s> %s(%s, Lazy_Fuzzy_Expr<%s>::EXPR_EVALED, %s);\n",
+        type_str.c_str(), param_id.c_str(), lazy ? "FALSE" : "TRUE", type_str.c_str(), ref_expr.expr);
       if (ref_expr.postamble) {
         expr->postamble = mputstr(expr->postamble, ref_expr.postamble);
       }
       Code::free_expr(&ref_expr);
-      expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
+      expr->expr = mputstr(expr->expr, param_id.c_str());
     }
 
-    void LazyParamData::generate_code_ap_default_value(expression_struct *expr, Value* value, Scope* scope) {
-      const string& lazy_param_id = value->get_temporary_id();
-      expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
-        value->get_my_governor()->get_genname_value(scope).c_str(), lazy_param_id.c_str(),
-        value->get_my_governor()->get_genname_value(scope).c_str(), value->get_genname_own(scope).c_str());
-      expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
+    void LazyFuzzyParamData::generate_code_ap_default_value(expression_struct *expr, Value* value, Scope* scope, boolean lazy) {
+      const string& param_id = value->get_temporary_id();
+      expr->preamble = mputprintf(expr->preamble, "Lazy_Fuzzy_Expr<%s> %s(%s, Lazy_Fuzzy_Expr<%s>::EXPR_EVALED, %s);\n",
+        value->get_my_governor()->get_genname_value(scope).c_str(), param_id.c_str(),
+        lazy ? "FALSE" : "TRUE", value->get_my_governor()->get_genname_value(scope).c_str(),
+        value->get_genname_own(scope).c_str());
+      expr->expr = mputstr(expr->expr, param_id.c_str());
     }
 
-    void LazyParamData::generate_code_ap_default_ti(expression_struct *expr, TemplateInstance* ti, Scope* scope) {
-      const string& lazy_param_id = ti->get_Template()->get_temporary_id();
-      expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
-        ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), lazy_param_id.c_str(),
-        ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), ti->get_Template()->get_genname_own(scope).c_str());
-      expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
+    void LazyFuzzyParamData::generate_code_ap_default_ti(expression_struct *expr, TemplateInstance* ti, Scope* scope, boolean lazy) {
+      const string& param_id = ti->get_Template()->get_temporary_id();
+      expr->preamble = mputprintf(expr->preamble, "Lazy_Fuzzy_Expr<%s> %s(%s, Lazy_Fuzzy_Expr<%s>::EXPR_EVALED, %s);\n",
+        ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), param_id.c_str(),
+        lazy ? "FALSE" : "TRUE", ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), 
+        ti->get_Template()->get_genname_own(scope).c_str());
+      expr->expr = mputstr(expr->expr, param_id.c_str());
     }
 
 } // namespace Common
diff --git a/compiler2/Value.hh b/compiler2/Value.hh
index ba32dd28e34a2779829313b276e62afe4a99e6f9..e34c93ec7286352f1242ffd001fb1e0371818c8c 100644
--- a/compiler2/Value.hh
+++ b/compiler2/Value.hh
@@ -1027,13 +1027,13 @@ namespace Common {
 
   /** @} end of AST_Value group */
 
-  class LazyParamData {
-    static int depth; // recursive code generation: calling a func. with lazy param inside a lazy param
+  class LazyFuzzyParamData {
+    static int depth; // recursive code generation: calling a func. with lazy/fuzzy param inside a lazy/fuzzy param
     static bool used_as_lvalue;
     static vector<string>* type_vec;
     static vector<string>* refd_vec;
   public:
-    static bool in_lazy();
+    static bool in_lazy_or_fuzzy();
     static void init(bool p_used_as_lvalue);
     static void clean();
     static string add_ref_genname(Assignment* ass, Scope* scope);
@@ -1041,12 +1041,12 @@ namespace Common {
     static string get_constr_param_name(size_t idx);
     static void generate_code_for_value(expression_struct* expr, Value* val, Scope* my_scope);
     static void generate_code_for_template(expression_struct* expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* my_scope);
-    static void generate_code(expression_struct *expr, Value* value, Scope* scope);
-    static void generate_code(expression_struct *expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* scope);
-    static void generate_code_lazyparam_class(expression_struct *expr, expression_struct& param_expr, const string& lazy_param_id, const string& type_name);
-    static void generate_code_ap_default_ref(expression_struct *expr, Ttcn::Ref_base* ref, Scope* scope);
-    static void generate_code_ap_default_value(expression_struct *expr, Value* value, Scope* scope);
-    static void generate_code_ap_default_ti(expression_struct *expr, TemplateInstance* ti, Scope* scope);
+    static void generate_code(expression_struct *expr, Value* value, Scope* scope, boolean lazy);
+    static void generate_code(expression_struct *expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* scope, boolean lazy);
+    static void generate_code_param_class(expression_struct *expr, expression_struct& param_expr, const string& param_id, const string& type_name, boolean lazy);
+    static void generate_code_ap_default_ref(expression_struct *expr, Ttcn::Ref_base* ref, Scope* scope, boolean lazy);
+    static void generate_code_ap_default_value(expression_struct *expr, Value* value, Scope* scope, boolean lazy);
+    static void generate_code_ap_default_ti(expression_struct *expr, TemplateInstance* ti, Scope* scope, boolean lazy);
   };
   
 } // namespace Common
diff --git a/compiler2/ttcn3/AST_ttcn3.cc b/compiler2/ttcn3/AST_ttcn3.cc
index 30393a8fd17ae4b963238cf7b77c3d0b94a7a2b8..e664433f7530cee11fe29a735e2732720b843682 100644
--- a/compiler2/ttcn3/AST_ttcn3.cc
+++ b/compiler2/ttcn3/AST_ttcn3.cc
@@ -692,8 +692,8 @@ namespace Ttcn {
       expr->expr = mputc(expr->expr, ')');
     } else {
       expr->expr = mputstr(expr->expr,
-        LazyParamData::in_lazy() ?
-        LazyParamData::add_ref_genname(ass, my_scope).c_str() :
+        LazyFuzzyParamData::in_lazy_or_fuzzy() ?
+        LazyFuzzyParamData::add_ref_genname(ass, my_scope).c_str() :
         ass->get_genname_from_scope(my_scope).c_str());
     }
     if (subrefs.get_nof_refs() > 0) subrefs.generate_code(expr, ass);
@@ -755,8 +755,8 @@ namespace Ttcn {
       expr->expr = mputc(expr->expr, ')');
     } else {
       expr->expr = mputstr(expr->expr,
-        LazyParamData::in_lazy() ?
-        LazyParamData::add_ref_genname(ass, my_scope).c_str() :
+        LazyFuzzyParamData::in_lazy_or_fuzzy() ?
+        LazyFuzzyParamData::add_ref_genname(ass, my_scope).c_str() :
         ass->get_genname_from_scope(my_scope).c_str());
     }
     expr->expr = mputstr(expr->expr, ")");
@@ -996,7 +996,7 @@ namespace Ttcn {
     if (!Ref_base::has_single_expr()) return false;
     for (size_t i = 0; i < parlist.get_nof_pars(); i++)
       if (!parlist.get_par(i)->has_single_expr()) return false;
-    // if any formal parameter has lazy evaluation 
+    // if any formal parameter has lazy or fuzzy evaluation 
     Common::Assignment *ass = get_refd_assignment();
     if (ass) {
       const FormalParList *fplist = ass->get_FormalParList();
@@ -1004,7 +1004,7 @@ namespace Ttcn {
         size_t num_formal = fplist->get_nof_fps();
         for (size_t i=0; i<num_formal; ++i) {
           const FormalPar *fp = fplist->get_fp_byIndex(i);
-          if (fp->get_lazy_eval()) return false;
+          if (fp->get_eval_type() != NORMAL_EVAL) return false;
         }
       }
     }
@@ -6409,7 +6409,7 @@ namespace Ttcn {
       body = mprintf("if (!strcmp(function_name, \"%s\")) {\n",
         dispname_str);
       if (nof_fps > 0) {
-        body = fp_list->generate_code_object(body, "", ' ');
+        body = fp_list->generate_code_object(body, "", ' ', true);
         for (size_t i = 0; i < nof_fps; i++) {
           body = mputprintf(body, "%s.decode_text(function_arguments);\n",
             fp_list->get_fp_byIndex(i)->get_reference_name(my_scope).c_str());
@@ -7914,10 +7914,10 @@ namespace Ttcn {
   // =================================
 
   FormalPar::FormalPar(asstype_t p_asstype, Type *p_type, Identifier* p_name,
-    TemplateInstance *p_defval, bool p_lazy_eval)
+    TemplateInstance *p_defval, param_eval_t p_eval)
     : Definition(p_asstype, p_name), type(p_type), my_parlist(0),
     used_as_lvalue(false), template_restriction(TR_NONE),
-    lazy_eval(p_lazy_eval), defval_generated(false), usage_found(false)
+    eval(p_eval), defval_generated(false), usage_found(false)
   {
     switch (p_asstype) {
     case A_PAR_VAL:
@@ -7940,10 +7940,10 @@ namespace Ttcn {
 
   FormalPar::FormalPar(asstype_t p_asstype,
     template_restriction_t p_template_restriction, Type *p_type,
-    Identifier* p_name, TemplateInstance *p_defval, bool p_lazy_eval)
+    Identifier* p_name, TemplateInstance *p_defval, param_eval_t p_eval)
     : Definition(p_asstype, p_name), type(p_type), my_parlist(0),
     used_as_lvalue(false), template_restriction(p_template_restriction),
-    lazy_eval(p_lazy_eval), defval_generated(false), usage_found(false)
+    eval(p_eval), defval_generated(false), usage_found(false)
   {
     switch (p_asstype) {
     case A_PAR_TEMPL_IN:
@@ -7962,7 +7962,7 @@ namespace Ttcn {
   FormalPar::FormalPar(asstype_t p_asstype, Identifier* p_name,
     TemplateInstance *p_defval)
     : Definition(p_asstype, p_name), type(0), my_parlist(0),
-    used_as_lvalue(false), template_restriction(TR_NONE), lazy_eval(false),
+    used_as_lvalue(false), template_restriction(TR_NONE), eval(NORMAL_EVAL),
     defval_generated(false), usage_found(false)
   {
     if (p_asstype != A_PAR_TIMER)
@@ -8667,9 +8667,9 @@ namespace Ttcn {
       else {
         // update the genname so that all references in the generated code
         // will point to the shadow object
-  if (!lazy_eval) {
+        if (eval == NORMAL_EVAL) {
           set_genname(id->get_name() + "_shadow");
-  }
+        }
         used_as_lvalue = true;
       }
     }
@@ -8756,8 +8756,8 @@ namespace Ttcn {
     const char *name_str = display_name ? id->get_name().c_str() : "";
     switch (asstype) {
     case A_PAR_VAL_IN:
-      if (lazy_eval) {
-        str = mputprintf(str, "Lazy_Param<%s>& %s", type->get_genname_value(my_scope).c_str(), name_str);
+      if (eval != NORMAL_EVAL) {
+        str = mputprintf(str, "Lazy_Fuzzy_Expr<%s>& %s", type->get_genname_value(my_scope).c_str(), name_str);
       } else {
         str = mputprintf(str, "const %s& %s", type->get_genname_value(my_scope).c_str(), name_str);
       }
@@ -8769,8 +8769,8 @@ namespace Ttcn {
         name_str);
       break;
     case A_PAR_TEMPL_IN:
-      if (lazy_eval) {
-        str = mputprintf(str, "Lazy_Param<%s>& %s", type->get_genname_template(my_scope).c_str(), name_str);
+      if (eval != NORMAL_EVAL) {
+        str = mputprintf(str, "Lazy_Fuzzy_Expr<%s>& %s", type->get_genname_template(my_scope).c_str(), name_str);
       } else {
         str = mputprintf(str, "const %s& %s", type->get_genname_template(my_scope).c_str(), name_str);
       }
@@ -8792,7 +8792,7 @@ namespace Ttcn {
   string FormalPar::get_reference_name(Scope* scope) const
   {
     string ret_val;
-    if (lazy_eval) {
+    if (eval != NORMAL_EVAL) {
       ret_val += "((";
       switch (asstype) {
       case A_PAR_TEMPL_IN:
@@ -8805,19 +8805,24 @@ namespace Ttcn {
       ret_val += "&)";
     }
     ret_val += get_id().get_name();
-    if (lazy_eval) {
+    if (eval != NORMAL_EVAL) {
       ret_val += ")";
     }
     return ret_val;
   }
 
-  char *FormalPar::generate_code_object(char *str, const char *p_prefix, char refch)
+  char *FormalPar::generate_code_object(char *str, const char *p_prefix, char refch, bool gen_init)
   {
     const char *name_str = id->get_name().c_str();
     switch (asstype) {
     case A_PAR_VAL_IN:
-      if (lazy_eval) {
-        str = mputprintf(str, "Lazy_Param<%s> %s%s;\n", type->get_genname_value(my_scope).c_str(), p_prefix, name_str);
+      if (eval != NORMAL_EVAL) {
+        str = mputprintf(str, "Lazy_Fuzzy_Expr<%s> %s%s",
+          type->get_genname_value(my_scope).c_str(), p_prefix, name_str);
+        if (gen_init) {
+          str = mputprintf(str, "(%s)", eval == LAZY_EVAL ? "FALSE" : "TRUE");
+        }
+        str = mputstr(str, ";\n");
       } else {
         str = mputprintf(str, "%s %s%s;\n", type->get_genname_value(my_scope).c_str(), p_prefix, name_str);
       }
@@ -8829,8 +8834,13 @@ namespace Ttcn {
         type->get_genname_value(my_scope).c_str(), refch, p_prefix, name_str);
       break;
     case A_PAR_TEMPL_IN:
-      if (lazy_eval) {
-        str = mputprintf(str, "Lazy_Param<%s> %s%s;\n", type->get_genname_template(my_scope).c_str(), p_prefix, name_str);
+      if (eval != NORMAL_EVAL) {
+        str = mputprintf(str, "Lazy_Fuzzy_Expr<%s> %s%s",
+          type->get_genname_template(my_scope).c_str(), p_prefix, name_str);
+        if (gen_init) {
+          str = mputprintf(str, "(%s)", eval == LAZY_EVAL ? "FALSE" : "TRUE");
+        }
+        str = mputstr(str, ";\n");
       } else {
         str = mputprintf(str, "%s %s%s;\n", type->get_genname_template(my_scope).c_str(), p_prefix, name_str);
       }
@@ -8853,7 +8863,7 @@ namespace Ttcn {
   {
     if ((used_as_lvalue || (use_runtime_2 && usage_found &&
         my_parlist->get_my_def()->get_asstype() == Definition::A_ALTSTEP))
-        && !lazy_eval) {
+        && eval == NORMAL_EVAL) {
       const string& t_genname = get_genname();
       const char *genname_str = t_genname.c_str();
       const char *name_str = id->get_name().c_str();
@@ -9108,14 +9118,15 @@ namespace Ttcn {
     }
   }
 
-  // check that @lazy paramterization not used in cases currently unsupported
-  void FormalParList::chk_noLazyParams() {
+  // check that @lazy and @fuzzy paramterization are not used in cases currently unsupported
+  void FormalParList::chk_noLazyFuzzyParams() {
     Error_Context cntxt(this, "In formal parameter list");
     for (size_t i = 0; i < pars_v.size(); i++) {
       FormalPar *par = pars_v[i];
-      if (par->get_lazy_eval()) {
-        par->error("Formal parameter `%s' cannot be @lazy, not supported in this case.",
-          par->get_id().get_dispname().c_str());
+      if (par->get_eval_type() != NORMAL_EVAL) {
+        par->error("Formal parameter `%s' cannot be @%s, not supported in this case.",
+          par->get_id().get_dispname().c_str(),
+          par->get_eval_type() == LAZY_EVAL ? "lazy" : "fuzzy");
       }
     }
   }
@@ -9208,8 +9219,8 @@ namespace Ttcn {
             get_template_restriction()));
       }
       // check for @lazy equivalence
-      if (type_par->get_lazy_eval()!=function_par->get_lazy_eval()) {
-        function_par->error("Parameter @lazy-ness mismatch");
+      if (type_par->get_eval_type()!=function_par->get_eval_type()) {
+        function_par->error("Parameter evaluation type (normal, @lazy or @fuzzy) mismatch");
       }
       // check for name equivalence
       const Identifier& type_par_id = type_par->get_id();
@@ -9520,10 +9531,10 @@ namespace Ttcn {
     return str;
   }
 
-  char *FormalParList::generate_code_object(char *str, const char *p_prefix, char refch)
+  char *FormalParList::generate_code_object(char *str, const char *p_prefix, char refch, bool gen_init)
   {
     for (size_t i = 0; i < pars_v.size(); i++)
-      str = pars_v[i]->generate_code_object(str, p_prefix, refch);
+      str = pars_v[i]->generate_code_object(str, p_prefix, refch, gen_init);
     return str;
   }
 
@@ -9775,14 +9786,14 @@ namespace Ttcn {
   void ActualPar::generate_code(expression_struct *expr, bool copy_needed,
                                 FormalPar* formal_par) const
   {
-    bool lazy_param = formal_par != NULL ? formal_par->get_lazy_eval() : false;
+    param_eval_t param_eval = formal_par != NULL ? formal_par->get_eval_type() : NORMAL_EVAL;
     bool used_as_lvalue = formal_par != NULL ? formal_par->get_used_as_lvalue() : false;
     switch (selection) {
     case AP_VALUE:
-      if (lazy_param) { // copy_needed doesn't matter in this case
-        LazyParamData::init(used_as_lvalue);
-        LazyParamData::generate_code(expr, val, my_scope);
-        LazyParamData::clean();
+      if (param_eval != NORMAL_EVAL) { // copy_needed doesn't matter in this case
+        LazyFuzzyParamData::init(used_as_lvalue);
+        LazyFuzzyParamData::generate_code(expr, val, my_scope, param_eval == LAZY_EVAL);
+        LazyFuzzyParamData::clean();
         if (val->get_valuetype() == Value::V_REFD) {
           // check if the reference is a parameter, mark it as used if it is
           Reference* r = dynamic_cast<Reference*>(val->get_reference());
@@ -9791,8 +9802,7 @@ namespace Ttcn {
           }
         }
       } else {
-        if (copy_needed) expr->expr = mputprintf(expr->expr, "%s(",
-          val->get_my_governor()->get_genname_value(my_scope).c_str());
+        char* expr_expr = NULL;
         if (use_runtime_2 && TypeConv::needs_conv_refd(val)) {
           // Generate everything to preamble to be able to tackle the wrapper
           // constructor call.  TODO: Reduce the number of temporaries created.
@@ -9803,16 +9813,44 @@ namespace Ttcn {
             tmp_id_str);
           expr->preamble = TypeConv::gen_conv_code_refd(expr->preamble,
             tmp_id_str, val);
-          expr->expr = mputstr(expr->expr, tmp_id_str);
-        } else val->generate_code_expr(expr);
+          expr_expr = mputstr(expr_expr, tmp_id_str);
+        } else {
+          expression_struct val_expr;
+          Code::init_expr(&val_expr);
+          val->generate_code_expr(&val_expr);
+          if (val_expr.preamble != NULL) {
+            expr->preamble = mputstr(expr->preamble, val_expr.preamble);
+          }
+          if (val_expr.postamble == NULL) {
+            expr_expr = mputstr(expr_expr, val_expr.expr);
+          }
+          else {
+            // make sure the postambles of the parameters are executed before the
+            // function call itself (needed if the value contains function calls
+            // with lazy or fuzzy parameters)
+            const string& tmp_id = val->get_temporary_id();
+            expr->preamble = mputprintf(expr->preamble, "%s %s(%s);\n",
+              val->get_my_governor()->get_genname_value(my_scope).c_str(),
+              tmp_id.c_str(), val_expr.expr);
+            expr->preamble = mputstr(expr->preamble, val_expr.postamble);
+            expr_expr = mputstr(expr_expr, tmp_id.c_str());
+            copy_needed = false; // already copied
+          }
+          Code::free_expr(&val_expr);
+        }
+        if (copy_needed) expr->expr = mputprintf(expr->expr, "%s(",
+          val->get_my_governor()->get_genname_value(my_scope).c_str());
+        expr->expr = mputstr(expr->expr, expr_expr);
+        Free(expr_expr);
         if (copy_needed) expr->expr = mputc(expr->expr, ')');
       }
       break;
     case AP_TEMPLATE:
-      if (lazy_param) { // copy_needed doesn't matter in this case
-        LazyParamData::init(used_as_lvalue);
-        LazyParamData::generate_code(expr, temp, gen_restriction_check, my_scope);
-        LazyParamData::clean();
+      if (param_eval != NORMAL_EVAL) { // copy_needed doesn't matter in this case
+        LazyFuzzyParamData::init(used_as_lvalue);
+        LazyFuzzyParamData::generate_code(expr, temp, gen_restriction_check, my_scope,
+           param_eval == LAZY_EVAL);
+        LazyFuzzyParamData::clean();
         if (temp->get_DerivedRef() != NULL ||
             temp->get_Template()->get_templatetype() == Template::TEMPLATE_REFD) {
           // check if the reference is a parameter, mark it as used if it is
@@ -9823,9 +9861,7 @@ namespace Ttcn {
           }
         }
       } else {
-        if (copy_needed)
-          expr->expr = mputprintf(expr->expr, "%s(", temp->get_Template()
-            ->get_my_governor()->get_genname_template(my_scope).c_str());
+        char* expr_expr = NULL;
         if (use_runtime_2 && TypeConv::needs_conv_refd(temp->get_Template())) {
           const string& tmp_id = temp->get_Template()->get_temporary_id();
           const char *tmp_id_str = tmp_id.c_str();
@@ -9838,13 +9874,41 @@ namespace Ttcn {
           if (gen_restriction_check != TR_NONE)
             expr->preamble = Template::generate_restriction_check_code(
               expr->preamble, tmp_id_str, gen_restriction_check);
-          expr->expr = mputstr(expr->expr, tmp_id_str);
-        } else temp->generate_code(expr, gen_restriction_check);
+          expr_expr = mputstr(expr_expr, tmp_id_str);
+        } else {
+          expression_struct temp_expr;
+          Code::init_expr(&temp_expr);
+          temp->generate_code(&temp_expr, gen_restriction_check);
+          if (temp_expr.preamble != NULL) {
+            expr->preamble = mputstr(expr->preamble, temp_expr.preamble);
+          }
+          if (temp_expr.postamble == NULL) {
+            expr_expr = mputstr(expr_expr, temp_expr.expr);
+          }
+          else {
+            // make sure the postambles of the parameters are executed before the
+            // function call itself (needed if the template contains function calls
+            // with lazy or fuzzy parameters)
+            const string& tmp_id = val->get_temporary_id();
+            expr->preamble = mputprintf(expr->preamble, "%s %s(%s);\n",
+              temp->get_Template()->get_my_governor()->get_genname_template(my_scope).c_str(),
+              tmp_id.c_str(), temp_expr.expr);
+            expr->preamble = mputstr(expr->preamble, temp_expr.postamble);
+            expr_expr = mputstr(expr_expr, tmp_id.c_str());
+            copy_needed = false; // already copied
+          }
+          Code::free_expr(&temp_expr);
+        }
+        if (copy_needed)
+          expr->expr = mputprintf(expr->expr, "%s(", temp->get_Template()
+            ->get_my_governor()->get_genname_template(my_scope).c_str());
+        expr->expr = mputstr(expr->expr, expr_expr);
+        Free(expr_expr);
         if (copy_needed) expr->expr = mputc(expr->expr, ')');
       }
       break;
     case AP_REF: {
-      if (lazy_param) FATAL_ERROR("ActualPar::generate_code()"); // syntax error should have already happened
+      if (param_eval != NORMAL_EVAL) FATAL_ERROR("ActualPar::generate_code()"); // syntax error should have already happened
       if (copy_needed) FATAL_ERROR("ActualPar::generate_code()");
       bool is_restricted_template = gen_restriction_check != TR_NONE ||
         gen_post_restriction_check != TR_NONE;
@@ -9925,22 +9989,25 @@ namespace Ttcn {
       if (copy_needed) FATAL_ERROR("ActualPar::generate_code()");
       switch (act->selection) {
       case AP_REF:
-        if (lazy_param) {
-          LazyParamData::generate_code_ap_default_ref(expr, act->ref, my_scope);
+        if (param_eval != NORMAL_EVAL) {
+          LazyFuzzyParamData::generate_code_ap_default_ref(expr, act->ref, my_scope,
+            param_eval == LAZY_EVAL);
         } else {
           act->ref->generate_code(expr);
         }
         break;
       case AP_VALUE:
-        if (lazy_param) {
-          LazyParamData::generate_code_ap_default_value(expr, act->val, my_scope);
+        if (param_eval != NORMAL_EVAL) {
+          LazyFuzzyParamData::generate_code_ap_default_value(expr, act->val, my_scope,
+            param_eval == LAZY_EVAL);
         } else {
           expr->expr = mputstr(expr->expr, act->val->get_genname_own(my_scope).c_str());
         }
         break;
       case AP_TEMPLATE:
-        if (lazy_param) {
-          LazyParamData::generate_code_ap_default_ti(expr, act->temp, my_scope);
+        if (param_eval != NORMAL_EVAL) {
+          LazyFuzzyParamData::generate_code_ap_default_ti(expr, act->temp, my_scope,
+            param_eval == LAZY_EVAL);
         } else {
           expr->expr = mputstr(expr->expr, act->temp->get_Template()->get_genname_own(my_scope).c_str());
         }
@@ -10241,8 +10308,8 @@ namespace Ttcn {
               Code::init_expr(&array_expr);
               // the array object's name contains the reference, followed by
               // the subrefs before the current array ref
-              array_expr.expr = mcopystr(LazyParamData::in_lazy() ?
-                LazyParamData::add_ref_genname(ass, ref->get_my_scope()).c_str() :
+              array_expr.expr = mcopystr(LazyFuzzyParamData::in_lazy_or_fuzzy() ?
+                LazyFuzzyParamData::add_ref_genname(ass, ref->get_my_scope()).c_str() :
                 ass->get_genname_from_scope(ref->get_my_scope()).c_str());
               if (ref_i > 0) {
                 subrefs->generate_code(&array_expr, ass, ref_i);
diff --git a/compiler2/ttcn3/AST_ttcn3.hh b/compiler2/ttcn3/AST_ttcn3.hh
index dd1cda7c3f05063d9d489e90bfe63e9e4acf42f0..00ee997815500b427fa078f73aa781483912eeec 100644
--- a/compiler2/ttcn3/AST_ttcn3.hh
+++ b/compiler2/ttcn3/AST_ttcn3.hh
@@ -1634,8 +1634,8 @@ namespace Ttcn {
     bool used_as_lvalue;
     /** restriction on template value */
     template_restriction_t template_restriction;
-    /** normal or lazy evaluation parametrization should be used */
-    bool lazy_eval;
+    /** normal, lazy or fuzzy evaluation parametrization should be used */
+    param_eval_t eval;
     /** Flag that indicates whether the C++ code for the parameter's default
       * value has been generated or not. */
     bool defval_generated;
@@ -1649,11 +1649,11 @@ namespace Ttcn {
     FormalPar& operator=(const FormalPar& p);
   public:
     FormalPar(asstype_t p_asstype, Type *p_type, Identifier* p_name,
-      TemplateInstance *p_defval, bool p_lazy_eval=false);
+      TemplateInstance *p_defval, param_eval_t p_eval = NORMAL_EVAL);
     FormalPar(asstype_t p_asstype,
       template_restriction_t p_template_restriction,
       Type *p_type, Identifier* p_name, TemplateInstance *p_defval,
-      bool p_lazy_eval=false);
+      param_eval_t p_eval = NORMAL_EVAL);
     FormalPar(asstype_t p_asstype, Identifier* p_name,
       TemplateInstance *p_defval);
     ~FormalPar();
@@ -1716,7 +1716,7 @@ namespace Ttcn {
      * The \a refch parameter is needed when the code for start_ptc_function is
      * generated, because reference is generated in case of inout parameters. */
     char *generate_code_object(char *str, const char *p_prefix,
-      char refch = '&');
+      char refch = '&', bool gen_init = false);
     /** Generates a C++ statement that instantiates a shadow object for the
      * parameter when necessary. It is used when the value of an 'in' value or
      * template parameter is overwritten within the function body. */
@@ -1727,7 +1727,7 @@ namespace Ttcn {
     virtual void dump_internal(unsigned level) const;
     template_restriction_t get_template_restriction()
       { return template_restriction; }
-    virtual bool get_lazy_eval() const { return lazy_eval; }
+    virtual param_eval_t get_eval_type() const { return eval; }
     // code generation: get the C++ string that refers to the formal parameter
     // adds a casting to data type if wrapped into a lazy param
     string get_reference_name(Scope* scope) const;
@@ -1779,7 +1779,7 @@ namespace Ttcn {
     /** Checks the parameter list, which belongs to definition of type
      * \a deftype. */
     void chk(Definition::asstype_t deftype);
-    void chk_noLazyParams();
+    void chk_noLazyFuzzyParams();
     /** Checks the parameter list for startability: reports error if the owner
      * function cannot be started on a PTC. Used by functions and function
      * types. Parameter \a p_what shall contain "Function" or "Function type",
@@ -1834,7 +1834,7 @@ namespace Ttcn {
      * The \a refch parameter is needed when the code for start_ptc_function is
      * generated, because reference is generated in case of inout parameters. */
     char *generate_code_object(char *str, const char *p_prefix,
-      char refch = '&');
+      char refch = '&', bool gen_init = false);
     /** Generates the C++ shadow objects for all parameters. */
     char *generate_shadow_objects(char *str) const;
     char *generate_code_set_unbound(char *str) const;
diff --git a/compiler2/ttcn3/compiler.y b/compiler2/ttcn3/compiler.y
index 46cc545358dbad238b6a9b3fabf7374afbcf9b76..e5a379b790cb31d03e38b61ec7a29512fed50ee8 100644
--- a/compiler2/ttcn3/compiler.y
+++ b/compiler2/ttcn3/compiler.y
@@ -215,6 +215,7 @@ static const string anyname("anytype");
   template_restriction_t template_restriction;
   ValueRedirect* value_redirect;
   SingleValueRedirect* single_value_redirect;
+  param_eval_t eval;
 
   struct {
     bool is_raw;
@@ -897,7 +898,7 @@ static const string anyname("anytype");
  *********************************************************************/
 
 %type <bool_val> optAliveKeyword optOptionalKeyword optOverrideKeyword
-  optErrValueRaw optAllKeyword optLazyOrFuzzyModifier
+  optErrValueRaw optAllKeyword
 %type <str> FreeText optLanguageSpec PatternChunk PatternChunkList
 %type <uchar_val> Group Plane Row Cell
 %type <id> FieldIdentifier FieldReference GlobalModuleId
@@ -1027,6 +1028,7 @@ static const string anyname("anytype");
 %type <variableentries> VariableList
 %type <variableentry> VariableEntry
 %type <subtypeparses> seqValueOrRange AllowedValues optSubTypeSpec
+%type <eval> optLazyOrFuzzyModifier
 
 %type <arraydimension_list> optArrayDef
 %type <fieldorarrayref_list> optExtendedFieldReference
@@ -7690,14 +7692,9 @@ Reference: // 490 ValueReference
 /* A.1.6.5 Parameterization */
 
 optLazyOrFuzzyModifier:
-  /* empty */ { $$ = false; }
-| LazyKeyword { $$ = true; }
-| FuzzyKeyword
-  {
-    $$ = false;
-    Location loc(infile, @1);
-    loc.error("Modifier '@fuzzy' is not currently supported.");
-  }
+  /* empty */ { $$ = NORMAL_EVAL; }
+| LazyKeyword { $$ = LAZY_EVAL; }
+| FuzzyKeyword { $$ = FUZZY_EVAL; }
 ;
 
 FormalValuePar: // 516
diff --git a/core/Basetype.hh b/core/Basetype.hh
index 71d2d8213421e66fe86cf50059f04971309e77b3..7b86f6dbf0962f12c241c386142f651aa781ffa1 100644
--- a/core/Basetype.hh
+++ b/core/Basetype.hh
@@ -29,6 +29,7 @@
 #include "RInt.hh"
 #include "JSON_Tokenizer.hh"
 #include "Logger.hh"
+#include "Error.hh"
 #ifdef TITAN_RUNTIME_2
 #include "Struct_of.hh"
 #include "XER.hh"
@@ -1062,21 +1063,64 @@ extern boolean operator!=(null_type null_value, const Empty_Record_Type& other_v
 #undef VIRTUAL_IF_RUNTIME_2
 #endif
 
+/** Base class for values and templates with fuzzy or lazy evaluation
+  *
+  * When inheriting, override the virtual function eval_expr() to evaluate
+  * the desired expression. Add new members and a new constructor if the
+  * expression contains references to variables.
+  * The class is also used by itself (without inheriting) to store the static
+  * values/templates of fuzzy or lazy parameters (the ones that are known at
+  * compile-time). */
 template <class EXPR_TYPE>
-class Lazy_Param {
+class Lazy_Fuzzy_Expr {
 protected:
+  /** Evaluation type. True for fuzzy evaluation, false for lazy evaluation. */
+  boolean fuzzy;
+  /** Indicates whether a lazy expression has been evaluated. This flag is
+    * updated in case of fuzzy evaluation, too, in case the evaluation type is
+    * later changed to lazy. */
   boolean expr_evaluated;
-  EXPR_TYPE expr_cache;  
+  /** The previous value of expr_evaluated is stored here when it is reset.
+    * (This is only needed if an evaluated lazy expression is changed to fuzzy,
+    * then to lazy, and isn't evaluated until it is reverted back to the initial
+    * lazy evaluation. Changing from fuzzy to lazy resets the evaluation flag,
+    * and the information, that the initial lazy expression was evaluated, would
+    * otherwise be lost.) */
+  boolean old_expr_evaluated;
+  /** Stores the value of the evaluated expression (in which case it is unbound
+    * until the first evaluation) or a static value/template, if it is known at
+    * compile-time. */
+  EXPR_TYPE expr_cache;
+  /** Evaluates the expression. Empty by default. Should be overridden by the
+    * inheriting class. */
   virtual void eval_expr() {}
 public:
-  Lazy_Param(): expr_evaluated(FALSE) {}
+  /** Constructor called by the inheriting class. */
+  Lazy_Fuzzy_Expr(boolean p_fuzzy): fuzzy(p_fuzzy), expr_evaluated(FALSE), old_expr_evaluated(FALSE) {}
+  /** Dummy type used by the static value/template constructor, since the
+    * inheriting class' constructor may have parameters of any type. */
   enum evaluated_state_t { EXPR_EVALED };
-  Lazy_Param(evaluated_state_t /*p_es*/, EXPR_TYPE p_cache): expr_evaluated(TRUE), expr_cache(p_cache) {}
+  /** Constructor for static values and templates. */
+  Lazy_Fuzzy_Expr(boolean p_fuzzy, evaluated_state_t /*p_es*/, EXPR_TYPE p_cache)
+  : fuzzy(p_fuzzy), expr_evaluated(TRUE), old_expr_evaluated(TRUE), expr_cache(p_cache) {}
+  /** Copy constructor (can't set it to private, since it is currently used by
+    * the generated default altstep classes). */
+  Lazy_Fuzzy_Expr(const Lazy_Fuzzy_Expr&) {
+    TTCN_error("Internal error: Copying a fuzzy or lazy parameter.");
+  }
+  /** Casting operator. This function is called whenever the fuzzy or lazy
+    * expression is referenced. */
   operator EXPR_TYPE&() {
-    if (!expr_evaluated) { eval_expr(); expr_evaluated=TRUE; }
+    if (fuzzy || !expr_evaluated) {
+      eval_expr();
+      expr_evaluated = TRUE;
+    }
     return expr_cache;
   }
-  virtual ~Lazy_Param() {}
+  /** Virtual destructor. */
+  virtual ~Lazy_Fuzzy_Expr() {}
+  /** Logging function. Used by the TTCN-3 Debugger for printing the values of
+    * lazy parameters. */
   void log() const {
     if (!expr_evaluated) {
       TTCN_Logger::log_event_str("<not evaluated>");
@@ -1085,6 +1129,21 @@ public:
       expr_cache.log();
     }
   }
+  /** Changes the evaluation type (from lazy to fuzzy or from fuzzy to lazy). */
+  void change() {
+    fuzzy = !fuzzy;
+    if (!fuzzy) {
+      old_expr_evaluated = expr_evaluated;
+      expr_evaluated = FALSE;
+    }
+  }
+  /** Reverts the evaluation type back to its previous state. */
+  void revert() {
+    fuzzy = !fuzzy;
+    if (fuzzy) {
+      expr_evaluated = expr_evaluated || old_expr_evaluated;
+    }
+  }
 };
 
 /** Interface/base class for decoded content matching 
diff --git a/core/Debugger.hh b/core/Debugger.hh
index 23f90ca8cbc782ae35ffec329808bd783015f6a2..387f9c72d7bb1d6630ad353fa6abf451ff3dcd51 100644
--- a/core/Debugger.hh
+++ b/core/Debugger.hh
@@ -510,10 +510,15 @@ public:
   {
     const void* ptr = p_var.set_function != NULL ? p_var.value : p_var.cvalue;
     TTCN_Logger::begin_event_log2str();
-    ((Lazy_Param<EXPR_TYPE>*)ptr)->log();
+    ((Lazy_Fuzzy_Expr<EXPR_TYPE>*)ptr)->log();
     return TTCN_Logger::end_event_log2str();
   }
   
+  static CHARSTRING print_fuzzy_param(const variable_t&)
+  {
+    return CHARSTRING("<fuzzy value>");
+  }
+  
   //////////////////////////////////////////////////////
   ////// methods called by other debugger classes //////
   //////////////////////////////////////////////////////
diff --git a/regression_test/Makefile b/regression_test/Makefile
index d3eb4c2432ed2b0c24fe12add1f0d14e127927bd..9c60c32c6fb888f901d515521856b547f08e71fe 100644
--- a/regression_test/Makefile
+++ b/regression_test/Makefile
@@ -48,7 +48,7 @@ XML ipv6 implicitOmit testcase_defparam transparent HQ16404 cfgFile \
 all_from lazyEval tryCatch text2ttcn json junitlogger ttcn2json profiler templateOmit \
 customEncoding makefilegen uidChars checkstate hostid templateIstemplatekind \
 selectUnion templateExclusiveRange any_from templatePatternRef indexWithRecofArray \
-connectMapOperTest
+connectMapOperTest fuzzy
 
 ifdef DYN
 DIRS += loggerplugin
diff --git a/regression_test/fuzzy/FuzzyFunctions.ttcn b/regression_test/fuzzy/FuzzyFunctions.ttcn
new file mode 100644
index 0000000000000000000000000000000000000000..f08ab24bd3b9e241503467d9fe7006cf3a94df62
--- /dev/null
+++ b/regression_test/fuzzy/FuzzyFunctions.ttcn
@@ -0,0 +1,261 @@
+/******************************************************************************
+ * 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:
+ *   Baranyi, Botond
+ *
+ ******************************************************************************/
+
+// This module contains functions and altsteps for testing fuzzy parameters
+module FuzzyFunctions {
+
+import from FuzzyTypes all;
+
+// Functions with fuzzy parameters
+// -------------------------------
+//
+// These functions add, multiply or concatenate their fuzzy parameter
+// with itself a specified amount of times, and return the result.
+// Functions with fuzzy parameters of structured types perform these
+// operations on their elements or fields.
+// Functions with fuzzy template parameters perform matching on a
+// list of values.
+//
+// Some of the functions are multi-leveled, testing the use of fuzzy
+// parameters passed as another function's fuzzy parameter.
+// Some of the multi-leveled functions have a lazy parameter instead of
+// a fuzzy one, to test the conversions between fuzzy and lazy parameters.
+
+function f_fuzzy_usage_int(in @fuzzy integer p_fuzzy, in integer p_usages) return integer {
+  var integer v_sum := 0;
+  for (var integer i := 0; i < p_usages; i := i + 1) {
+    v_sum := v_sum + p_fuzzy;
+  }
+  return v_sum;
+}
+
+function f_fuzzy_usage_float(in @fuzzy float p_fuzzy, in integer p_usages) return float {
+  var float v_sum := 0.0;
+  for (var integer i := 0; i < p_usages; i := i + 1) {
+    v_sum := v_sum + p_fuzzy;
+  }
+  return v_sum;
+}
+
+function f_wrapped_fuzzy_usage_float(in @fuzzy float p_fuzzy, in integer p_outer_usages, in integer p_inner_usages) return float {
+  var float v_prod := 1.0;
+  for (var integer i := 0; i < p_outer_usages; i := i + 1) {
+    v_prod := v_prod * f_fuzzy_usage_float(p_fuzzy, p_inner_usages);
+  }
+  return v_prod;
+}
+
+function f_fuzzy_usage_cstr(in @fuzzy charstring p_fuzzy, in integer p_usages) return charstring {
+  var charstring v_res := "";
+  for (var integer i := 0; i < p_usages; i := i + 1) {
+    v_res := v_res & p_fuzzy;
+  }
+  return v_res;
+}
+
+function f_lazy_usage_bstr(in @lazy bitstring p_lazy, in integer p_usages) return bitstring {
+  var bitstring v_res := ''B;
+  for (var integer i := 0; i < p_usages; i := i + 1) {
+    v_res := v_res & p_lazy;
+  }
+  return v_res;
+}
+
+function f_wrapped_fuzzy_usage_bstr(in @fuzzy bitstring p_fuzzy, in integer p_outer_usages, in integer p_inner_usages) return bitstring {
+  var bitstring v_res := ''B;
+  for (var integer i := 0; i < p_outer_usages; i := i + 1) {
+    // chaining these concatenations does not currently work (p_fuzzy would be treated as lazy)
+    v_res := v_res & p_fuzzy;
+    v_res := v_res & f_lazy_usage_bstr(p_fuzzy, p_inner_usages);
+  }
+  return v_res;
+}
+
+function f_fuzzy_usage_hstr(in @fuzzy hexstring p_fuzzy, in integer p_usages) return hexstring {
+  var hexstring v_res := ''H;
+  for (var integer i := 0; i < p_usages; i := i + 1) {
+    v_res := v_res & p_fuzzy;
+  }
+  return v_res;
+}
+
+function f_wrapped_lazy_usage_hstr(in @lazy hexstring p_lazy, in integer p_outer_usages, in integer p_inner_usages) return hexstring {
+  var hexstring v_res := ''H;
+  for (var integer i := 0; i < p_outer_usages; i := i + 1) {
+    // chaining these concatenations does not currently work (p_lazy would be treated as fuzzy)
+    v_res := v_res & p_lazy;
+    v_res := v_res & f_fuzzy_usage_hstr(p_lazy, p_inner_usages);
+  }
+  return v_res;
+}
+
+function f_fuzzy_usage_ostr(in @fuzzy octetstring p_fuzzy, in integer p_usages) return octetstring {
+  var octetstring v_res := ''O;
+  for (var integer i := 0; i < p_usages; i := i + 1) {
+    v_res := v_res & p_fuzzy;
+  }
+  return v_res;
+}
+
+function f_wrapped_lazy_usage_ostr(in @lazy octetstring p_lazy, in integer p_outer_usages, in integer p_inner_usages) return octetstring {
+  var octetstring v_res := ''O;
+  for (var integer i := 0; i < p_outer_usages; i := i + 1) {
+    // chaining these concatenations does not currently work (p_lazy would be treated as fuzzy)
+    v_res := v_res & p_lazy;
+    v_res := v_res & f_fuzzy_usage_ostr(p_lazy, p_inner_usages);
+  }
+  return v_res;
+}
+
+function f_double_wrapped_fuzzy_usage_ostr(in @fuzzy octetstring p_fuzzy, in integer p_outer_usages, in integer p_middle_usages, in integer p_inner_usages) return octetstring {
+  var octetstring v_res := ''O;
+  for (var integer i := 0; i < p_outer_usages; i := i + 1) {
+    // chaining these concatenations does not currently work (p_fuzzy would be treated as lazy)
+    v_res := v_res & p_fuzzy;
+    v_res := v_res & f_wrapped_lazy_usage_ostr(p_fuzzy, p_middle_usages, p_inner_usages);
+  }
+  return v_res;
+}
+
+function f_lazy_usage_ustr(in @lazy universal charstring p_lazy, in integer p_usages) return universal charstring {
+  var universal charstring v_res := "";
+  for (var integer i := 0; i < p_usages; i := i + 1) {
+    v_res := v_res & p_lazy;
+  }
+  return v_res;
+}
+
+function f_wrapped_fuzzy_usage_ustr(in @fuzzy universal charstring p_fuzzy, in integer p_outer_usages, in integer p_inner_usages) return universal charstring {
+  var universal charstring v_res := "";
+  for (var integer i := 0; i < p_outer_usages; i := i + 1) {
+    // chaining these concatenations does not currently work (p_fuzzy would be treated as lazy)
+    v_res := v_res & p_fuzzy;
+    v_res := v_res & f_lazy_usage_ustr(p_fuzzy, p_inner_usages);
+  }
+  return v_res;
+}
+
+function f_double_wrapped_lazy_usage_ustr(in @lazy universal charstring p_lazy, in integer p_outer_usages, in integer p_middle_usages, in integer p_inner_usages) return universal charstring {
+  var universal charstring v_res := "";
+  for (var integer i := 0; i < p_outer_usages; i := i + 1) {
+    // chaining these concatenations does not currently work (p_lazy would be treated as fuzzy)
+    v_res := v_res & p_lazy;
+    v_res := v_res & f_wrapped_fuzzy_usage_ustr(p_lazy, p_middle_usages, p_inner_usages);
+  }
+  return v_res;
+}
+
+function f_wrapped_fuzzy_usage_rec(in @fuzzy Rec p_fuzzy, in integer p_rec_usages, in integer p_int_usages, in integer p_str_usages) return Rec {
+  var Rec v_res := { num := 0, str := "" };
+  for (var integer i := 0; i < p_rec_usages; i := i + 1) {
+    v_res.num := v_res.num + f_fuzzy_usage_int(p_fuzzy.num, p_int_usages);
+    v_res.str := v_res.str & f_fuzzy_usage_cstr(p_fuzzy.str, p_str_usages);
+  }
+  return v_res;
+}
+
+function f_fuzzy_usage_int_temp(in template @fuzzy integer pt_fuzzy, in IntList p_values) return integer {
+  var integer v_nof_matches := 0;
+  for (var integer i := 0; i < lengthof(p_values); i := i + 1) {
+    if (match(p_values[i], pt_fuzzy)) {
+      v_nof_matches := v_nof_matches + 1;
+    }
+  }
+  return v_nof_matches;
+}
+
+function f_wrapped_fuzzy_usage_list_temp(in template @fuzzy IntList pt_fuzzy, in IntList p_values) return integer {
+  var integer v_nof_matches := 0;
+  for (var integer i := 0; i < lengthof(pt_fuzzy); i := i + 1) {
+    v_nof_matches := v_nof_matches + f_fuzzy_usage_int_temp(pt_fuzzy[i], p_values);
+  }
+  return v_nof_matches;
+}
+
+// Altstep with fuzzy parameters
+altstep as_fuzzy_bool(in @fuzzy boolean p_fuzzy) runs on CT {
+  var template integer vt_msg := (1..10);
+  [p_fuzzy] pt.receive(vt_msg) { }
+  [not p_fuzzy] pt.receive(vt_msg) { }
+  [p_fuzzy] pt.receive { }
+  [not p_fuzzy] pt.receive { }
+}
+
+// Functions used as fuzzy parameters
+// ----------------------------------
+//
+// These functions are used as the expressions of fuzzy parameters.
+// Each function returns its value or template parameter, and
+// increases a counter, to help test how many times a fuzzy
+// parameter's expression was evaluated.
+
+function f_fuzzy_return_int(in integer p_ret) runs on CT return integer {
+  ct_calls := ct_calls + 1;
+  return p_ret;
+}
+
+function f_fuzzy_return_float(in float p_ret) runs on CT return float {
+  ct_calls := ct_calls + 1;
+  return p_ret;
+}
+
+function f_fuzzy_return_cstr(in charstring p_ret) runs on CT return charstring {
+  ct_calls := ct_calls + 1;
+  return p_ret;
+}
+
+function f_fuzzy_return_bstr(in bitstring p_ret) runs on CT return bitstring {
+  ct_calls := ct_calls + 1;
+  return p_ret;
+}
+
+function f_fuzzy_return_hstr(in hexstring p_ret) runs on CT return hexstring {
+  ct_calls := ct_calls + 1;
+  return p_ret;
+}
+
+function f_fuzzy_return_ostr(in octetstring p_ret) runs on CT return octetstring {
+  ct_calls := ct_calls + 1;
+  return p_ret;
+}
+
+function f_fuzzy_return_ustr(in universal charstring p_ret) runs on CT return universal charstring {
+  ct_calls := ct_calls + 1;
+  return p_ret;
+}
+
+function f_fuzzy_return_bool(in boolean p_ret) runs on CT return boolean {
+  ct_calls := ct_calls + 1;
+  return p_ret;
+}
+
+function f_fuzzy_return_rec(in Rec p_ret) runs on CT return Rec {
+  ct_calls := ct_calls + 1;
+  return p_ret;
+}
+
+function f_fuzzy_return_int_temp(in template integer pt_ret) runs on CT return template integer {
+  ct_calls := ct_calls + 1;
+  return pt_ret;
+}
+
+function f_fuzzy_return_list_temp(in template IntList pt_ret) runs on CT return template IntList {
+  ct_calls := ct_calls + 1;
+  return pt_ret;
+}
+
+function f_fuzzy_return_uni_temp(in template Uni pt_ret) runs on CT return template Uni {
+  ct_calls := ct_calls + 1;
+  return pt_ret;
+}
+
+} // end of module
diff --git a/regression_test/fuzzy/FuzzyTestcases.ttcn b/regression_test/fuzzy/FuzzyTestcases.ttcn
new file mode 100644
index 0000000000000000000000000000000000000000..944a829aca3531f2bd48e9ad7f52a394e87f4f8e
--- /dev/null
+++ b/regression_test/fuzzy/FuzzyTestcases.ttcn
@@ -0,0 +1,347 @@
+/******************************************************************************
+ * 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:
+ *   Baranyi, Botond
+ *
+ ******************************************************************************/
+
+// This module contains test cases for fuzzy parameters
+module FuzzyTestcases {
+
+import from FuzzyTypes all;
+import from FuzzyFunctions all;
+
+testcase tc_fuzzy_int() runs on CT {
+  var integer v_usages := 0;
+  var integer v_exp_res := 0;
+  var integer v_res := f_fuzzy_usage_int(f_fuzzy_return_int(1), v_usages);
+  if (ct_calls != v_usages) {
+    setverdict(fail, "Expected ", v_usages, " calls, got ", ct_calls);
+  }
+  if (v_res != v_exp_res) {
+    setverdict(fail, "Expected result: ", v_exp_res, ", got: ", v_res);
+  }
+  
+  v_usages := 3;
+  v_exp_res := 6;
+  v_res := f_fuzzy_usage_int(f_fuzzy_return_int(2), v_usages);
+  if (ct_calls != v_usages) {
+    setverdict(fail, "Expected ", v_usages, " calls, got ", ct_calls);
+  }
+  if (v_res != v_exp_res) {
+    setverdict(fail, "Expected result: ", v_exp_res, ", got: ", v_res);
+  }
+  
+  setverdict(pass);
+}
+
+testcase tc_fuzzy_wrapped_float() runs on CT {
+  var integer v_outer_usages := 0;
+  var integer v_inner_usages := 0;
+  var float v_exp_res := 1.0;
+  var float v_res := f_wrapped_fuzzy_usage_float(f_fuzzy_return_float(0.6), v_outer_usages, v_inner_usages);
+  if (ct_calls != v_outer_usages * v_inner_usages) {
+    setverdict(fail, "Expected ", v_outer_usages * v_inner_usages, " calls, got ", ct_calls);
+  }
+  if (v_res != v_exp_res) {
+    setverdict(fail, "Expected result: ", v_exp_res, ", got: ", v_res);
+  }
+  
+  v_outer_usages := 3;
+  v_inner_usages := 4;
+  v_exp_res := 1000.0;
+  v_res := f_wrapped_fuzzy_usage_float(f_fuzzy_return_float(2.5), v_outer_usages, v_inner_usages);
+  if (ct_calls != v_outer_usages * v_inner_usages) {
+    setverdict(fail, "Expected ", v_outer_usages * v_inner_usages, " calls, got ", ct_calls);
+  }
+  if (v_res != v_exp_res) {
+    setverdict(fail, "Expected result: ", v_exp_res, ", got: ", v_res);
+  }
+  setverdict(pass);
+}
+
+// non-standard
+testcase tc_fuzzy_in_fuzzy_cstr() runs on CT {
+  var integer v_outer_usages := 0;
+  var integer v_inner_usages := 0;
+  var charstring v_exp_res := "";
+  var charstring v_res := f_fuzzy_usage_cstr(f_fuzzy_usage_cstr(f_fuzzy_return_cstr("ab"), v_inner_usages), v_outer_usages);
+  if (ct_calls != v_outer_usages) {
+    setverdict(fail, "Expected ", v_outer_usages, " calls, got ", ct_calls);
+  }
+  if (v_res != v_exp_res) {
+    setverdict(fail, "Expected result: ", v_exp_res, ", got: ", v_res);
+  }
+  
+  v_outer_usages := 2;
+  v_inner_usages := 3;
+  v_exp_res := "abababababab"; // "ab" x 6
+  v_res := f_fuzzy_usage_cstr(f_fuzzy_usage_cstr(f_fuzzy_return_cstr("ab"), v_inner_usages), v_outer_usages);
+  if (ct_calls != v_outer_usages) {
+    setverdict(fail, "Expected ", v_outer_usages, " calls, got ", ct_calls);
+  }
+  if (v_res != v_exp_res) {
+    setverdict(fail, "Expected result: ", v_exp_res, ", got: ", v_res);
+  }
+  setverdict(pass);
+}
+
+testcase tc_lazy_wrapped_in_fuzzy_bstr() runs on CT {
+  var integer v_outer_usages := 0;
+  var integer v_inner_usages := 0;
+  var bitstring v_exp_res := ''B;
+  var bitstring v_res := f_wrapped_fuzzy_usage_bstr(f_fuzzy_return_bstr('10'B), v_outer_usages, v_inner_usages);
+  if (ct_calls != v_outer_usages * 2) {
+    setverdict(fail, "Expected ", v_outer_usages * 2, " calls, got ", ct_calls);
+  }
+  if (v_res != v_exp_res) {
+    setverdict(fail, "Expected result: ", v_exp_res, ", got: ", v_res);
+  }
+  
+  v_outer_usages := 3;
+  v_inner_usages := 4;
+  v_exp_res := '101010101010101010101010101010'B; // '10'B x 15
+  v_res := f_wrapped_fuzzy_usage_bstr(f_fuzzy_return_bstr('10'B), v_outer_usages, v_inner_usages);
+  if (ct_calls != v_outer_usages * 2) {
+    setverdict(fail, "Expected ", v_outer_usages * 2, " calls, got ", ct_calls);
+  }
+  if (v_res != v_exp_res) {
+    setverdict(fail, "Expected result: ", v_exp_res, ", got: ", v_res);
+  }
+  setverdict(pass);
+}
+
+testcase tc_fuzzy_wrapped_in_lazy_hstr() runs on CT {
+  var integer v_outer_usages := 0;
+  var integer v_inner_usages := 0;
+  var hexstring v_exp_res := ''H;
+  var hexstring v_res := f_wrapped_lazy_usage_hstr(f_fuzzy_return_hstr('12EF'H), v_outer_usages, v_inner_usages);
+  if (ct_calls != v_outer_usages * v_inner_usages) {
+    setverdict(fail, "Expected ", v_outer_usages * v_inner_usages, " calls, got ", ct_calls);
+  }
+  if (v_res != v_exp_res) {
+    setverdict(fail, "Expected result: ", v_exp_res, ", got: ", v_res);
+  }
+  
+  v_outer_usages := 3;
+  v_inner_usages := 2;
+  v_exp_res := 'AC3AC3AC3AC3AC3AC3AC3AC3AC3'H; // 'AC3'H x 9
+  v_res := f_wrapped_lazy_usage_hstr(f_fuzzy_return_hstr('AC3'H), v_outer_usages, v_inner_usages);
+  if (ct_calls != v_outer_usages * v_inner_usages + 1) {
+    setverdict(fail, "Expected ", v_outer_usages * v_inner_usages + 1, " calls, got ", ct_calls);
+  }
+  if (v_res != v_exp_res) {
+    setverdict(fail, "Expected result: ", v_exp_res, ", got: ", v_res);
+  }
+  setverdict(pass);
+}
+
+testcase tc_fuzzy_wrapped_in_lazy_wrapped_in_fuzzy_ostr() runs on CT {
+  var integer v_outer_usages := 0;
+  var integer v_middle_usages := 0;
+  var integer v_inner_usages := 0;
+  var octetstring v_exp_res := ''O;
+  var octetstring v_res := f_double_wrapped_fuzzy_usage_ostr(f_fuzzy_return_ostr('12EF'O), v_outer_usages, v_middle_usages, v_inner_usages);
+  if (ct_calls != v_outer_usages * (v_middle_usages * v_inner_usages + 1)) {
+    setverdict(fail, "Expected ", v_outer_usages * (v_middle_usages * v_inner_usages + 1), " calls, got ", ct_calls);
+  }
+  if (v_res != v_exp_res) {
+    setverdict(fail, "Expected result: ", v_exp_res, ", got: ", v_res);
+  }
+  
+  v_outer_usages := 2;
+  v_middle_usages := 2;
+  v_inner_usages := 3;
+  v_exp_res := 'DADADADADADADADADADADADADADADADADADA'O; // 'DE'O x 18
+  v_res := f_double_wrapped_fuzzy_usage_ostr(f_fuzzy_return_ostr('DA'O), v_outer_usages, v_middle_usages, v_inner_usages);
+  if (ct_calls != v_outer_usages * (v_middle_usages * v_inner_usages + 2)) {
+    setverdict(fail, "Expected ", v_outer_usages * (v_middle_usages * v_inner_usages + 2), " calls, got ", ct_calls);
+  }
+  if (v_res != v_exp_res) {
+    setverdict(fail, "Expected result: ", v_exp_res, ", got: ", v_res);
+  }
+  setverdict(pass);
+}
+
+testcase tc_lazy_wrapped_in_fuzzy_wrapped_in_lazy_ustr() runs on CT {
+  var integer v_outer_usages := 0;
+  var integer v_middle_usages := 0;
+  var integer v_inner_usages := 0;
+  var universal charstring v_exp_res := "";
+  var universal charstring v_res := f_double_wrapped_lazy_usage_ustr(f_fuzzy_return_ustr(char(0, 1, 2, 3)), v_outer_usages, v_middle_usages, v_inner_usages);
+  if (ct_calls != v_outer_usages * v_middle_usages * 2) {
+    setverdict(fail, "Expected ", v_outer_usages * v_middle_usages * 2, " calls, got ", ct_calls);
+  }
+  if (v_res != v_exp_res) {
+    setverdict(fail, "Expected result: ", v_exp_res, ", got: ", v_res);
+  }
+  
+  v_outer_usages := 2;
+  v_middle_usages := 3;
+  v_inner_usages := 2;
+  v_exp_res := "áááááááááááááááááááá"; // "á" x 20
+  v_res := f_double_wrapped_lazy_usage_ustr(f_fuzzy_return_ustr("á"), v_outer_usages, v_middle_usages, v_inner_usages);
+  if (ct_calls != v_outer_usages * v_middle_usages * 2 + 1) {
+    setverdict(fail, "Expected ", v_outer_usages * v_middle_usages * 2 + 1, " calls, got ", ct_calls);
+  }
+  if (v_res != v_exp_res) {
+    setverdict(fail, "Expected result: ", v_exp_res, ", got: ", v_res);
+  }
+  setverdict(pass);
+}
+
+testcase tc_fuzzy_wrapped_rec() runs on CT {
+  var integer v_rec_usages := 0;
+  var integer v_int_usages := 0;
+  var integer v_str_usages := 0;
+  var Rec v_rec := { num := 5, str := "xy" };
+  var Rec v_exp_res := { num := 0, str := "" };
+  var Rec v_res := f_wrapped_fuzzy_usage_rec(f_fuzzy_return_rec(v_rec), v_rec_usages, v_int_usages, v_str_usages);
+  if (ct_calls != v_rec_usages * (v_int_usages + v_str_usages)) {
+    setverdict(fail, "Expected ", v_rec_usages * (v_int_usages + v_str_usages), " calls, got ", ct_calls);
+  }
+  if (v_res != v_exp_res) {
+    setverdict(fail, "Expected result: ", v_exp_res, ", got: ", v_res);
+  }
+  
+  v_rec_usages := 2;
+  v_int_usages := 4;
+  v_str_usages := 3;
+  v_exp_res := { num := 40, str := "xyxyxyxyxyxy" };
+  v_res := f_wrapped_fuzzy_usage_rec(f_fuzzy_return_rec(v_rec), v_rec_usages, v_int_usages, v_str_usages);
+  if (ct_calls != v_rec_usages * (v_int_usages + v_str_usages)) {
+    setverdict(fail, "Expected ", v_rec_usages * (v_int_usages + v_str_usages), " calls, got ", ct_calls);
+  }
+  if (v_res != v_exp_res) {
+    setverdict(fail, "Expected result: ", v_exp_res, ", got: ", v_res);
+  }
+  setverdict(pass);
+}
+
+testcase tc_fuzzy_int_temp() runs on CT {
+  var template integer vt_int := (0..infinity);
+  var IntList v_values := { };
+  var integer v_exp_res := 0;
+  var integer v_res := f_fuzzy_usage_int_temp(f_fuzzy_return_int_temp(vt_int), v_values);
+  if (ct_calls != lengthof(v_values)) {
+    setverdict(fail, "Expected ", lengthof(v_values), " calls, got ", ct_calls);
+  }
+  if (v_res != v_exp_res) {
+    setverdict(fail, "Expected result: ", v_exp_res, ", got: ", v_res);
+  }
+  
+  v_values := { 1, -6, 199, 0, -3000 };
+  v_exp_res := 3;
+  v_res := f_fuzzy_usage_int_temp(f_fuzzy_return_int_temp(vt_int), v_values);
+  if (ct_calls != lengthof(v_values)) {
+    setverdict(fail, "Expected ", lengthof(v_values), " calls, got ", ct_calls);
+  }
+  if (v_res != v_exp_res) {
+    setverdict(fail, "Expected result: ", v_exp_res, ", got: ", v_res);
+  }
+  setverdict(pass);
+}
+
+testcase tc_fuzzy_wrapped_list_temp() runs on CT {
+  var template IntList vt_list := { };
+  var IntList v_values := { };
+  var integer v_exp_res := 0;
+  var integer v_res := f_wrapped_fuzzy_usage_list_temp(f_fuzzy_return_list_temp(vt_list), v_values);
+  if (ct_calls != (lengthof(v_values) + 1) * lengthof(vt_list) + 1) {
+    setverdict(fail, "Expected ", (lengthof(v_values) + 1) * lengthof(vt_list) + 1, " calls, got ", ct_calls);
+  }
+  if (v_res != v_exp_res) {
+    setverdict(fail, "Expected result: ", v_exp_res, ", got: ", v_res);
+  }
+  
+  ct_calls := 0;
+  vt_list := { ?, (1, (100..200)), (-infinity..0), -2 };
+  v_values := { 1, -6, 199, 0, -3000 };
+  v_exp_res := 10;
+  v_res := f_wrapped_fuzzy_usage_list_temp(f_fuzzy_return_list_temp(vt_list), v_values);
+  if (ct_calls != (lengthof(v_values) + 1) * lengthof(vt_list) + 1) {
+    setverdict(fail, "Expected ", (lengthof(v_values) + 1) * lengthof(vt_list) + 1, " calls, got ", ct_calls);
+  }
+  if (v_res != v_exp_res) {
+    setverdict(fail, "Expected result: ", v_exp_res, ", got: ", v_res);
+  }
+  setverdict(pass);
+}
+
+testcase tc_fuzzy_altstep_bool() runs on CT {
+  connect(self:pt, self:pt);
+  pt.send(3);
+  timer tmr;
+  tmr.start(0.5);
+  alt {
+    [] tmr.timeout {
+      setverdict(fail, "First test timed out.");
+    }
+    [] as_fuzzy_bool(f_fuzzy_return_bool(false));
+  }
+  if (ct_calls != 2) {
+    setverdict(fail, "Expected 2 calls, got ", ct_calls);
+  }
+  
+  ct_calls := 0;
+  pt.send(-6);
+  tmr.stop;
+  tmr.start(0.5);
+  alt {
+    [] tmr.timeout {
+      setverdict(fail, "Second test timed out.");
+    }
+    [] as_fuzzy_bool(f_fuzzy_return_bool(true));
+  }
+  if (ct_calls != 3) {
+    setverdict(fail, "Expected 3 calls, got ", ct_calls);
+  }
+  setverdict(pass);
+}
+
+// Testcase with fuzzy parameters
+testcase tc_fuzzy_testcase_uni(in template @fuzzy Uni pt_fuzzy) runs on CT {
+  var Uni v_values[4] := {
+    { i := 10 },
+    { os := 'AB12F9'O },
+    { i := -991 },
+    { ucs := "eeeeee" }
+  };
+  var integer v_nof_matches := 0;
+  for (var integer i := 0; i < lengthof(v_values); i := i + 1) {
+    if (match(v_values[i], pt_fuzzy)) {
+      v_nof_matches := v_nof_matches + 1;
+    }
+  }
+  if (ct_calls != lengthof(v_values)) {
+    setverdict(fail, "Expected ", lengthof(v_values), " calls, got ", ct_calls);
+  }
+  if (v_nof_matches != 2) {
+    setverdict(fail, "Expected 2 matches, got ", v_nof_matches);
+  }
+  setverdict(pass);
+}
+
+control {
+  execute(tc_fuzzy_int());
+  execute(tc_fuzzy_wrapped_float());
+  execute(tc_fuzzy_in_fuzzy_cstr());
+  execute(tc_lazy_wrapped_in_fuzzy_bstr());
+  execute(tc_fuzzy_wrapped_in_lazy_hstr());
+  execute(tc_fuzzy_wrapped_in_lazy_wrapped_in_fuzzy_ostr());
+  execute(tc_lazy_wrapped_in_fuzzy_wrapped_in_lazy_ustr());
+  execute(tc_fuzzy_wrapped_rec());
+  execute(tc_fuzzy_int_temp());
+  execute(tc_fuzzy_wrapped_list_temp());
+  execute(tc_fuzzy_altstep_bool());
+  
+  var template Uni vt_uni := { i := ? };
+  execute(tc_fuzzy_testcase_uni(f_fuzzy_return_uni_temp(vt_uni)));
+}
+
+} // end of module
diff --git a/regression_test/fuzzy/FuzzyTypes.ttcn b/regression_test/fuzzy/FuzzyTypes.ttcn
new file mode 100644
index 0000000000000000000000000000000000000000..7e321e9d36086499a3156bd894f09cfa8b56e189
--- /dev/null
+++ b/regression_test/fuzzy/FuzzyTypes.ttcn
@@ -0,0 +1,41 @@
+/******************************************************************************
+ * 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:
+ *   Baranyi, Botond
+ *
+ ******************************************************************************/
+
+// This module contains types for testing fuzzy parameters
+module FuzzyTypes {
+
+type port PT message {
+  inout integer
+}
+with {
+  extension "internal";
+}
+
+type component CT {
+  var integer ct_calls := 0;
+  port PT pt;
+}
+
+type record Rec {
+  integer num,
+  charstring str
+}
+
+type record of integer IntList;
+
+type union Uni {
+  integer i,
+  octetstring os,
+  universal charstring ucs
+}
+
+} // end of module
diff --git a/regression_test/fuzzy/Makefile b/regression_test/fuzzy/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..b012c91086200ab11c42372a4e56553cab10ba1d
--- /dev/null
+++ b/regression_test/fuzzy/Makefile
@@ -0,0 +1,63 @@
+##############################################################################
+# 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:
+#   Baranyi, Botond
+#
+##############################################################################
+TOPDIR := ../
+include $(TOPDIR)/Makefile.regression
+
+MAKE_PROG := $(MAKE)
+
+TTCN_FILES := FuzzyTypes.ttcn FuzzyFunctions.ttcn FuzzyTestcases.ttcn
+CFG := fuzzy.cfg
+
+FILES := $(TTCN_FILES) $(CFG) 
+
+RUNNABLE := fuzzy$(EXE_SUFFIX)
+
+COVERAGE_FLAG := 
+ifeq ($(COVERAGE), yes)
+  COVERAGE_FLAG += -C
+endif
+
+DIR_SINGLE := dir_single_mode
+DIR_PARALLEL := dir_parallel_mode
+GENERATED_DIRS := $(DIR_SINGLE) $(DIR_PARALLEL)
+
+# List of fake targets:
+.PHONY: all clean run run_single run_parallel runall
+
+all: $(GENERATED_DIRS)
+
+$(DIR_SINGLE):
+	mkdir $@
+	cd $@ && for file in $(FILES); do ln -s ../$$file || exit; done
+	cd $@ && $(TTCN3_DIR)/bin/ttcn3_makefilegen $(COVERAGE_FLAG) $(SPLIT_FLAG) -s -e $(RUNNABLE) ./*  && $(MAKE_PROG)
+
+$(DIR_PARALLEL):
+	mkdir $@
+	cd $@ && for file in $(FILES); do ln -s ../$$file || exit; done
+	cd $@ && $(TTCN3_DIR)/bin/ttcn3_makefilegen $(COVERAGE_FLAG) $(SPLIT_FLAG) -e $(RUNNABLE) ./*  && $(MAKE_PROG)
+
+run: $(GENERATED_DIRS)
+	cd $(DIR_SINGLE) && ./$(RUNNABLE) $(CFG) && grep "Overall verdict: pass" *.log
+	cd $(DIR_PARALLEL) && $(TTCN3_DIR)/bin/ttcn3_start $(RUNNABLE) $(CFG) && grep "Overall verdict: pass" *.log
+
+# To run all tests, possibly in parallel
+run_single: $(DIR_SINGLE)
+	cd $(DIR_SINGLE) && ./$(RUNNABLE) $(CFG) && grep "Overall verdict: pass" *.log
+
+run_parallel: $(DIR_PARALLEL) 
+	cd $(DIR_PARALLEL) && $(TTCN3_DIR)/bin/ttcn3_start $(RUNNABLE) $(CFG) && grep "Overall verdict: pass" *.log
+
+runall: run_single run_parallel
+
+clean distclean:
+	rm -rf $(GENERATED_DIRS)
+
diff --git a/regression_test/fuzzy/fuzzy.cfg b/regression_test/fuzzy/fuzzy.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..9a0f3a9e1d1a86451bdfe5597a6782a9ea0e91e5
--- /dev/null
+++ b/regression_test/fuzzy/fuzzy.cfg
@@ -0,0 +1,21 @@
+###############################################################################
+# 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:
+#   Baranyi, Botond
+#
+###############################################################################
+[MODULE_PARAMETERS]
+[LOGGING]
+Logfile := "fuzzy_%r.log"
+FileMask := LOG_ALL
+ConsoleMask := TTCN_WARNING | TTCN_ERROR | TTCN_TESTCASE | TTCN_STATISTICS
+
+[EXECUTE]
+FuzzyTestcases
+
+