diff --git a/compiler2/Type.hh b/compiler2/Type.hh
index 01106fdc90833a75739b66a155856de8fb9d759b..d3ebf42447db8540b004ef19bcf0c93ee67bc22c 100644
--- a/compiler2/Type.hh
+++ b/compiler2/Type.hh
@@ -702,6 +702,10 @@ namespace Common {
       * Only used with new codec handling. */
     bool can_have_coding(MessageEncodingType_t coding);
     
+    /** Checks whether the type itself or one of its fields/elements is a
+      * component or default type. Recursive. */
+    void chk_map_param(Location* usage);
+    
     /** Return whether the two typetypes are compatible.  Sometimes, this is
      *  just a question of \p p_tt1 == \p p_tt2.  When there are multiple
      *  typetypes for a type (e.g. T_ENUM_A and T_ENUM_T) then all
diff --git a/compiler2/Type_chk.cc b/compiler2/Type_chk.cc
index d680f9a5de76002d76d2b823542df21e054e8ec0..5ab6baaa7eadf7ed7e9eb2911eec81904bc6e0a3 100644
--- a/compiler2/Type_chk.cc
+++ b/compiler2/Type_chk.cc
@@ -163,10 +163,18 @@ void Type::chk()
   case T_ARRAY:
     chk_Array();
     break;
-  case T_PORT:
+  case T_PORT: {
     u.port->chk();
+    Ttcn::FormalParList* map_params = u.port->get_map_parameters(true);
+    if (map_params != NULL) {
+      map_params->set_genname(get_genname_own());
+    }
+    Ttcn::FormalParList* unmap_params = u.port->get_map_parameters(false);
+    if (unmap_params != NULL) {
+      unmap_params->set_genname(get_genname_own());
+    }
     if (w_attrib_path) u.port->chk_attributes(w_attrib_path);
-    break;
+    break; }
   case T_SIGNATURE:
     chk_Signature();
     break;
@@ -7730,4 +7738,43 @@ void Type::chk_this_template_Signature(Template *t, namedbool incomplete_allowed
       "signature `%s'", get_typename().c_str());
 }
 
+void Type::chk_map_param(Location* usage)
+{
+  Type* t = get_type_refd_last();
+  if (RecursionTracker::is_happening(t)) {
+    return;
+  }
+  RecursionTracker tracker(t);
+  
+  switch (t->typetype) {
+  case T_COMPONENT:
+  case T_DEFAULT:
+    usage->error("The `map'/`unmap' parameters of a port type cannot be or "
+      "contain a field/element of %s type",
+      t->typetype == T_COMPONENT ? "component" : "default");
+    note("Prohibited type is here");
+    break;
+  case T_SEQ_T:
+  case T_SET_T:
+  case T_CHOICE_T:
+  case T_CHOICE_A:
+  case T_SEQ_A:
+  case T_SET_A:
+  case T_OPENTYPE:
+  case T_ANYTYPE:
+    for (size_t i = 0; i < t->u.secho.cfm->get_nof_comps(); ++i) {
+      t->u.secho.cfm->get_comp_byIndex(i)->get_type()->chk_map_param(usage);
+    }
+    break;
+  case T_SEQOF:
+  case T_SETOF:
+  case T_ARRAY:
+    t->get_ofType()->chk_map_param(usage);
+    break;
+  default:
+    // everything else is allowed
+    break;
+  }
+}
+
 } // namespace Common
diff --git a/compiler2/ttcn3/AST_ttcn3.cc b/compiler2/ttcn3/AST_ttcn3.cc
index deb45168d7695b51ff0576d05622bb41def21e67..dac7ed53a792cfd309a9b6e1d88b5fb397bbe358 100644
--- a/compiler2/ttcn3/AST_ttcn3.cc
+++ b/compiler2/ttcn3/AST_ttcn3.cc
@@ -9583,6 +9583,22 @@ namespace Ttcn {
         default:
           break;
         }
+        break;
+      case Definition::A_PORT:
+        switch (par->get_asstype()) {
+        case Definition::A_PAR_VAL:
+        case Definition::A_PAR_VAL_IN:
+        case Definition::A_PAR_VAL_OUT:
+        case Definition::A_PAR_VAL_INOUT:
+          // these are allowed
+          par->get_Type()->chk_map_param(par);
+          break;
+        default:
+          par->error("The `map'/`unmap' parameters of a port type cannot have %s",
+            par->get_assname());
+          break;
+        }
+        break;
       default:
         // everything is allowed for functions and altsteps
         break;
diff --git a/compiler2/ttcn3/Statement.cc b/compiler2/ttcn3/Statement.cc
index a4469be42e6040216bf0228f2cbec843ffef9ab6..463ce4f5989bdf2215220a200d43204395666d5a 100644
--- a/compiler2/ttcn3/Statement.cc
+++ b/compiler2/ttcn3/Statement.cc
@@ -697,6 +697,7 @@ namespace Ttcn {
       delete config_op.portref1;
       delete config_op.compref2;
       delete config_op.portref2;
+      delete config_op.ap_list;
       break;
     case S_START_TIMER:
       delete timer_op.timerref;
@@ -1423,7 +1424,8 @@ namespace Ttcn {
 
   Statement::Statement(statementtype_t p_st,
                        Value *p_compref1, Reference *p_portref1,
-                       Value *p_compref2, Reference *p_portref2)
+                       Value *p_compref2, Reference *p_portref2,
+                       ParsedActualParameters* p_params)
     : statementtype(p_st), my_sb(0)
   {
     switch(statementtype) {
@@ -1438,6 +1440,8 @@ namespace Ttcn {
       config_op.compref2=p_compref2;
       config_op.portref2=p_portref2;
       config_op.translate=false;
+      config_op.parsed_params=p_params;
+      config_op.fp_list=NULL;
       break;
     default:
       FATAL_ERROR("Statement::Statement()");
@@ -1989,6 +1993,9 @@ namespace Ttcn {
       config_op.portref1->set_my_scope(p_scope);
       config_op.compref2->set_my_scope(p_scope);
       config_op.portref2->set_my_scope(p_scope);
+      if (config_op.parsed_params != NULL) {
+        config_op.parsed_params->set_my_scope(p_scope);
+      }
       break;
     case S_START_TIMER:
       timer_op.timerref->set_my_scope(p_scope);
@@ -2307,6 +2314,9 @@ namespace Ttcn {
       config_op.portref1->set_fullname(p_fullname+".portref1");
       config_op.compref2->set_fullname(p_fullname+".compref2");
       config_op.portref2->set_fullname(p_fullname+".portref2");
+      if (config_op.parsed_params != NULL) {
+        config_op.parsed_params->set_fullname(p_fullname+".<parameters>");
+      }
       break;
     case S_START_TIMER:
       timer_op.timerref->set_fullname(p_fullname+".timerref");
@@ -5031,6 +5041,12 @@ error:
           "endpoint is unknown",
           ptb1 != NULL ? "second" : "first");
       }
+      if (config_op.parsed_params != NULL &&
+          ((cref1_is_system && ptb1 == NULL) ||
+           (cref2_is_system && ptb2 == NULL))) {
+        error("Cannot determine system component in `%s' operation with "
+          "`param' clause", get_stmt_name());
+      }
       return;
     }
     if (cref1_is_tc || cref2_is_system) {
@@ -5100,6 +5116,32 @@ error:
         }
       }
     }
+    
+    if (config_op.parsed_params != NULL) {
+      if (cref1_is_system) {
+        config_op.fp_list = ptb1->get_map_parameters(statementtype == S_MAP);
+      }
+      else if (cref2_is_system) {
+        config_op.fp_list = ptb2->get_map_parameters(statementtype == S_MAP);
+      }
+      else {
+        error("Cannot determine system component in `%s' operation with "
+          "`param' clause", get_stmt_name());
+      }
+      if (config_op.fp_list != NULL) {
+        ActualParList* parlist = new ActualParList;
+        if (config_op.fp_list->fold_named_and_chk(config_op.parsed_params, parlist)) {
+          delete parlist;
+          delete config_op.parsed_params;
+          config_op.ap_list = NULL;
+        } else {
+          delete config_op.parsed_params;
+          parlist->set_fullname(get_fullname());
+          parlist->set_my_scope(my_sb);
+          config_op.ap_list = parlist;
+        }
+      }
+    }
   }
 
   void Statement::chk_start_timer()
@@ -7816,6 +7858,60 @@ error:
       // a simple string shall be formed from the port name and array indices
       generate_code_portref(&expr, config_op.portref2);
     }
+    if (config_op.ap_list != NULL) {
+      // handle 'map'/'unmap' parameters
+      size_t nof_pars = config_op.ap_list->get_nof_pars();
+      string tmp_id = my_sb->get_scope_mod_gen()->get_temporary_id();
+      expr.preamble = mputprintf(expr.preamble,
+        "Map_Params %s(%u);\n", tmp_id.c_str(), (unsigned int) nof_pars);
+      for (size_t i = 0; i < nof_pars; ++i) {
+        ActualPar* ap = config_op.ap_list->get_par(i);
+        FormalPar* fp = config_op.fp_list->get_fp_byIndex(i);
+        bool copy_needed = ap->get_selection() == ActualPar::AP_VALUE;
+        expression_struct par_expr;
+        Code::init_expr(&par_expr);
+        ap->generate_code(&par_expr, copy_needed, fp);
+        if (fp->get_asstype() != Definition::A_PAR_VAL_OUT) {
+          // set the values of 'in' and 'inout' parameters before the call
+          if (par_expr.preamble != NULL) {
+            expr.preamble = mputstr(expr.preamble, par_expr.preamble);
+          }
+          expr.preamble = mputprintf(expr.preamble,
+            "%s.set_param(%u, ttcn_to_string(%s));\n",
+            tmp_id.c_str(), (unsigned int) i, par_expr.expr);
+        }
+        else {
+          // set empty strings for 'out' parameters
+          expr.preamble = mputprintf(expr.preamble,
+            "%s.set_param(%u, CHARSTRING(\"\"));\n",
+            tmp_id.c_str(), (unsigned int) i);
+        }
+        if (fp->get_asstype() == Definition::A_PAR_VAL_OUT ||
+            fp->get_asstype() == Definition::A_PAR_VAL_INOUT) {
+          // store the new values of 'out' and 'inout' parameters after the call
+          // note: this only works in single mode, in parallel mode execution
+          // will continue after the mapping request, without waiting for a
+          // reply that could contain the new values of the parameters
+          expr.postamble = mputprintf(expr.postamble,
+            "if (%s.get_param(%u).lengthof() > 0) "
+            "string_to_ttcn(%s.get_param(%u), %s);\n",
+            tmp_id.c_str(), (unsigned int) i,
+            tmp_id.c_str(), (unsigned int) i, par_expr.expr);
+          if (par_expr.postamble != NULL) {
+            expr.postamble = mputstr(expr.postamble, par_expr.postamble);
+          }
+        }
+        Code::free_expr(&par_expr);
+      }
+      expr.expr = mputprintf(expr.expr, ", %s", tmp_id.c_str());
+    }
+    else if (statementtype == S_MAP || statementtype == S_UNMAP) {
+      // create an empty struct for 'connect' and 'disconnect'
+      string tmp_id = my_sb->get_scope_mod_gen()->get_temporary_id();
+      expr.preamble = mputprintf(expr.preamble,
+        "Map_Params %s(0);\n", tmp_id.c_str());
+      expr.expr = mputprintf(expr.expr, ", %s", tmp_id.c_str());
+    }
     if (config_op.translate == true) {
       expr.expr = mputstr(expr.expr, ", TRUE");
     }
diff --git a/compiler2/ttcn3/Statement.hh b/compiler2/ttcn3/Statement.hh
index 608012b10391faff58f48fb0be88b034978694cd..680c05a922357afa1bbe101551e89edf8eed4f6b 100644
--- a/compiler2/ttcn3/Statement.hh
+++ b/compiler2/ttcn3/Statement.hh
@@ -350,6 +350,11 @@ namespace Ttcn {
         Value *compref2;
         Reference *portref2;
         bool translate; // true if a map statement enables translation mode
+        union {
+          ParsedActualParameters* parsed_params;
+          ActualParList* ap_list;
+        };
+        FormalParList* fp_list; // not owned
       } config_op; ///< used by S_CONNECT, S_MAP, S_DISCONNECT, S_UNMAP
 
       struct {
@@ -618,7 +623,8 @@ namespace Ttcn {
     /** Constructor used by S_CONNECT, S_DISCONNECT, S_MAP, S_UNMAP */
     Statement(statementtype_t p_st,
               Value *p_compref1, Reference *p_portref1,
-              Value *p_compref2, Reference *p_portref2);
+              Value *p_compref2, Reference *p_portref2,
+              ParsedActualParameters* p_params);
     /** Constructor used by S_TESTCASE_INSTANCE */
     Statement(statementtype_t p_st, Ref_pard *p_ref, Value *p_val);
     /** Constructor used by S_ACTIVATE_REFD */
diff --git a/compiler2/ttcn3/Ttcnstuff.cc b/compiler2/ttcn3/Ttcnstuff.cc
index 61e544d7f24e2a630e874d3b7ff324f7456fc9e4..9eab7fdcbc0e4182035e48ff903e41248666f924 100644
--- a/compiler2/ttcn3/Ttcnstuff.cc
+++ b/compiler2/ttcn3/Ttcnstuff.cc
@@ -1036,7 +1036,7 @@ namespace Ttcn {
   PortTypeBody::PortTypeBody(PortOperationMode_t p_operation_mode,
     Types *p_in_list, Types *p_out_list, Types *p_inout_list,
     bool p_in_all, bool p_out_all, bool p_inout_all, Definitions *defs,
-    bool p_realtime)
+    bool p_realtime, FormalParList *p_map_params, FormalParList *p_unmap_params)
     : Node(), Location(), my_type(0), operation_mode(p_operation_mode),
     in_list(p_in_list), out_list(p_out_list), inout_list(p_inout_list),
     in_all(p_in_all), out_all(p_out_all), inout_all(p_inout_all),
@@ -1044,7 +1044,8 @@ namespace Ttcn {
     in_msgs(0), out_msgs(0), in_sigs(0), out_sigs(0),
     testport_type(TP_REGULAR), port_type(PT_REGULAR),
     provider_refs(), provider_types(),
-    in_mappings(0), out_mappings(0), vardefs(defs), realtime(p_realtime)
+    in_mappings(0), out_mappings(0), vardefs(defs), realtime(p_realtime),
+    map_params(p_map_params), unmap_params(p_unmap_params)
   {
   }
 
@@ -1065,6 +1066,8 @@ namespace Ttcn {
     delete in_mappings;
     delete out_mappings;
     delete vardefs;
+    delete map_params;
+    delete unmap_params;
   }
 
   PortTypeBody *PortTypeBody::clone() const
@@ -1088,6 +1091,12 @@ namespace Ttcn {
     if (in_mappings) in_mappings->set_fullname(p_fullname + ".<in_mappings>");
     if (out_mappings) out_mappings->set_fullname(p_fullname + ".<out_mappings>");
     vardefs->set_fullname(p_fullname + ".<port_var>");
+    if (map_params != NULL) {
+      map_params->set_fullname(p_fullname + ".<map_params>");
+    }
+    if (unmap_params != NULL) {
+      unmap_params->set_fullname(p_fullname + ".<unmap_params>");
+    }
   }
 
   void PortTypeBody::set_my_scope(Scope *p_scope)
@@ -1101,6 +1110,12 @@ namespace Ttcn {
     if (in_mappings) in_mappings->set_my_scope(p_scope);
     if (out_mappings) out_mappings->set_my_scope(p_scope);
     vardefs->set_parent_scope(p_scope);
+    if (map_params != NULL) {
+      map_params->set_my_scope(p_scope);
+    }
+    if (unmap_params != NULL) {
+      unmap_params->set_my_scope(p_scope);
+    }
   }
 
   void PortTypeBody::set_my_type(Type *p_type)
@@ -1186,6 +1201,11 @@ namespace Ttcn {
     if (!checked) FATAL_ERROR("PortTypeBody::is_internal_port()");
     return testport_type == TP_INTERNAL;
   }
+  
+  FormalParList* PortTypeBody::get_map_parameters(bool map) const
+  {
+    return map ? map_params : unmap_params;
+  }
 
   Type *PortTypeBody::get_address_type()
   {
@@ -1776,6 +1796,15 @@ namespace Ttcn {
     if (provider_refs.size() == 0 && vardefs->get_nof_asss() > 0) {
       error("Port variables can only be used when the port is a translation port.");
     }
+    
+    if (map_params != NULL) {
+      Error_Context cntxt(map_params, "In `map' parameters");
+      map_params->chk(Definition::A_PORT);
+    }
+    if (unmap_params != NULL) {
+      Error_Context cntxt(unmap_params, "In `unmap' parameters");
+      unmap_params->chk(Definition::A_PORT);
+    }
   }
 
   void PortTypeBody::chk_attributes(Ttcn::WithAttribPath *w_attrib_path)
@@ -2115,6 +2144,12 @@ namespace Ttcn {
   void PortTypeBody::generate_code(output_struct *target)
   {
     if (!checked || !my_type) FATAL_ERROR("PortTypeBody::generate_code()");
+    if (map_params != NULL) {
+      map_params->generate_code_defval(target);
+    }
+    if (unmap_params != NULL) {
+      unmap_params->generate_code_defval(target);
+    }
     stringpool pool;
     port_def pdef;
     memset(&pdef, 0, sizeof(pdef));
@@ -2593,6 +2628,14 @@ namespace Ttcn {
       DEBUG(level, "out mappings:");
       out_mappings->dump(level + 1);
     }
+    if (map_params != NULL) {
+      DEBUG(level, "map parameters:");
+      map_params->dump(level + 1);
+    }
+    if (unmap_params != NULL) {
+      DEBUG(level, "unmap parameters:");
+      unmap_params->dump(level + 1);
+    }
   }
 
   // =================================
diff --git a/compiler2/ttcn3/Ttcnstuff.hh b/compiler2/ttcn3/Ttcnstuff.hh
index 23a2f397b21b5b9885182b57a503e8339d4ac0d7..42b347a5a76bf24959f7febbfe236baa3d4b3591 100644
--- a/compiler2/ttcn3/Ttcnstuff.hh
+++ b/compiler2/ttcn3/Ttcnstuff.hh
@@ -405,6 +405,7 @@ private:
   TypeMappings *in_mappings, *out_mappings; ///< mappings for PT_USER
   Definitions *vardefs; ///< variable definitions inside the port
   bool realtime;
+  FormalParList *map_params, *unmap_params;
   /** Copy constructor not implemented */
   PortTypeBody(const PortTypeBody& p);
   /** Assignment disabled */
@@ -413,7 +414,7 @@ public:
   PortTypeBody(PortOperationMode_t p_operation_mode,
     Types *p_in_list, Types *p_out_list, Types *p_inout_list,
     bool p_in_all, bool p_out_all, bool p_inout_all, Definitions *defs,
-    bool p_realtime);
+    bool p_realtime, FormalParList *p_map_params, FormalParList *p_unmap_params);
   ~PortTypeBody();
   virtual PortTypeBody *clone() const;
   virtual void set_fullname(const string& p_fullname);
@@ -430,6 +431,7 @@ public:
   bool getreply_allowed() const;
   bool catch_allowed() const;
   bool is_internal() const;
+  FormalParList* get_map_parameters(bool map) const;
   /** Returns the address type that can be used in communication operations
    * on this port type. NULL is returned if addressing inside SUT is not
    * supported or the address type does not exist. */
diff --git a/compiler2/ttcn3/compiler.y b/compiler2/ttcn3/compiler.y
index c38479a54cba7f1585c0f213d695507cc637d681..10fe18cfb73e95c9db09f4e20f9a38b75975efcb 100644
--- a/compiler2/ttcn3/compiler.y
+++ b/compiler2/ttcn3/compiler.y
@@ -288,6 +288,7 @@ static const string anyname("anytype");
     TypeMappings *in_mappings, *out_mappings;
     size_t varnElements;
     Ttcn::Definition **varElements;
+    FormalParList *map_params, *unmap_params;
   } portdefbody;
   
   struct {
@@ -978,7 +979,7 @@ static const string anyname("anytype");
   TemplateFormalPar FunctionFormalPar TestcaseFormalPar
 %type <formalparlist> optTemplateFormalParList TemplateFormalParList
   optFunctionFormalParList FunctionFormalParList optTestcaseFormalParList
-  TestcaseFormalParList optAltstepFormalParList
+  TestcaseFormalParList optAltstepFormalParList FormalValueParList
 %type <group> GroupDef GroupIdentifier
 %type <friend_list> FriendModuleDef
 %type <ifclause> ElseIfClause
@@ -1038,7 +1039,7 @@ static const string anyname("anytype");
   optReceiveParameter
 %type <parsedpar> FunctionActualParList TestcaseActualParList
   optFunctionActualParList optTestcaseActualParList
-  NamedPart UnnamedPart
+  NamedPart UnnamedPart optParamClause
 %type <templinsts>  optTemplateActualParList
   seqTemplateActualPar seqTemplateInstance
 %type <templs> ValueOrAttribList seqValueOrAttrib ValueList Complement
@@ -1269,6 +1270,7 @@ ForStatement
 FormalTemplatePar
 FormalTimerPar
 FormalValuePar
+FormalValueParList
 FromClause
 FullGroupIdentifier
 FunctionActualPar
@@ -1475,6 +1477,7 @@ optFunctionActualParList
 optFunctionFormalParList
 optMtcSpec
 optParDefaultValue
+optParamClause
 optPortCallBody
 optPortRedirectOutgoing
 optReceiveParameter
@@ -1576,6 +1579,8 @@ StructOfDefBody
     delete $$.varElements[i];
   }
   delete $$.varElements;
+  delete $$.map_params;
+  delete $$.unmap_params;
 }
 PortDefList
 PortDefLists
@@ -2886,7 +2891,8 @@ PortDefAttribs: // 60
     Free($3.varElements);
     PortTypeBody *body = new PortTypeBody($1,
       $3.in_list, $3.out_list, $3.inout_list,
-      $3.in_all, $3.out_all, $3.inout_all, defs, $2);
+      $3.in_all, $3.out_all, $3.inout_all, defs, $2,
+      $3.map_params, $3.unmap_params);
     body->set_location(infile, @$);
     $$ = new Type(Type::T_PORT, body);
     $$->set_location(infile, @$);
@@ -2904,7 +2910,8 @@ PortDefAttribs: // 60
     Free($6.varElements);
     PortTypeBody *body = new PortTypeBody($1,
       $6.in_list, $6.out_list, $6.inout_list,
-      $6.in_all, $6.out_all, $6.inout_all, defs, $2);
+      $6.in_all, $6.out_all, $6.inout_all, defs, $2,
+      $6.map_params, $6.unmap_params);
     body->set_location(infile, @$);
     $$ = new Type(Type::T_PORT, body);
     body->add_user_attribute($5.elements, $5.nElements, $6.in_mappings, $6.out_mappings, false);
@@ -2934,6 +2941,8 @@ PortDefLists:
     $$.out_mappings = 0;
     $$.varnElements = 0;
     $$.varElements = 0;
+    $$.map_params = NULL;
+    $$.unmap_params = NULL;
   }
 ;
 
@@ -3004,6 +3013,26 @@ seqPortDefList:
       }
       Free($2.varElements);
     }
+    if ($2.map_params != NULL) {
+      if ($$.map_params != NULL) {
+        Location loc(infile, @2);
+        loc.error("Multiple `map' parameter lists in port type definition");
+        delete $2.map_params;
+      }
+      else {
+        $$.map_params = $2.map_params;
+      }
+    }
+    if ($2.unmap_params != NULL) {
+      if ($$.unmap_params != NULL) {
+        Location loc(infile, @2);
+        loc.error("Multiple `unmap' parameter lists in port type definition");
+        delete $2.unmap_params;
+      }
+      else {
+        $$.unmap_params = $2.unmap_params;
+      }
+    }
   }
 ;
 
@@ -3031,6 +3060,8 @@ PortDefList:
     $$.inout_all = false;
     $$.varnElements = 0;
     $$.varElements = 0;
+    $$.map_params = NULL;
+    $$.unmap_params = NULL;
   }
 | OutParKeyword AllOrTypeListWithTo
   {
@@ -3055,6 +3086,8 @@ PortDefList:
     $$.inout_all = false;
     $$.varnElements = 0;
     $$.varElements = 0;
+    $$.map_params = NULL;
+    $$.unmap_params = NULL;
   }
 | InOutParKeyword AllOrTypeList
   {
@@ -3075,6 +3108,8 @@ PortDefList:
     $$.out_mappings = 0;
     $$.varnElements = 0;
     $$.varElements = 0;
+    $$.map_params = NULL;
+    $$.unmap_params = NULL;
   }
 | InParKeyword error
   {
@@ -3088,6 +3123,8 @@ PortDefList:
     $$.out_mappings = 0;
     $$.varnElements = 0;
     $$.varElements = 0;
+    $$.map_params = NULL;
+    $$.unmap_params = NULL;
   }
 | OutParKeyword error
   {
@@ -3101,6 +3138,8 @@ PortDefList:
     $$.out_mappings = 0;
     $$.varnElements = 0;
     $$.varElements = 0;
+    $$.map_params = NULL;
+    $$.unmap_params = NULL;
   }
 | InOutParKeyword error
   {
@@ -3114,6 +3153,8 @@ PortDefList:
     $$.out_mappings = 0;
     $$.varnElements = 0;
     $$.varElements = 0;
+    $$.map_params = NULL;
+    $$.unmap_params = NULL;
   }
 | PortElementVarDef optSemiColon {
     $$.in_list = 0;
@@ -3130,7 +3171,54 @@ PortDefList:
       $$.varElements[i] = $1.elements[i];
     }
     delete $1.elements;
-}
+    $$.map_params = NULL;
+    $$.unmap_params = NULL;
+  }
+| MapKeyword ParamKeyword '(' FormalValueParList ')'
+  {
+    $$.in_list = 0;
+    $$.out_list = 0;
+    $$.inout_list = 0;
+    $$.in_all = false;
+    $$.out_all = false;
+    $$.inout_all = false;
+    $$.in_mappings = 0;
+    $$.out_mappings = 0;
+    $$.varnElements = 0;
+    $$.varElements = 0;
+    $$.map_params = $4;
+    $$.map_params->set_location(infile, @4);
+    $$.unmap_params = NULL;
+  }
+| UnmapKeyword ParamKeyword '(' FormalValueParList ')'
+  {
+    $$.in_list = 0;
+    $$.out_list = 0;
+    $$.inout_list = 0;
+    $$.in_all = false;
+    $$.out_all = false;
+    $$.inout_all = false;
+    $$.in_mappings = 0;
+    $$.out_mappings = 0;
+    $$.varnElements = 0;
+    $$.varElements = 0;
+    $$.map_params = NULL;
+    $$.unmap_params = $4;
+    $$.unmap_params->set_location(infile, @4);
+  }
+;
+
+FormalValueParList:
+  FormalValuePar
+  {
+    $$ = new FormalParList;
+    $$->add_fp($1);
+  }
+| FormalValueParList ',' FormalValuePar
+  {
+    $$ = $1;
+    $$->add_fp($3);
+  }
 ;
 
 WithList:
@@ -6072,7 +6160,7 @@ ConnectStatement: // 329
   ConnectKeyword SingleConnectionSpec
   {
     $$=new Statement(Statement::S_CONNECT,
-                     $2.compref1, $2.portref1, $2.compref2, $2.portref2);
+                     $2.compref1, $2.portref1, $2.compref2, $2.portref2, NULL);
     $$->set_location(infile, @$);
   }
 ;
@@ -6115,7 +6203,7 @@ DisconnectStatement: // 335
   {
     if ($2.portref1 && $2.portref2 && $2.compref1 && $2.compref2) {
       $$ = new Statement(Statement::S_DISCONNECT,
-	$2.compref1, $2.portref1, $2.compref2, $2.portref2);
+                         $2.compref1, $2.portref1, $2.compref2, $2.portref2, NULL);
     } else {
       Location loc(infile, @$);
       loc.error("Disconnect operation on multiple connections is "
@@ -6168,15 +6256,20 @@ AllCompsAllPortsSpec: // 339
 ;
 
 MapStatement: // 341
-  MapKeyword SingleConnectionSpec
+  MapKeyword SingleConnectionSpec optParamClause
   {
     $$=new Statement(Statement::S_MAP,
                      $2.compref1, $2.portref1,
-                     $2.compref2, $2.portref2);
+                     $2.compref2, $2.portref2, $3);
     $$->set_location(infile, @$);
   }
 ;
 
+optParamClause:
+  /* empty */ { $$ = NULL; }
+| ParamKeyword '(' FunctionActualParList ')' { $$ = $3; }
+;
+
 UnmapStatement: // 343
   UnmapKeyword
   {
@@ -6186,11 +6279,11 @@ UnmapStatement: // 343
     loc.error("Unmap operation on multiple mappings is "
       "not currently supported");
   }
-| UnmapKeyword SingleOrMultiConnectionSpec
+| UnmapKeyword SingleOrMultiConnectionSpec optParamClause
   {
     if ($2.compref1 && $2.portref1 && $2.compref1 && $2.compref2) {
       $$ = new Statement(Statement::S_UNMAP,
-	$2.compref1, $2.portref1, $2.compref2, $2.portref2);
+                         $2.compref1, $2.portref1, $2.compref2, $2.portref2, $3);
     } else {
       Location loc(infile, @$);
       loc.error("Unmap operation on multiple mappings is "
@@ -6199,6 +6292,7 @@ UnmapStatement: // 343
       delete $2.portref1;
       delete $2.compref2;
       delete $2.portref2;
+      delete $3;
       $$ = new Statement(Statement::S_ERROR);
     }
     $$->set_location(infile, @$);
diff --git a/compiler2/ttcn3/port.c b/compiler2/ttcn3/port.c
index 35e8318de9055befd190bba9b0dcacbd50bc47b1..9070bb66e38d87837d71827740f0b2d3218b3d77 100644
--- a/compiler2/ttcn3/port.c
+++ b/compiler2/ttcn3/port.c
@@ -3601,8 +3601,8 @@ void generateTestPortSkeleton(const port_def *pdef)
       "\tvoid Handle_Fd_Event_Readable(int fd);\n"
       "\t/* void Handle_Timeout(double time_since_last_call); */\n"
       "protected:\n"
-      "\tvoid user_map(const char *system_port);\n"
-      "\tvoid user_unmap(const char *system_port);\n\n"
+      "\tvoid user_map(const char *system_port, Map_Params& params);\n"
+      "\tvoid user_unmap(const char *system_port, Map_Params& params);\n\n"
       "\tvoid user_start();\n"
       "\tvoid user_stop();\n\n",
       class_name, base_class_name, class_name,
@@ -3782,10 +3782,12 @@ void generateTestPortSkeleton(const port_def *pdef)
       "{\n\n"
       "}\n\n"
       "/*void %s::Handle_Timeout(double time_since_last_call) {}*/\n\n"
-      "void %s::user_map(const char * /*system_port*/)\n"
+      "void %s::user_map(const char * /*system_port*/, "
+      "Map_Params& /*params*/)\n"
       "{\n\n"
       "}\n\n"
-      "void %s::user_unmap(const char * /*system_port*/)\n"
+      "void %s::user_unmap(const char * /*system_port*/, "
+      "Map_Params& /*params*/)\n"
       "{\n\n"
       "}\n\n"
       "void %s::user_start()\n"
diff --git a/core/Communication.cc b/core/Communication.cc
index f34053853d5c30c91ee2f30be89e338d467a6dfd..4d4cb28c922482d65835932e36860ff203cbdae8 100644
--- a/core/Communication.cc
+++ b/core/Communication.cc
@@ -1024,7 +1024,8 @@ void TTCN_Communication::send_disconnected(const char *local_port,
 }
 
 void TTCN_Communication::send_map_req(component src_component,
-  const char *src_port, const char *system_port, boolean translation)
+  const char *src_port, const char *system_port, Map_Params& params,
+  boolean translation)
 {
   Text_Buf text_buf;
   text_buf.push_int(MSG_MAP_REQ);
@@ -1032,6 +1033,11 @@ void TTCN_Communication::send_map_req(component src_component,
   text_buf.push_int(translation == FALSE ? 0 : 1);
   text_buf.push_string(src_port);
   text_buf.push_string(system_port);
+  unsigned int nof_params = params.get_nof_params();
+  text_buf.push_int(nof_params);
+  for (unsigned int i = 0; i < nof_params; ++i) {
+    text_buf.push_string((const char*) params.get_param(i));
+  }
   send_message(text_buf);
 }
 
@@ -1047,7 +1053,8 @@ void TTCN_Communication::send_mapped(const char *local_port,
 }
 
 void TTCN_Communication::send_unmap_req(component src_component,
-  const char *src_port, const char *system_port, boolean translation)
+  const char *src_port, const char *system_port, Map_Params& params,
+  boolean translation)
 {
   Text_Buf text_buf;
   text_buf.push_int(MSG_UNMAP_REQ);
@@ -1055,6 +1062,11 @@ void TTCN_Communication::send_unmap_req(component src_component,
   text_buf.push_int(translation == FALSE ? 0 : 1);
   text_buf.push_string(src_port);
   text_buf.push_string(system_port);
+  unsigned int nof_params = params.get_nof_params();
+  text_buf.push_int(nof_params);
+  for (unsigned int i = 0; i < nof_params; ++i) {
+    text_buf.push_string((const char*) params.get_param(i));
+  }
   send_message(text_buf);
 }
 
@@ -1767,12 +1779,19 @@ void TTCN_Communication::process_map()
   boolean translation = incoming_buf.pull_int().get_val() == 0 ? FALSE : TRUE;
   char *local_port = incoming_buf.pull_string();
   char *system_port = incoming_buf.pull_string();
+  unsigned int nof_params = incoming_buf.pull_int().get_val();
+  Map_Params params(nof_params);
+  for (unsigned int i = 0; i < nof_params; ++i) {
+    char* par = incoming_buf.pull_string();
+    params.set_param(i, CHARSTRING(par));
+    delete [] par;
+  }
   incoming_buf.cut_message();
 
   try {
-    PORT::map_port(local_port, system_port, FALSE);
+    PORT::map_port(local_port, system_port, params, FALSE);
     if (translation == TRUE) {
-      PORT::map_port(local_port, system_port, TRUE);
+      PORT::map_port(local_port, system_port, params, TRUE);
     }
     if (!TTCN_Runtime::is_single()) {
       if (translation == FALSE) {
@@ -1813,12 +1832,19 @@ void TTCN_Communication::process_unmap()
   boolean translation = incoming_buf.pull_int().get_val() == 0 ? FALSE : TRUE;
   char *local_port = incoming_buf.pull_string();
   char *system_port = incoming_buf.pull_string();
+  unsigned int nof_params = incoming_buf.pull_int().get_val();
+  Map_Params params(nof_params);
+  for (unsigned int i = 0; i < nof_params; ++i) {
+    char* par = incoming_buf.pull_string();
+    params.set_param(i, CHARSTRING(par));
+    delete [] par;
+  }
   incoming_buf.cut_message();
 
   try {
-    PORT::unmap_port(local_port, system_port, FALSE);
+    PORT::unmap_port(local_port, system_port, params, FALSE);
     if (translation == TRUE) {
-      PORT::unmap_port(local_port, system_port, TRUE);
+      PORT::unmap_port(local_port, system_port, params, TRUE);
     }
     if (!TTCN_Runtime::is_single()) {
       if (translation == FALSE) {
diff --git a/core/Communication.hh b/core/Communication.hh
index be7d54b3d944c58dd9ef8d61fa87009e59d83436..5397a04bb51f5fa57bf4878dd55f98993b23b6c5 100644
--- a/core/Communication.hh
+++ b/core/Communication.hh
@@ -34,6 +34,7 @@ struct sockaddr_un;
 #include "NetworkHandler.hh"
 
 class MC_Connection;
+class Map_Params;
 
 class TTCN_Communication {
   static int mc_fd;
@@ -120,11 +121,11 @@ public:
   static void send_disconnected(const char *local_port,
     component remote_component, const char *remote_port);
   static void send_map_req(component src_component, const char *src_port,
-    const char *system_port, boolean translation);
+    const char *system_port, Map_Params& params, boolean translation);
   static void send_mapped(const char *local_port,
     const char *system_port, boolean translation);
-  static void send_unmap_req(component src_component,
-    const char *src_port, const char *system_port, boolean translation);
+  static void send_unmap_req(component src_component, const char *src_port,
+    const char *system_port, Map_Params& params, boolean translation);
   static void send_unmapped(const char *local_port,
     const char *system_port, boolean translation);
 
diff --git a/core/Port.cc b/core/Port.cc
index 9ba366bd55174650d43715bfca74420e0565ce0c..fcc02a312343229abfd66134357f2b6df052c60e 100644
--- a/core/Port.cc
+++ b/core/Port.cc
@@ -53,6 +53,35 @@
 
 #include "../common/dbgnew.hh"
 
+Map_Params::Map_Params(unsigned int p_nof_params)
+: nof_params(p_nof_params), params(new CHARSTRING[nof_params]) { }
+
+Map_Params::~Map_Params()
+{
+  delete[] params;
+}
+
+void Map_Params::set_param(unsigned int p_index, const CHARSTRING& p_param)
+{
+  if (p_index >= nof_params) {
+    TTCN_error("Map/unmap parameter index out of bounds");
+  }
+  params[p_index] = p_param;
+}
+
+unsigned int Map_Params::get_nof_params() const
+{
+  return nof_params;
+}
+
+const CHARSTRING& Map_Params::get_param(unsigned int p_index) const
+{
+  if (p_index >= nof_params) {
+    TTCN_error("Map/unmap parameter index out of bounds");
+  }
+  return params[p_index];
+}
+
 PORT *PORT::list_head = NULL, *PORT::list_tail = NULL;
 PORT *PORT::system_list_head = NULL, *PORT::system_list_tail = NULL;
 
@@ -357,7 +386,8 @@ void PORT::deactivate_port(boolean system)
         TitanLoggerApi::Port__Misc_reason::removing__unterminated__mapping,
         port_name, NULL_COMPREF, system_port);
       try {
-        unmap(system_port, system);
+        Map_Params params(0);
+        unmap(system_port, params, system);
       } catch (const TC_Error&) { }
       if (is_parallel) {
         try {
@@ -1146,12 +1176,28 @@ void PORT::Uninstall_Handler()
   Fd_And_Timeout_User::set_timer(this, 0.0);
 }
 
-void PORT::user_map(const char *)
+void PORT::user_map(const char *system_port)
 {
+  // call the new user_map function if the legacy version is not overridden in
+  // the port implementation
+  Map_Params dummy(0);
+  user_map(system_port, dummy);
+}
 
+void PORT::user_unmap(const char *system_port)
+{
+  // call the new user_unmap function if the legacy version is not overridden in
+  // the port implementation
+  Map_Params dummy(0);
+  user_unmap(system_port, dummy);
 }
 
-void PORT::user_unmap(const char *)
+void PORT::user_map(const char *, Map_Params&)
+{
+
+}
+
+void PORT::user_unmap(const char *, Map_Params&)
 {
 
 }
@@ -2190,7 +2236,7 @@ void PORT::process_last_message(port_connection *conn_ptr)
   }
 }
 
-void PORT::map(const char *system_port, boolean translation)
+void PORT::map(const char *system_port, Map_Params& params, boolean translation)
 {
   if (!is_active) TTCN_error("Inactive port %s cannot be mapped.", port_name);
 
@@ -2215,7 +2261,13 @@ void PORT::map(const char *system_port, boolean translation)
     set_system_parameters(port_name);
   }
 
-  user_map(system_port);
+  if (params.get_nof_params() == 0) {
+    // call the legacy function if there are no parameters (for backward compatibility)
+    user_map(system_port);
+  }
+  else {
+    user_map(system_port, params);
+  }
 
   if (translation == FALSE) {
     TTCN_Logger::log_port_misc(
@@ -2241,7 +2293,7 @@ void PORT::map(const char *system_port, boolean translation)
     "addressing.", port_name);
 }
 
-void PORT::unmap(const char *system_port, boolean translation)
+void PORT::unmap(const char *system_port, Map_Params& params, boolean translation)
 {
   int del_posn;
   for (del_posn = 0; del_posn < n_system_mappings; del_posn++) {
@@ -2273,7 +2325,13 @@ void PORT::unmap(const char *system_port, boolean translation)
     n_system_mappings * sizeof(*system_mappings));
 
   try {
-    user_unmap(system_port);
+    if (params.get_nof_params() == 0) {
+      // call the legacy function if there are no parameters (for backward compatibility)
+      user_unmap(system_port);
+    }
+    else {
+      user_unmap(system_port, params);
+    }
   } catch (...) {
     // prevent from memory leak
     Free(unmapped_port);
@@ -2517,7 +2575,8 @@ void PORT::terminate_local_connection(const char *src_port,
   }
 }
 
-void PORT::map_port(const char *component_port, const char *system_port, boolean translation)
+void PORT::map_port(const char *component_port, const char *system_port,
+                    Map_Params& params, boolean translation)
 {
   if (translation == TRUE) {
     TTCN_Runtime::initialize_system_port(system_port);
@@ -2530,9 +2589,9 @@ void PORT::map_port(const char *component_port, const char *system_port, boolean
     TTCN_error("Map operation is not allowed on a connected port (%s).", port_name);
   }
   if (translation == FALSE) {
-    port_ptr->map(system_port, translation);
+    port_ptr->map(system_port, params, translation);
   } else {
-    port_ptr->map(component_port, translation);
+    port_ptr->map(component_port, params, translation);
   }
   if (translation == TRUE) {
     PORT* other_port_ptr = lookup_by_name(component_port, FALSE);
@@ -2544,7 +2603,8 @@ void PORT::map_port(const char *component_port, const char *system_port, boolean
   }
 }
 
-void PORT::unmap_port(const char *component_port, const char *system_port, boolean translation)
+void PORT::unmap_port(const char *component_port, const char *system_port,
+                      Map_Params& params, boolean translation)
 {
   if (translation == TRUE) {
     TTCN_Runtime::initialize_system_port(system_port);
@@ -2554,9 +2614,9 @@ void PORT::unmap_port(const char *component_port, const char *system_port, boole
   if (port_ptr == NULL) TTCN_error("Unmap operation refers to "
     "non-existent port %s.", port_name);
   if (translation == FALSE) {
-    port_ptr->unmap(system_port, translation);
+    port_ptr->unmap(system_port, params, translation);
   } else {
-    port_ptr->unmap(component_port, translation);
+    port_ptr->unmap(component_port, params, translation);
   }
   if (translation == TRUE) {
     PORT* other_port_ptr = lookup_by_name(component_port, FALSE);
diff --git a/core/Port.hh b/core/Port.hh
index 568177c4f1c23fad0dc8606f16b0180175f3767b..e969b86a6d313b779eff756ed5f5a1b4009519b4 100644
--- a/core/Port.hh
+++ b/core/Port.hh
@@ -39,6 +39,20 @@ extern const COMPONENT_template& any_compref;
 
 struct port_connection; // no user serviceable parts inside
 
+class Map_Params {
+  unsigned int nof_params;
+  CHARSTRING* params;
+  
+  Map_Params(const Map_Params&); // copy disabled
+  Map_Params& operator=(const Map_Params&); // assignment disabled
+public:
+  Map_Params(unsigned int p_nof_params);
+  ~Map_Params();
+  void set_param(unsigned int p_index, const CHARSTRING& p_param);
+  unsigned int get_nof_params() const;
+  const CHARSTRING& get_param(unsigned int p_index) const;
+};
+
 /** Base class for all test ports */
 class PORT : public Fd_And_Timeout_Event_Handler {
   friend class PORT_LIST;
@@ -305,10 +319,15 @@ protected:
   * It can be used together with the interface introduced in TITAN R7E.
   */
   void Uninstall_Handler();
-
+  
+  // legacy map and unmap functions for backward compatibility
   virtual void user_map(const char *system_port);
   virtual void user_unmap(const char *system_port);
 
+  // new map and unmap functions (with parameters)
+  virtual void user_map(const char *system_port, Map_Params& params);
+  virtual void user_unmap(const char *system_port, Map_Params& params);
+
   virtual void user_start();
   virtual void user_stop();
 
@@ -376,8 +395,8 @@ private:
   void handle_incoming_data(port_connection *conn_ptr);
   void process_last_message(port_connection *conn_ptr);
 
-  void map(const char *system_port, boolean translation);
-  void unmap(const char *system_port, boolean translation);
+  void map(const char *system_port, Map_Params& params, boolean translation);
+  void unmap(const char *system_port, Map_Params& params, boolean translation);
 
 public:
   static void process_connect_listen(const char *local_port,
@@ -393,8 +412,8 @@ public:
   static void terminate_local_connection(const char *src_port,
     const char *dest_port);
 
-  static void map_port(const char *component_port, const char *system_port, boolean translation);
-  static void unmap_port(const char *component_port, const char *system_port, boolean translation);
+  static void map_port(const char *component_port, const char *system_port, Map_Params& params, boolean translation);
+  static void unmap_port(const char *component_port, const char *system_port, Map_Params& params, boolean translation);
 };
 
 #endif
diff --git a/core/Runtime.cc b/core/Runtime.cc
index 13819f516168877a081f8d7aecbbc94b52b954c7..c1bb2a57d37b58159f7807c6fa0a36277cbbf865 100644
--- a/core/Runtime.cc
+++ b/core/Runtime.cc
@@ -1865,7 +1865,8 @@ void TTCN_Runtime::disconnect_port(
 
 void TTCN_Runtime::map_port(
   const COMPONENT& src_compref, const char *src_port,
-  const COMPONENT& dst_compref, const char *dst_port, boolean translation)
+  const COMPONENT& dst_compref, const char *dst_port, Map_Params& params,
+  boolean translation)
 {
   check_port_name(src_port, "map", "first");
   check_port_name(dst_port, "map", "second");
@@ -1913,20 +1914,20 @@ void TTCN_Runtime::map_port(
   case SINGLE_TESTCASE:
     if (comp_reference != MTC_COMPREF) TTCN_error("Only the ports of mtc "
       "can be mapped in single mode.");
-    PORT::map_port(comp_port, system_port, FALSE);
+    PORT::map_port(comp_port, system_port, params, FALSE);
     if (translation == TRUE) {
-      PORT::map_port(comp_port, system_port, TRUE);
+      PORT::map_port(comp_port, system_port, params, TRUE);
     }
     break;
   case MTC_TESTCASE:
     TTCN_Communication::send_map_req(comp_reference, comp_port,
-      system_port, translation);
+      system_port, params, translation);
     executor_state = MTC_MAP;
     wait_for_state_change();
     break;
   case PTC_FUNCTION:
     TTCN_Communication::send_map_req(comp_reference, comp_port,
-      system_port, translation);
+      system_port, params, translation);
     executor_state = PTC_MAP;
     wait_for_state_change();
     break;
@@ -1946,7 +1947,8 @@ void TTCN_Runtime::map_port(
 
 void TTCN_Runtime::unmap_port(
   const COMPONENT& src_compref, const char *src_port,
-  const COMPONENT& dst_compref, const char *dst_port, boolean translation)
+  const COMPONENT& dst_compref, const char *dst_port, Map_Params& params,
+  boolean translation)
 {
   check_port_name(src_port, "unmap", "first");
   check_port_name(dst_port, "unmap", "second");
@@ -1994,20 +1996,20 @@ void TTCN_Runtime::unmap_port(
   case SINGLE_TESTCASE:
     if (comp_reference != MTC_COMPREF) TTCN_error("Only the ports of mtc "
       "can be unmapped in single mode.");
-    PORT::unmap_port(comp_port, system_port, FALSE);
+    PORT::unmap_port(comp_port, system_port, params, FALSE);
     if (translation == TRUE) {
-      PORT::unmap_port(comp_port, system_port, TRUE);
+      PORT::unmap_port(comp_port, system_port, params, TRUE);
     }
     break;
   case MTC_TESTCASE:
     TTCN_Communication::send_unmap_req(comp_reference, comp_port,
-      system_port, translation);
+      system_port, params, translation);
     executor_state = MTC_UNMAP;
     wait_for_state_change();
     break;
   case PTC_FUNCTION:
     TTCN_Communication::send_unmap_req(comp_reference, comp_port,
-      system_port, translation);
+      system_port, params, translation);
     executor_state = PTC_UNMAP;
     wait_for_state_change();
     break;
diff --git a/core/Runtime.hh b/core/Runtime.hh
index c8b057480d2089c5dae466fcaf9797990d207652..0dc86197d9410c104fcc73ef8626f8a2e42a817c 100644
--- a/core/Runtime.hh
+++ b/core/Runtime.hh
@@ -33,6 +33,7 @@ class CHARSTRING;
 class INTEGER;
 class FLOAT;
 class PORT;
+class Map_Params;
 
 extern "C" {
 typedef void (*signal_handler_type)(int);
@@ -270,10 +271,12 @@ public:
     const COMPONENT& dst_compref, const char *dst_port);
   static void map_port(
     const COMPONENT& src_compref, const char *src_port,
-    const COMPONENT& dst_compref, const char *dst_port, boolean translation = FALSE);
+    const COMPONENT& dst_compref, const char *dst_port,
+    Map_Params& params, boolean translation = FALSE);
   static void unmap_port(
     const COMPONENT& src_compref, const char *src_port,
-    const COMPONENT& dst_compref, const char *dst_port, boolean translation = FALSE);
+    const COMPONENT& dst_compref, const char *dst_port,
+    Map_Params& params, boolean translation = FALSE);
 
   static void begin_controlpart(const char *module_name);
   static void end_controlpart();
diff --git a/function_test/Semantic_Analyser/Makefile.semantic b/function_test/Semantic_Analyser/Makefile.semantic
index ffbf6d0b9c7626c83a40873885029632f7a23d88..151bdb7df69ec5b29d9bac5fcd2d11af4d730560 100644
--- a/function_test/Semantic_Analyser/Makefile.semantic
+++ b/function_test/Semantic_Analyser/Makefile.semantic
@@ -16,7 +16,7 @@ include ../../Makefile.personal
 
 SADIRS := ver param template any_from pattern_ref float recof_index \
 port_translation mtc_and_system_clause port_map_connect deterministic invoking_function_from_specific_places \
-json realtime
+json realtime map_param
 ifdef RT2
 SADIRS += deprecated erroneous_attributes template_concat
 endif
diff --git a/function_test/Semantic_Analyser/map_param/.gitignore b/function_test/Semantic_Analyser/map_param/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e2d293255e6d2f314e34950e486a48630d873491
--- /dev/null
+++ b/function_test/Semantic_Analyser/map_param/.gitignore
@@ -0,0 +1,2 @@
+!Makefile
+!*.ttcn
diff --git a/function_test/Semantic_Analyser/map_param/Makefile b/function_test/Semantic_Analyser/map_param/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..12d2217e87b8d0a1ddc38baad5b76c3685d4dc5a
--- /dev/null
+++ b/function_test/Semantic_Analyser/map_param/Makefile
@@ -0,0 +1,13 @@
+##############################################################################
+# Copyright (c) 2000-2019 Ericsson Telecom AB
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+#
+# Contributors:
+#   Balasko, Jeno
+#   Baranyi, Botond
+#
+##############################################################################
+include ../common.mk
diff --git a/function_test/Semantic_Analyser/map_param/map_param_SE.ttcn b/function_test/Semantic_Analyser/map_param/map_param_SE.ttcn
new file mode 100644
index 0000000000000000000000000000000000000000..5c69d208429be0ac5dbab555100336f9c5b0b84b
--- /dev/null
+++ b/function_test/Semantic_Analyser/map_param/map_param_SE.ttcn
@@ -0,0 +1,92 @@
+/******************************************************************************
+ * Copyright (c) 2000-2019 Ericsson Telecom AB
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+ *
+ * Contributors:
+ *   Baranyi, Botond
+ *
+ ******************************************************************************/
+module map_param_SE { //^In TTCN-3 module//
+
+/* testing the 'map param' and 'unmap' param clauses in port type definitions */
+type port PT1 message {
+  inout charstring
+}
+
+type component CT1 {}
+
+type record of CT1 CompList; //Prohibited type is here//
+
+type set Set_w_default {
+  default f //Prohibited type is here//
+}
+
+type port PT2 message { //^In type definition//
+  inout integer
+  map param (CT1 a, in default b, inout PT1 c) //^In `map' parameters// //^In formal parameter list// //^In parameter//3 //The `map'/`unmap' parameters of a port type cannot be or contain a field/element of component type// //Prohibited type is here//2 //The `map'/`unmap' parameters of a port type cannot be or contain a field/element of default type// //The `map'/`unmap' parameters of a port type cannot have port parameter//
+  unmap param (out CompList d, inout Set_w_default e) //^In `unmap' parameters// //In formal parameter list// //^In parameter//2 //The `map'/`unmap' parameters of a port type cannot be or contain a field/element of component type// //The `map'/`unmap' parameters of a port type cannot be or contain a field/element of default type//
+}
+
+signature Sig(in integer x, out float y);
+
+type port PT3 procedure { //^In type definition//
+  inout Sig
+  map param (in integer x, out float x) //^In `map' parameters// //^In formal parameter list// //Duplicate parameter with name// //Previous definition of `x' is here//
+  unmap param (inout Nonexistent x) //^In `unmap' parameters// //^In formal parameter list// //^In parameter// //There is no local or imported definition with name//
+}
+
+type record of integer IntList;
+
+type octetstring Oct2 length (2);
+
+type port PT4 message {
+  inout integer
+  map param (in Oct2 x, out IntList y)
+  unmap param (inout integer z)
+}
+
+type component CT4 {
+  port PT4 pt
+}
+
+/* testing the 'param' clause in 'map' and 'unmap' operations */
+testcase tc() runs on CT4 { //^In testcase definition//
+  map(mtc:pt, system:pt);
+  unmap(mtc:pt, system:pt);
+  
+  var IntList list;
+  var integer i := 6;
+  map(mtc:pt, system:pt) param ('ABCD'O, list);
+  unmap(mtc:pt, system:pt) param (i);
+  
+  map(mtc:pt, system:pt) param (x := 'ABCD'O, y := list);
+  unmap(mtc:pt, system:pt) param (z := i);
+  
+  map(mtc:pt, system:pt) param (octetstring: 'ABCD'O, IntList: list); //^In map statement// //^In parameter// //Explicit type specification is useless for//
+  unmap(mtc:pt, system:pt) param (integer: i); //^In unmap statement// //^In parameter// //Explicit type specification is useless for//
+  
+  map(mtc:pt, system:pt) param ('11223344'O, i); //^In map statement// //^In parameter//2 //is not a valid value for type `octetstring' which has subtype// //Reference to a variable or value parameter of type `@map_param_SE.IntList' was expected instead of `integer'//
+  unmap(mtc:pt, system:pt) param ("2"); //^In unmap statement// //^In parameter// //Reference to a variable or value parameter was expected for an `inout' value parameter//
+  
+  map(mtc:pt, system:pt) param (octetstring: ?); //^In map statement// //Too few parameters\: 2 was expected instead of 1// //^In parameter// //A specific value without matching symbols was expected for a value parameter//
+  unmap(mtc:pt, system:pt) param (-); //^In unmap statement// //^In parameter// //Not used symbol \(`-'\) cannot be used for parameter that does not have default value//
+}
+
+function func_w_system() system CT4 {
+  var IntList list;
+  var integer i := 6;
+  map(mtc:pt, system:pt) param ('ABCD'O, list);
+  unmap(mtc:pt, system:pt) param (i);
+}
+
+function func_w_no_system() runs on CT4 mtc CT4 { //^In function definition//
+  var IntList list;
+  var integer i := 6;
+  map(mtc:pt, system:pt) param ('ABCD'O, list); //^In map statement// //Cannot determine system component in `map' operation with `param' clause//
+  unmap(mtc:pt, system:pt) param (i); //^In unmap statement// //Cannot determine system component in `unmap' operation with `param' clause//
+}
+
+}
diff --git a/function_test/Semantic_Analyser/map_param/t b/function_test/Semantic_Analyser/map_param/t
new file mode 100755
index 0000000000000000000000000000000000000000..3a4b58ec16cf2f1390a36c7a92f8823e3b94b425
--- /dev/null
+++ b/function_test/Semantic_Analyser/map_param/t
@@ -0,0 +1,9 @@
+#!/usr/bin/perl
+# note this is called through "perl -w"
+use strict;
+
+my $self = $0;
+$self =~ s!/t!!;
+
+exec('make check --no-print-directory -s -C ' . $self);
+
diff --git a/mctr2/mctr/MainController.cc b/mctr2/mctr/MainController.cc
index eb011582107520d5db8cf7f3ad31d4ff87fe796f..dc8acb618e6167d0b88b260662c1d01d1eff38ba 100644
--- a/mctr2/mctr/MainController.cc
+++ b/mctr2/mctr/MainController.cc
@@ -3410,13 +3410,18 @@ void MainController::send_disconnect_ack(component_struct *tc)
 }
 
 void MainController::send_map(component_struct *tc,
-  const char *local_port, const char *system_port, boolean translation)
+  const char *local_port, const char *system_port, unsigned int nof_params,
+  char** params, boolean translation)
 {
   Text_Buf text_buf;
   text_buf.push_int(MSG_MAP);
   text_buf.push_int(translation == FALSE ? 0 : 1);
   text_buf.push_string(local_port);
   text_buf.push_string(system_port);
+  text_buf.push_int(nof_params);
+  for (unsigned int i = 0; i < nof_params; ++i) {
+    text_buf.push_string(params[i]);
+  }
   send_message(tc->tc_fd, text_buf);
 }
 
@@ -3428,13 +3433,18 @@ void MainController::send_map_ack(component_struct *tc)
 }
 
 void MainController::send_unmap(component_struct *tc,
-  const char *local_port, const char *system_port, boolean translation)
+  const char *local_port, const char *system_port, unsigned int nof_params,
+  char** params, boolean translation)
 {
   Text_Buf text_buf;
   text_buf.push_int(MSG_UNMAP);
   text_buf.push_int(translation == FALSE ? 0 : 1);
   text_buf.push_string(local_port);
   text_buf.push_string(system_port);
+  text_buf.push_int(nof_params);
+  for (unsigned int i = 0; i < nof_params; ++i) {
+    text_buf.push_string(params[i]);
+  }
   send_message(tc->tc_fd, text_buf);
 }
 
@@ -5371,11 +5381,18 @@ void MainController::process_map_req(component_struct *tc)
     delete [] system_port;
     return;
   }
+  
+  unsigned int nof_params = text_buf.pull_int().get_val();
+  char** params = new char*[nof_params];
+  for (unsigned int i = 0; i < nof_params; ++i) {
+    params[i] = text_buf.pull_string();
+  }
 
   port_connection *conn = find_connection(src_compref, src_port,
     SYSTEM_COMPREF, system_port);
   if (conn == NULL) {
-    send_map(components[src_compref], src_port, system_port, translate == 0 ? FALSE : TRUE);
+    send_map(components[src_compref], src_port, system_port, nof_params,
+      params, translate == 0 ? FALSE : TRUE);
     conn = new port_connection;
     conn->head.comp_ref = src_compref;
     conn->head.port_name = src_port;
@@ -5408,6 +5425,11 @@ void MainController::process_map_req(component_struct *tc)
     delete [] src_port;
     delete [] system_port;
   }
+  
+  for (unsigned int i = 0; i < nof_params; ++i) {
+    delete [] params[i];
+  }
+  delete [] params;
 }
 
 void MainController::process_mapped(component_struct *tc)
@@ -5470,6 +5492,13 @@ void MainController::process_unmap_req(component_struct *tc)
     delete [] system_port;
     return;
   }
+  
+  unsigned int nof_params = text_buf.pull_int().get_val();
+  char** params = new char*[nof_params];
+  for (unsigned int i = 0; i < nof_params; ++i) {
+    params[i] = text_buf.pull_string();
+  }
+  
   port_connection *conn = find_connection(src_compref, src_port,
       SYSTEM_COMPREF, system_port);
   if (conn == NULL) {
@@ -5477,7 +5506,8 @@ void MainController::process_unmap_req(component_struct *tc)
   } else {
     switch (conn->conn_state) {
     case CONN_MAPPED:
-      send_unmap(components[src_compref], src_port, system_port, translation);
+      send_unmap(components[src_compref], src_port, system_port, nof_params,
+        params, translation);
       conn->conn_state = CONN_UNMAPPING;
     case CONN_UNMAPPING:
       add_requestor(&conn->requestors, tc);
@@ -5497,6 +5527,11 @@ void MainController::process_unmap_req(component_struct *tc)
 
   delete [] src_port;
   delete [] system_port;
+  
+  for (unsigned int i = 0; i < nof_params; ++i) {
+    delete [] params[i];
+  }
+  delete [] params;
 }
 
 void MainController::process_unmapped(component_struct *tc)
diff --git a/mctr2/mctr/MainController.h b/mctr2/mctr/MainController.h
index 17dc8b4bf70b0301f58fd3728260ea1c411b61b5..6cb22d4293c83a308338640b898021283f579d03 100644
--- a/mctr2/mctr/MainController.h
+++ b/mctr2/mctr/MainController.h
@@ -526,10 +526,12 @@ private:
     const char *local_port, component remote_comp, const char *remote_port);
   static void send_disconnect_ack(component_struct *tc);
   static void send_map(component_struct *tc,
-    const char *local_port, const char *system_port, boolean translate);
+    const char *local_port, const char *system_port, unsigned int nof_params,
+    char** params, boolean translate);
   static void send_map_ack(component_struct *tc);
   static void send_unmap(component_struct *tc,
-    const char *local_port, const char *system_port, boolean translate);
+    const char *local_port, const char *system_port, unsigned int nof_params,
+    char** params, boolean translate);
   static void send_unmap_ack(component_struct *tc);
   static void send_debug_command(int fd, int commandID, const char* arguments);
   static void send_debug_setup(host_struct *hc);
diff --git a/regression_test/map_param/Makefile b/regression_test/map_param/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9c9f97c991007c587d1cb8b50ccef9914dc0da5c
--- /dev/null
+++ b/regression_test/map_param/Makefile
@@ -0,0 +1,20 @@
+##############################################################################
+# Copyright (c) 2000-2019 Ericsson Telecom AB
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+#
+# Contributors:
+#   Baranyi, Botond
+#
+##############################################################################
+TOPDIR := ..
+include $(TOPDIR)/Makefile.regression
+
+DIR_SINGLE := single_mode
+DIR_PARALLEL := parallel_mode
+
+all clean distclean run dep:
+	$(MAKE) -C $(DIR_SINGLE) $@
+	$(MAKE) -C $(DIR_PARALLEL) $@
diff --git a/regression_test/map_param/PT.cc b/regression_test/map_param/PT.cc
new file mode 100644
index 0000000000000000000000000000000000000000..de3944bd01d75ca9752a53aed4a9c0b50ce9dede
--- /dev/null
+++ b/regression_test/map_param/PT.cc
@@ -0,0 +1,136 @@
+// This Test Port skeleton source file was generated by the
+// TTCN-3 Compiler of the TTCN-3 Test Executor version CRL 113 200/6 R5B
+// for ebotbar (ebotbar@ebotbarVB) on Mon Apr 29 13:25:58 2019
+
+// Copyright (c) 2000-2019 Ericsson Telecom AB
+
+// You may modify this file. Complete the body of empty functions and
+// add your member functions here.
+
+#include "PT.hh"
+
+namespace common {
+
+PT::PT(const char *par_port_name)
+	: PT_BASE(par_port_name)
+{
+
+}
+
+PT::~PT()
+{
+
+}
+
+void PT::set_parameter(const char * /*parameter_name*/,
+	const char * /*parameter_value*/)
+{
+
+}
+
+/*void PT::Handle_Fd_Event(int fd, boolean is_readable,
+	boolean is_writable, boolean is_error) {}*/
+
+void PT::Handle_Fd_Event_Error(int /*fd*/)
+{
+
+}
+
+void PT::Handle_Fd_Event_Writable(int /*fd*/)
+{
+
+}
+
+void PT::Handle_Fd_Event_Readable(int /*fd*/)
+{
+
+}
+
+/*void PT::Handle_Timeout(double time_since_last_call) {}*/
+
+void PT::user_map(const char * /*system_port*/, Map_Params& params)
+{
+  if (params.get_nof_params() != 0) {
+    CHARSTRING p1_str = params.get_param(0);
+    if (p1_str.lengthof() > 0) {
+      // OK
+      OCTETSTRING p1;
+      string_to_ttcn(params.get_param(0), p1);
+      // check the value
+      if (p1 != P1__INITIAL) {
+        char* reason = mprintf("Initial value of parameter p1 is incorrect: %s", (const char*) p1_str);
+        TTCN_Runtime::setverdict(FAIL, reason);
+        Free(reason);
+      }
+    }
+    else {
+      // not OK
+      TTCN_Runtime::setverdict(FAIL, "Parameter p1 is unset");
+    }
+    
+    CHARSTRING p2_str = params.get_param(1);
+    if (p2_str.lengthof() == 0) {
+      // OK
+      // now set the output value
+      params.set_param(1, ttcn_to_string(P2__FINAL));
+    }
+    else {
+      // not OK
+      char* reason = mprintf("Parameter p2 is set: %s", (const char*) p2_str);
+      TTCN_Runtime::setverdict(FAIL, reason);
+      Free(reason);
+    }
+    CT_component_map__param = TRUE;
+  }
+  else {
+    CT_component_map__empty = TRUE;
+  }
+}
+
+void PT::user_unmap(const char * /*system_port*/, Map_Params& params)
+{
+  if (params.get_nof_params() != 0) {
+    CHARSTRING p_str = params.get_param(0);
+    if (p_str.lengthof() > 0) {
+      // OK
+      INTEGER p;
+      string_to_ttcn(params.get_param(0), p);
+      // check the input value
+      if (p != P__INITIAL) {
+        char* reason = mprintf("Initial value of parameter p is incorrect: %s", (const char*) p_str);
+        TTCN_Runtime::setverdict(FAIL, reason);
+        Free(reason);
+      }
+      else {
+        // set the output value
+        params.set_param(0, ttcn_to_string(P__FINAL));
+      }
+    }
+    else {
+      // not OK
+      TTCN_Runtime::setverdict(FAIL, "Parameter p is unset");
+    }
+    CT_component_unmap__param = TRUE;
+  }
+  else {
+    CT_component_unmap__empty = TRUE;
+  }
+}
+
+void PT::user_start()
+{
+
+}
+
+void PT::user_stop()
+{
+
+}
+
+void PT::outgoing_send(const CHARSTRING& /*send_par*/)
+{
+
+}
+
+} /* end of namespace */
+
diff --git a/regression_test/map_param/PT.hh b/regression_test/map_param/PT.hh
new file mode 100644
index 0000000000000000000000000000000000000000..1798dbc0f5ca24c99acaf91334a44916cbb4a60d
--- /dev/null
+++ b/regression_test/map_param/PT.hh
@@ -0,0 +1,44 @@
+// This Test Port skeleton header file was generated by the
+// TTCN-3 Compiler of the TTCN-3 Test Executor version CRL 113 200/6 R5B
+// for ebotbar (ebotbar@ebotbarVB) on Mon Apr 29 13:25:58 2019
+
+// Copyright (c) 2000-2019 Ericsson Telecom AB
+
+// You may modify this file. Add your attributes and prototypes of your
+// member functions here.
+
+#ifndef PT_HH
+#define PT_HH
+
+#include "common.hh"
+
+namespace common {
+
+class PT : public PT_BASE {
+public:
+	PT(const char *par_port_name = NULL);
+	~PT();
+
+	void set_parameter(const char *parameter_name,
+		const char *parameter_value);
+
+private:
+	/* void Handle_Fd_Event(int fd, boolean is_readable,
+		boolean is_writable, boolean is_error); */
+	void Handle_Fd_Event_Error(int fd);
+	void Handle_Fd_Event_Writable(int fd);
+	void Handle_Fd_Event_Readable(int fd);
+	/* void Handle_Timeout(double time_since_last_call); */
+protected:
+	void user_map(const char *system_port, Map_Params& params);
+	void user_unmap(const char *system_port, Map_Params& params);
+
+	void user_start();
+	void user_stop();
+
+	void outgoing_send(const CHARSTRING& send_par);
+};
+
+} /* end of namespace */
+
+#endif
diff --git a/regression_test/map_param/common.ttcn b/regression_test/map_param/common.ttcn
new file mode 100644
index 0000000000000000000000000000000000000000..b4810185a4917f22069c6c8aa8671c80e340576d
--- /dev/null
+++ b/regression_test/map_param/common.ttcn
@@ -0,0 +1,53 @@
+/******************************************************************************
+ * Copyright (c) 2000-2019 Ericsson Telecom AB
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+ *
+ * Contributors:
+ *   Baranyi, Botond
+ *
+ ******************************************************************************/
+module common {
+
+type record of integer IntList;
+
+type port PT message {
+  in integer
+  out charstring
+  map param (in octetstring p1 := P1_INITIAL, out IntList p2)
+  unmap param (inout integer p)
+}
+
+type component CT {
+  port PT pt;
+  var boolean map_param := false;
+  var boolean unmap_param := false;
+  var boolean map_empty := false;
+  var boolean unmap_empty := false;
+}
+
+const octetstring P1_INITIAL := '1123'O;
+
+const IntList P2_INITIAL := { 1, 2, 3 };
+const IntList P2_FINAL := { 1, 2, 4, 8 };
+
+const integer P_INITIAL := -2;
+const integer P_FINAL := 2;
+
+function f_check_calls() runs on CT {
+  // check whether all 4 user functions have been called
+  if (map_param and unmap_param and map_empty and unmap_empty) {
+    setverdict(pass);
+  }
+  else {
+    setverdict(fail, "Not all user functions have been called.");
+    log("user_map with parameters: ", map_param);
+    log("user_unmap with parameters: ", unmap_param);
+    log("user_map without parameters: ", map_empty);
+    log("user_unmap without parameters: ", unmap_empty);
+  }
+}
+
+}
diff --git a/regression_test/map_param/parallel_mode/.gitignore b/regression_test/map_param/parallel_mode/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..f9a644002a83b3bc48d7a6bb30cde2b894e43815
--- /dev/null
+++ b/regression_test/map_param/parallel_mode/.gitignore
@@ -0,0 +1,12 @@
+map_param_parallel
+map_param_parallel.exe
+common*.cc
+common*.hh
+parallel_test*.cc
+parallel_test*.hh
+*.o
+*.d
+PT.cc
+PT.hh
+common.ttcn
+map_param_parallel*.log
diff --git a/regression_test/map_param/parallel_mode/Makefile b/regression_test/map_param/parallel_mode/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..3799c55ee8309372ce65ffd8158a0b7ac5d864f4
--- /dev/null
+++ b/regression_test/map_param/parallel_mode/Makefile
@@ -0,0 +1,65 @@
+##############################################################################
+# Copyright (c) 2000-2019 Ericsson Telecom AB
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+#
+# Contributors:
+#   Baranyi, Botond
+#
+##############################################################################
+TOPDIR := ../..
+include $(TOPDIR)/Makefile.regression
+
+.PHONY: all clean dep run
+
+TTCN3_LIB = ttcn3$(RT2_SUFFIX)-parallel$(DYNAMIC_SUFFIX)
+
+COMMON_TTCN3_MODULES = common.ttcn
+TTCN3_MODULES = $(COMMON_TTCN3_MODULES) parallel_test.ttcn
+
+GENERATED_SOURCES = $(TTCN3_MODULES:.ttcn=.cc)
+GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh)
+ifdef CODE_SPLIT
+GENERATED_SOURCES := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), .cc _seq.cc _set.cc  _seqof.cc _setof.cc _union.cc))
+else ifdef SPLIT_TO_SLICES
+POSTFIXES := $(foreach file, $(SPLIT_TO_SLICES), $(addsuffix $(file), _part_))
+POSTFIXES := $(foreach file, $(POSTFIXES), $(addprefix $(file), .cc))
+GENERATED_SOURCES2 := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), $(POSTFIXES)))
+GENERATED_SOURCES += $(GENERATED_SOURCES2)
+endif
+
+PORT_SOURCES = PT.cc
+PORT_HEADERS = $(PORT_SOURCES:.cc=.hh)
+
+
+OBJECTS = $(GENERATED_SOURCES:.cc=.o) $(PORT_SOURCES:.cc=.o) 
+
+TARGET = map_param_parallel$(EXESUFFIX)
+
+all: $(TARGET)
+
+$(COMMON_TTCN3_MODULES) $(PORT_SOURCES) $(PORT_HEADERS):
+	ln -s ../$@
+
+$(TARGET): $(OBJECTS)
+	$(CXX) $(LDFLAGS) -o $@ $(OBJECTS) -L$(TTCN3_DIR)/lib -l$(TTCN3_LIB) -L$(OPENSSL_DIR)/lib -lcrypto $($(PLATFORM)_LIBS)
+
+.cc.o:
+	$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
+
+$(GENERATED_SOURCES) $(GENERATED_HEADERS): $(TTCN3_MODULES) $(PORT_HEADERS)
+	$(TTCN3_COMPILER) $(TTCN3_MODULES)
+
+clean distclean:
+	-rm -f $(TARGET) $(OBJECTS) $(GENERATED_HEADERS) \
+	$(GENERATED_SOURCES) *.log Makefile.bak
+
+dep: $(GENERATED_SOURCES)
+	makedepend $(CPPFLAGS) $(GENERATED_SOURCES)
+
+run: $(TARGET)
+	$(TTCN3_DIR)/bin/ttcn3_start $(TARGET) parallel.cfg
+
+
diff --git a/regression_test/map_param/parallel_mode/parallel.cfg b/regression_test/map_param/parallel_mode/parallel.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..03783dd7c50fd8e58ffc940572758b3c4834d810
--- /dev/null
+++ b/regression_test/map_param/parallel_mode/parallel.cfg
@@ -0,0 +1,21 @@
+###############################################################################
+# Copyright (c) 2000-2019 Ericsson Telecom AB
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+#
+# Contributors:
+#   Baranyi, Botond
+#
+###############################################################################
+[MODULE_PARAMETERS]
+[LOGGING]
+Logfile := "map_param_parallel_%r.log"
+FileMask := LOG_ALL
+ConsoleMask := TTCN_WARNING | TTCN_ERROR | TTCN_TESTCASE | TTCN_STATISTICS
+
+[EXECUTE]
+parallel_test.tc_parallel_mtc
+parallel_test.tc_parallel_ptc
+
diff --git a/regression_test/map_param/parallel_mode/parallel_test.ttcn b/regression_test/map_param/parallel_mode/parallel_test.ttcn
new file mode 100644
index 0000000000000000000000000000000000000000..418cab6ca5752a9841074f359e2c1bf709eb3d1f
--- /dev/null
+++ b/regression_test/map_param/parallel_mode/parallel_test.ttcn
@@ -0,0 +1,61 @@
+/******************************************************************************
+ * Copyright (c) 2000-2019 Ericsson Telecom AB
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+ *
+ * Contributors:
+ *   Baranyi, Botond
+ *
+ ******************************************************************************/
+
+// this module contains tests for 'map'/'unmap' parameters in parallel mode
+// ('out' and 'inout' do not retain the new values set in the port implementation,
+// because the 'map' and 'unmap' operations are asynchronous, i.e. they don't
+// wait for a response before the next operation is executed)
+module parallel_test {
+
+import from common all;
+
+testcase tc_parallel_mtc() runs on CT {
+  var IntList v_p2 := P2_INITIAL;
+  map(mtc:pt, system:pt) param (-, v_p2);
+  if (v_p2 != P2_INITIAL) {
+    setverdict(fail, "Final value of parameter p2 is incorrect: ", v_p2);
+  }
+  
+  var integer v_p := P_INITIAL;
+  unmap(mtc:pt, system:pt) param(v_p);
+  if (v_p != P_INITIAL) {
+    setverdict(fail, "Final value of parameter p is incorrect: ", v_p);
+  }
+  
+  map(mtc:pt, system:pt);
+  unmap(mtc:pt, system:pt);
+  
+  f_check_calls();
+}
+
+testcase tc_parallel_ptc() runs on CT {
+  var CT ptc := CT.create;
+  
+  var IntList v_p2 := P2_INITIAL;
+  map(ptc:pt, system:pt) param (-, v_p2);
+  if (v_p2 != P2_INITIAL) {
+    setverdict(fail, "Final value of parameter p2 is incorrect: ", v_p2);
+  }
+  
+  var integer v_p := P_INITIAL;
+  unmap(ptc:pt, system:pt) param(v_p);
+  if (v_p != P_INITIAL) {
+    setverdict(fail, "Final value of parameter p is incorrect: ", v_p);
+  }
+  map(ptc:pt, system:pt);
+  unmap(ptc:pt, system:pt);
+  
+  ptc.start(f_check_calls());
+  ptc.done;
+}
+
+}
diff --git a/regression_test/map_param/single_mode/.gitignore b/regression_test/map_param/single_mode/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..cbe76a5861b26d82b155be905a75badbc94fb568
--- /dev/null
+++ b/regression_test/map_param/single_mode/.gitignore
@@ -0,0 +1,12 @@
+map_param_single
+map_param_single.exe
+common*.cc
+common*.hh
+single_test*.cc
+single_test*.hh
+*.o
+*.d
+PT.cc
+PT.hh
+common.ttcn
+map_param_single.log
diff --git a/regression_test/map_param/single_mode/Makefile b/regression_test/map_param/single_mode/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..2986a4d208b5e375ecc950ebfee90e47377dd85d
--- /dev/null
+++ b/regression_test/map_param/single_mode/Makefile
@@ -0,0 +1,65 @@
+##############################################################################
+# Copyright (c) 2000-2019 Ericsson Telecom AB
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+#
+# Contributors:
+#   Baranyi, Botond
+#
+##############################################################################
+TOPDIR := ../..
+include $(TOPDIR)/Makefile.regression
+
+.PHONY: all clean dep run
+
+TTCN3_LIB = ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX)
+
+COMMON_TTCN3_MODULES = common.ttcn
+TTCN3_MODULES = $(COMMON_TTCN3_MODULES) single_test.ttcn
+
+GENERATED_SOURCES = $(TTCN3_MODULES:.ttcn=.cc)
+GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh)
+ifdef CODE_SPLIT
+GENERATED_SOURCES := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), .cc _seq.cc _set.cc  _seqof.cc _setof.cc _union.cc))
+else ifdef SPLIT_TO_SLICES
+POSTFIXES := $(foreach file, $(SPLIT_TO_SLICES), $(addsuffix $(file), _part_))
+POSTFIXES := $(foreach file, $(POSTFIXES), $(addprefix $(file), .cc))
+GENERATED_SOURCES2 := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), $(POSTFIXES)))
+GENERATED_SOURCES += $(GENERATED_SOURCES2)
+endif
+
+PORT_SOURCES = PT.cc
+PORT_HEADERS = $(PORT_SOURCES:.cc=.hh)
+
+
+OBJECTS = $(GENERATED_SOURCES:.cc=.o) $(PORT_SOURCES:.cc=.o) 
+
+TARGET = map_param_single$(EXESUFFIX)
+
+all: $(TARGET)
+
+$(COMMON_TTCN3_MODULES) $(PORT_SOURCES) $(PORT_HEADERS):
+	ln -s ../$@
+
+$(TARGET): $(OBJECTS)
+	$(CXX) $(LDFLAGS) -o $@ $(OBJECTS) -L$(TTCN3_DIR)/lib -l$(TTCN3_LIB) -L$(OPENSSL_DIR)/lib -lcrypto $($(PLATFORM)_LIBS)
+
+.cc.o:
+	$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
+
+$(GENERATED_SOURCES) $(GENERATED_HEADERS): $(TTCN3_MODULES) $(PORT_HEADERS)
+	$(TTCN3_COMPILER) $(TTCN3_MODULES)
+
+clean distclean:
+	-rm -f $(TARGET) $(OBJECTS) $(GENERATED_HEADERS) \
+	$(GENERATED_SOURCES) *.log Makefile.bak
+
+dep: $(GENERATED_SOURCES)
+	makedepend $(CPPFLAGS) $(GENERATED_SOURCES)
+
+run: $(TARGET) single.cfg
+	./$^
+
+
diff --git a/regression_test/map_param/single_mode/single.cfg b/regression_test/map_param/single_mode/single.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..7856f410ff5f04a23d2a35e68d3e81f0ba9b735a
--- /dev/null
+++ b/regression_test/map_param/single_mode/single.cfg
@@ -0,0 +1,20 @@
+###############################################################################
+# Copyright (c) 2000-2019 Ericsson Telecom AB
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+#
+# Contributors:
+#   Baranyi, Botond
+#
+###############################################################################
+[MODULE_PARAMETERS]
+[LOGGING]
+Logfile := "map_param_single.log"
+FileMask := LOG_ALL
+ConsoleMask := TTCN_WARNING | TTCN_ERROR | TTCN_TESTCASE | TTCN_STATISTICS
+
+[EXECUTE]
+single_test.tc_single
+
diff --git a/regression_test/map_param/single_mode/single_test.ttcn b/regression_test/map_param/single_mode/single_test.ttcn
new file mode 100644
index 0000000000000000000000000000000000000000..b2d050454139f60ad082340a19db4e72056b2faa
--- /dev/null
+++ b/regression_test/map_param/single_mode/single_test.ttcn
@@ -0,0 +1,39 @@
+/******************************************************************************
+ * Copyright (c) 2000-2019 Ericsson Telecom AB
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+ *
+ * Contributors:
+ *   Baranyi, Botond
+ *
+ ******************************************************************************/
+
+// this module contains tests for 'map'/'unmap' parameters in single mode
+// ('out' and 'inout' parameters function normally, i.e. they retain the new
+// values set in the port implementation)
+module single_test {
+
+import from common all;
+
+testcase tc_single() runs on CT {
+  var IntList v_p2 := P2_INITIAL;
+  map(mtc:pt, system:pt) param (-, v_p2);
+  if (v_p2 != P2_FINAL) {
+    setverdict(fail, "Final value of parameter p2 is incorrect: ", v_p2);
+  }
+  
+  var integer v_p := P_INITIAL;
+  unmap(mtc:pt, system:pt) param(v_p);
+  if (v_p != P_FINAL) {
+    setverdict(fail, "Final value of parameter p is incorrect: ", v_p);
+  }
+  
+  map(mtc:pt, system:pt);
+  unmap(mtc:pt, system:pt);
+  
+  f_check_calls();
+}
+
+}