diff --git a/compiler2/Identifier.cc b/compiler2/Identifier.cc
index c09515a6532c3d1f731fa6d55bed2e8539470ff4..07a351772ac7249e598b72cc843c9e8a41097655 100644
--- a/compiler2/Identifier.cc
+++ b/compiler2/Identifier.cc
@@ -831,6 +831,7 @@ namespace Common {
     {"send__", "send", "send_"},
     {"sender__", "sender", "sender_"},
     {"set__", "set", "set_"},
+    {"setstate__", "setstate", "setstate_"},
     {"setverdict__", "setverdict", "setverdict_"},
     {"signature__", "signature", "signature_"},
     {"start__", "start", "start_"},
diff --git a/compiler2/ttcn3/Statement.cc b/compiler2/ttcn3/Statement.cc
index a496eb39f4dc72a0c0d07ea31ef8549ba7407bf1..fcabbcc30851f86a9cc898a56db04ae2e42fd3da 100644
--- a/compiler2/ttcn3/Statement.cc
+++ b/compiler2/ttcn3/Statement.cc
@@ -718,6 +718,10 @@ namespace Ttcn {
       delete update_op.w_attrib_path;
       delete update_op.err_attrib;
       break;
+    case S_SETSTATE:
+      delete setstate_op.val;
+      delete setstate_op.ti;
+      break;
     default:
       FATAL_ERROR("Statement::clean_up()");
     } // switch statementtype
@@ -1032,6 +1036,10 @@ namespace Ttcn {
     case S_DEACTIVATE:
       deactivate=p_val;
       break;
+    case S_SETSTATE:
+      setstate_op.val = p_val;
+      setstate_op.ti = NULL;
+      break;
     default:
       FATAL_ERROR("Statement::Statement()");
     } // switch statementtype
@@ -1465,6 +1473,22 @@ namespace Ttcn {
       FATAL_ERROR("Statement::Statement()");
     }
   }
+  
+    Statement::Statement(statementtype_t p_st, Value* p_val, TemplateInstance* p_ti)
+  : statementtype(p_st), my_sb(0)
+  {
+    switch (statementtype) {
+    case S_SETSTATE:
+      if (p_val == NULL || p_ti == NULL) {
+        FATAL_ERROR("Statement::Statement()");
+      }
+      setstate_op.val = p_val;
+      setstate_op.ti = p_ti;
+      break;
+    default:
+      FATAL_ERROR("Statement::Statement()");
+    }
+  }
 
   Statement::~Statement()
   {
@@ -1595,6 +1619,7 @@ namespace Ttcn {
     case S_START_PROFILER: return "@profiler.start";
     case S_STOP_PROFILER: return "@profiler.stop";
     case S_UPDATE: return "@update";
+    case S_SETSTATE: return "setstate";
     default:
       FATAL_ERROR("Statement::get_stmt_name()");
       return "";
@@ -1924,6 +1949,12 @@ namespace Ttcn {
         update_op.w_attrib_path->set_my_scope(p_scope);
       }
       break;
+    case S_SETSTATE:
+      setstate_op.val->set_my_scope(p_scope);
+      if (setstate_op.ti != NULL) {
+        setstate_op.ti->set_my_scope(p_scope);
+      }
+      break;
     default:
       FATAL_ERROR("Statement::set_my_scope()");
     } // switch statementtype
@@ -2208,6 +2239,12 @@ namespace Ttcn {
         update_op.w_attrib_path->set_fullname(p_fullname + ".<attribpath>");
       }
       break;
+    case S_SETSTATE:
+      setstate_op.val->set_fullname(p_fullname + ".val");
+      if (setstate_op.ti != NULL) {
+        setstate_op.ti->set_fullname(p_fullname + ".ti");
+      }
+      break;
     default:
       FATAL_ERROR("Statement::set_fullname()");
     } // switch statementtype
@@ -2498,6 +2535,7 @@ namespace Ttcn {
     case S_STOP_PROFILER:
     case S_INT2ENUM:
     case S_UPDATE:
+    case S_SETSTATE:
       return false;
     case S_ALT:
     case S_INTERLEAVE:
@@ -2755,6 +2793,9 @@ namespace Ttcn {
     case S_UPDATE:
       chk_update();
       break;
+    case S_SETSTATE:
+      chk_setstate();
+      break;
     default:
       FATAL_ERROR("Statement::chk()");
     } // switch statementtype
@@ -5628,6 +5669,42 @@ error:
         "this context");
     }
   }
+  
+  void Statement::chk_setstate() {
+    Error_Context cntxt(this, "In setstate statement");
+    {
+      Error_Context cntxt2(this, "In first parameter");
+      setstate_op.val->chk_expr_int(Type::EXPECTED_DYNAMIC_VALUE);
+      if (!setstate_op.val->is_unfoldable()) {
+        bool error = false;
+        if (setstate_op.val->get_val_Int()->is_native()) {
+          switch(setstate_op.val->get_val_Int()->get_val()) {
+            case 0:
+            case 1:
+            case 2:
+            case 3:
+              break;
+            default:
+              error = true;
+          }
+        } else {
+          error = true;
+        }
+        if (error) {
+          setstate_op.val->error("The value of the first parameter must be 0, 1, 2 or 3.");
+        }
+      }
+    }
+    if (setstate_op.ti != NULL) {
+      Error_Context cntxt2(this, "In second parameter");
+      Type* t = setstate_op.ti->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
+      if (t != NULL) {
+        setstate_op.ti->chk(t);
+      } else {
+        setstate_op.ti->error("Cannot determine the type of the parameter.");
+      }
+    }
+  }
 
   void Statement::set_code_section(
     GovernedSimple::code_section_t p_code_section)
@@ -5886,6 +5963,12 @@ error:
     case S_UPDATE:
       update_op.ref->set_code_section(p_code_section);
       break;
+    case S_SETSTATE:
+      setstate_op.val->set_code_section(p_code_section);
+      if (setstate_op.ti != NULL) {
+        setstate_op.ti->set_code_section(p_code_section);
+      }
+      break;
     default:
       FATAL_ERROR("Statement::set_code_section()");
     } // switch statementtype
@@ -6082,6 +6165,9 @@ error:
     case S_UPDATE:
       str = generate_code_update(str, def_glob_vars, src_glob_vars);
       break;
+    case S_SETSTATE:
+      str = generate_code_setstate(str);
+      break;
     default:
       FATAL_ERROR("Statement::generate_code()");
     } // switch
@@ -7383,6 +7469,19 @@ error:
     }
     expr.expr = mputstr(expr.expr, ")");
     if (config_op.translate) {
+      bool warning = false;
+      if (!config_op.compref1->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)) {
+        warning = true;
+        config_op.compref2->warning(
+          "Cannot determine the type of the component in the first parameter."
+          "The port translation will not work.");
+      }
+      if (!config_op.compref2->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)) {
+        warning = true;
+        config_op.compref2->warning(
+          "Cannot determine the type of the component in the second parameter."
+          "The port translation will not work.");
+      }
       string funcname;
       if (strcmp(opname, "map") == 0) {
         funcname = "add_port";
@@ -7391,7 +7490,7 @@ error:
       } else {
         //TODO connect, disconnect
       }
-      if (!funcname.empty()) {
+      if (!funcname.empty() && warning == false) {
         expr.expr = mputstr(expr.expr, ";\n");
         config_op.portref1->generate_code_portref(&expr, my_sb);
         expr.expr = mputprintf(expr.expr, ".%s(&(", funcname.c_str());
@@ -7567,6 +7666,27 @@ error:
     }
     return str;
   }
+  
+  char* Statement::generate_code_setstate(char *str) {
+    expression_struct expr;
+    Code::init_expr(&expr);
+    expr.expr = mputstr(expr.expr, "TTCN_Runtime::set_port_state(");
+    if (!setstate_op.val->is_unfoldable()) {
+      expr.expr = mputprintf(expr.expr, "%i", (int)setstate_op.val->get_val_Int()->get_val());
+    } else {
+      setstate_op.val->generate_code_expr(&expr);
+    }
+    
+    expr.expr = mputstr(expr.expr, ", ");
+    if (setstate_op.ti != NULL) {
+      expr.expr = mputstr(expr.expr, "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_SETSTATE, TRUE), ");
+      setstate_op.ti->generate_code(&expr);
+      expr.expr = mputstr(expr.expr, ".log(), TTCN_Logger::end_event_log2str()), FALSE);\n");
+    } else {
+      expr.expr = mputstr(expr.expr, "\"\", FALSE);\n");
+    }
+    return Code::merge_free_expr(str, &expr);
+  }
 
   void Statement::generate_code_expr_receive(expression_struct *expr,
     const char *opname)
@@ -8055,7 +8175,7 @@ error:
     Code::free_expr(&ref_expr);
     expr->expr = mputprintf(expr->expr, "&%s", tmp_id_var.c_str());
   }
-
+  
   void Statement::set_parent_path(WithAttribPath* p_path) {
     switch (statementtype) {
         case S_DEF:
@@ -8146,6 +8266,7 @@ error:
         case S_STOP_PROFILER:
         case S_INT2ENUM:
         case S_UPDATE:
+        case S_SETSTATE:
           break;
         default:
           FATAL_ERROR("Statement::set_parent_path()");
diff --git a/compiler2/ttcn3/Statement.hh b/compiler2/ttcn3/Statement.hh
index dd67c6a5b76a9d4baa68db1bc59973ac4727ba8f..299ea2f27b5dbd6e5e93e288f6743b1f718c785c 100644
--- a/compiler2/ttcn3/Statement.hh
+++ b/compiler2/ttcn3/Statement.hh
@@ -267,7 +267,8 @@ namespace Ttcn {
       S_STRING2TTCN, // convert_op
       S_INT2ENUM, // convert_op
       /* update statement */
-      S_UPDATE // update_op
+      S_UPDATE, // update_op
+      S_SETSTATE // setstate_op
     };
 
     enum component_t {
@@ -482,6 +483,11 @@ namespace Ttcn {
         WithAttribPath* w_attrib_path;
         ErroneousAttributes* err_attrib;
       } update_op; /**< S_UPDATE */
+      
+      struct {
+        Value* val;
+        TemplateInstance* ti;
+      } setstate_op; /**< S_SETSTATE */
     };
 
     Statement(const Statement& p); ///< copy disabled
@@ -525,7 +531,7 @@ namespace Ttcn {
     Statement(statementtype_t p_st, AltGuards *p_ags);
     /** Constructor used by S_RETURN */
     Statement(statementtype_t p_st, Template *p_temp);
-    /** Constructor used by S_DEACTIVATE, S_STOP_COMP, S_KILL */
+    /** Constructor used by S_DEACTIVATE, S_STOP_COMP, S_KILL, S_SETSTATE */
     Statement(statementtype_t p_st, Value *p_val);
     /** Constructor used by S_KILLED */
     Statement(statementtype_t p_st, Value *p_val, bool p_any_from,
@@ -607,6 +613,8 @@ namespace Ttcn {
     Statement(statementtype_t p_st, Value* p_val, Reference* p_ref);
     /** Constructor used by S_UPDATE */
     Statement(statementtype_t p_st, Reference* p_ref, MultiWithAttrib* p_attrib);
+    /** Constructor used by S_SETSTATE */
+    Statement(statementtype_t p_st, Value* p_val, TemplateInstance* p_ti);
     virtual ~Statement();
     virtual Statement* clone() const;
     virtual void dump(unsigned int level) const;
@@ -787,6 +795,7 @@ namespace Ttcn {
     void chk_string2ttcn();
     void chk_int2enum();
     void chk_update();
+    void chk_setstate();
   public:
     /** Sets the code section selector of all embedded values and
      *  templates to \a p_code_section. */
@@ -858,6 +867,7 @@ namespace Ttcn {
     char *generate_code_testcaseinst(char *str);
     char *generate_code_execute_refd(char *str);
     char* generate_code_update(char *str, char*& def_glob_vars, char*& src_glob_vars);
+    char* generate_code_setstate(char *str);
     /** used for receive, check-receive, trigger */
     void generate_code_expr_receive(expression_struct *expr,
       const char *opname);
diff --git a/compiler2/ttcn3/Ttcnstuff.cc b/compiler2/ttcn3/Ttcnstuff.cc
index 6ee5e66d1a1420a0ae9d1e1ba99fa6ca01324221..2d6676ae41e0f57f798545a75d670fcf9cd2315c 100644
--- a/compiler2/ttcn3/Ttcnstuff.cc
+++ b/compiler2/ttcn3/Ttcnstuff.cc
@@ -570,6 +570,8 @@ namespace Ttcn {
         FATAL_ERROR("TypeMappingTarget::fill_type_mapping_target()");
       target->mapping.function.name =
         pool.add(u.func.function_ptr->get_genname_from_scope(p_scope));
+      target->mapping.function.dispname =
+        pool.add(u.func.function_ptr->get_fullname());
       switch (u.func.function_ptr->get_prototype()) {
       case Ttcn::Def_Function_Base::PROTOTYPE_CONVERT:
         target->mapping.function.prototype = PT_CONVERT;
@@ -2297,10 +2299,15 @@ namespace Ttcn {
 
               mapped_type->targets[ind].mapping_type = M_FUNCTION;
               mapped_type->targets[ind].mapping.function.prototype = PT_FAST;
-              mapped_type->targets[ind].mapping.function.name = mapping_target->get_function()->get_genname_from_scope(my_scope).c_str();
-
-              mapped_type->targets[ind].target_name = pool.add(mapping->get_source_type()->get_genname_value(my_scope));
-              mapped_type->targets[ind].target_dispname = pool.add(mapping->get_source_type()->get_typename());
+              mapped_type->targets[ind].mapping.function.name =
+                mapping_target->get_function()->get_genname_from_scope(my_scope).c_str();
+              mapped_type->targets[ind].mapping.function.dispname =
+                pool.add(mapping_target->get_function()->get_fullname());
+
+              mapped_type->targets[ind].target_name =
+                pool.add(mapping->get_source_type()->get_genname_value(my_scope));
+              mapped_type->targets[ind].target_dispname =
+                pool.add(mapping->get_source_type()->get_typename());
               
               if (in_msgs->has_type(mapping->get_source_type())) {
                 mapped_type->targets[ind].target_index =
diff --git a/compiler2/ttcn3/compiler.l b/compiler2/ttcn3/compiler.l
index a251832aaa22fdc4d15c314a05c3129b22724804..62a04100982f0e9742dcfd9f4ff2917a8e7d4741 100644
--- a/compiler2/ttcn3/compiler.l
+++ b/compiler2/ttcn3/compiler.l
@@ -489,6 +489,7 @@ self		RETURN(SelfKeyword);
 send		RETURN_DOT(SendOpKeyword);
 sender		RETURN(SenderKeyword);
 set		RETURN(SetKeyword);
+setstate	RETURN(SetstateKeyword);
 setverdict	RETURN(SetVerdictKeyword);
 signature	RETURN(SignatureKeyword);
 start		RETURN_DOT(StartKeyword);
diff --git a/compiler2/ttcn3/compiler.y b/compiler2/ttcn3/compiler.y
index 5b096d7457cc92b47158cb1608eb0fc6be6d731d..5d771c1fc2571aaa1a67789711b31460927943c9 100644
--- a/compiler2/ttcn3/compiler.y
+++ b/compiler2/ttcn3/compiler.y
@@ -748,6 +748,7 @@ static const string anyname("anytype");
 %token SenderKeyword
 %token SendOpKeyword
 %token SetKeyword
+%token SetstateKeyword
 %token SetVerdictKeyword
 %token SignatureKeyword
 %token StartKeyword
@@ -994,7 +995,7 @@ static const string anyname("anytype");
   StartTimerStatement StopExecutionStatement StopStatement StopTCStatement
   StopTimerStatement TimeoutStatement TimerStatements TriggerStatement
   UnmapStatement VerdictStatements WhileStatement SelectCaseConstruct
-  SelectUnionConstruct UpdateStatement
+  SelectUnionConstruct UpdateStatement SetstateStatement
   StopTestcaseStatement String2TtcnStatement ProfilerStatement int2enumStatement
 %type <statementblock> StatementBlock optElseClause FunctionStatementOrDefList
   ControlStatementOrDefList ModuleControlBody
@@ -1346,6 +1347,7 @@ SenderSpec
 SetDef
 SetLocalVerdict
 SetOfDef
+SetstateStatement
 Signature
 SignatureDef
 SignatureFormalPar
@@ -4264,6 +4266,7 @@ FunctionStatement: // 180
 | ProfilerStatement { $$ = $1; }
 | int2enumStatement { $$ = $1; }
 | UpdateStatement { $$ = $1; }
+| SetstateStatement { $$ = $1; }
 ;
 
 FunctionInstance: /* refpard */ // 181
@@ -8335,6 +8338,18 @@ UpdateStatement:
   }
 ;
 
+SetstateStatement:
+  PortKeyword '.' SetstateKeyword '(' SingleExpression ')'
+  {
+    $$ = new Statement(Statement::S_SETSTATE, $5);
+    $$->set_location(infile, @$);
+  }
+| PortKeyword '.' SetstateKeyword '(' SingleExpression ',' TemplateInstance ')'
+  {
+    $$ = new Statement(Statement::S_SETSTATE, $5, $7);
+    $$->set_location(infile, @$);
+  }
+
 ProfilerRunningOp:
   TitanSpecificProfilerKeyword DotRunningKeyword
   {
diff --git a/compiler2/ttcn3/port.c b/compiler2/ttcn3/port.c
index b762ae6b106f5a6a2ec47ebed095254983e72db2..c4a876e2956cd049151d1dd25cc85caf10ddfe81 100644
--- a/compiler2/ttcn3/port.c
+++ b/compiler2/ttcn3/port.c
@@ -81,6 +81,9 @@ static char *generate_send_mapping(char *src, const port_def *pdef,
         }
       }
       src = mputstr(src, ") {\n");
+      src = mputstr(src, "TTCN_Runtime::set_translation_mode(TRUE, this);\n");
+      // Set to unset
+      src = mputstr(src, "TTCN_Runtime::set_port_state(-1, \"by test environment.\", TRUE);\n");
     }
     if (mapped_type->nTargets > 1) src = mputstr(src, "{\n");
     switch (target->mapping_type) {
@@ -162,8 +165,10 @@ static char *generate_send_mapping(char *src, const port_def *pdef,
       default:
         FATAL_ERROR("generate_send_mapping(): invalid mapping type");
     }
-    if (!pdef->legacy) {
-      src = mputstr(src, "if (mapped_par.is_bound()) {\n"); // temporary solution instead of setstate
+    if (!pdef->legacy && pdef->port_type == USER) {
+      src = mputstr(src,
+        "TTCN_Runtime::set_translation_mode(FALSE, NULL);\n"
+        "if (port_state == TRANSLATED) {\n");
     }
     src = mputprintf(src, "if (TTCN_Logger::log_this_event("
       "TTCN_Logger::PORTEVENT_DUALSEND)) {\n"
@@ -196,8 +201,11 @@ static char *generate_send_mapping(char *src, const port_def *pdef,
       }
       report_error = TRUE;
     }
-    if (!pdef->legacy) {
-      src = mputstr(src, "}\n");
+    if (!pdef->legacy && pdef->port_type == USER) {
+      src = mputprintf(src,
+        "} else if (port_state == UNSET) {\n"
+        "TTCN_error(\"The state of the port %%s remained unset after the mapping function %s finished.\", port_name);\n"
+        "}\n", target->mapping.function.dispname);
     }
     if (mapped_type->nTargets > 1) src = mputstr(src, "}\n");
     if (!pdef->legacy && pdef->port_type == USER) {
@@ -246,6 +254,10 @@ static char *generate_incoming_mapping(char *src, const port_def *pdef,
       src = mputstr(src, "TTCN_Buffer ttcn_buffer(incoming_par);\n");
       /* has_buffer will be set to TRUE later */
     }
+    if (!pdef->legacy && pdef->port_type == USER) {
+      src = mputstr(src, "TTCN_Runtime::set_translation_mode(TRUE, this);\n");
+      src = mputstr(src, "port_state = UNSET;\n");
+    }
     if (mapped_type->nTargets > 1) src = mputstr(src, "{\n");
     switch (target->mapping_type) {
     case M_FUNCTION:
@@ -353,8 +365,8 @@ static char *generate_incoming_mapping(char *src, const port_def *pdef,
       default:
         FATAL_ERROR("generate_incoming_mapping(): invalid mapping type");
     }
-    src = mputprintf(src, "msg_tail_count++;\n"
-      "%s"
+    src = mputprintf(src, "%s"
+      "msg_tail_count++;\n"
       "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_DUALRECV)) "
       "{\n"
       "TTCN_Logger::log_dualport_map(1, \"%s\",\n"
@@ -366,7 +378,9 @@ static char *generate_incoming_mapping(char *src, const port_def *pdef,
       "new_item->item_selection = MESSAGE_%lu;\n"
       "new_item->message_%lu = mapped_par;\n"
       "new_item->sender_component = sender_component;\n",
-      !pdef->legacy ? "if (mapped_par->is_bound()) {\n" : "", //temporary solution instead of setstate
+      !pdef->legacy && pdef->port_type == USER ?
+        "TTCN_Runtime::set_translation_mode(FALSE, NULL);\n"
+        "if (port_state == TRANSLATED) {\n" : "",
       target->target_dispname,
       (unsigned long) target->target_index,
       (unsigned long) target->target_index);
@@ -388,7 +402,15 @@ static char *generate_incoming_mapping(char *src, const port_def *pdef,
       }
       else {
         src = mputstr(src, "return;\n"
-          "} else delete mapped_par;\n");
+          "}");
+        if (pdef->port_type == USER && !pdef->legacy) {
+          src = mputprintf(src,
+            " else if (port_state == UNSET) {\n"
+            "delete mapped_par;\n"
+            "TTCN_error(\"The state of the port %%s remained unset after the mapping function %s finished.\", port_name);\n"
+            "}\n", target->mapping.function.dispname);
+        }
+        src = mputstr(src, "else {\ndelete mapped_par;\n}\n");
       }
       report_error = TRUE;
     }
@@ -1625,16 +1647,17 @@ void defPortClass(const port_def* pdef, output_struct* output)
     src = mputstr(src, "}\n\n");
   }
   
-  // Port variables which can be the mapped ports for translation
   if (pdef->port_type == USER && !pdef->legacy) {
     def = mputstr(def, "private:\n");
+    // Port type variables which can be the mapped ports for translation
     for (i = 0; i < pdef->provider_msg_outlist.nElements; i++) {
       def = mputprintf(def, "%s* p_%i;\n", pdef->provider_msg_outlist.elements[i].name, (int)i);
     }
+    def = mputstr(def, "translation_port_state port_state;\n");
   }
   
-  // Port variables which can be the mapper ports for translation
-  if (pdef->port_type == PROVIDER && pdef->n_mapper_name > 0) {
+  // Port type variables in the provider types.
+  if (pdef->n_mapper_name > 0) {
     def = mputstr(def, "private:\n");
     for (i = 0; i < pdef->n_mapper_name; i++) {
       def = mputprintf(def, "%s* p_%i;\n", pdef->mapper_name[i], (int)i);
@@ -1664,11 +1687,11 @@ void defPortClass(const port_def* pdef, output_struct* output)
     for (i = 0; i < pdef->provider_msg_outlist.nElements; i++) {
       src = mputprintf(src, "p_%i = NULL;\n", (int)i);
     }
+    src = mputprintf(src, "port_state = UNSET;\n");
   }
-  if (pdef->port_type == PROVIDER && pdef->n_mapper_name > 0) {
-    for (i = 0; i < pdef->n_mapper_name; i++) {
-      src = mputprintf(src, "p_%i = NULL;\n", (int)i);
-    }
+  // Port type variables in the provider types.
+  for (i = 0; i < pdef->n_mapper_name; i++) {
+    src = mputprintf(src, "p_%i = NULL;\n", (int)i);
   }
   src = mputstr(src, "}\n\n");
 
@@ -1707,7 +1730,8 @@ void defPortClass(const port_def* pdef, output_struct* output)
     if (pdef->port_type != USER || (msg->nTargets == 1 &&
       msg->targets[0].mapping_type == M_SIMPLE) || (pdef->port_type == USER && !pdef->legacy)) {
       // If not in translation mode then send message as normally would.
-      if (pdef->port_type == USER && !pdef->legacy && msg->nTargets > 1) {
+      if (pdef->port_type == USER && !pdef->legacy &&
+         (msg->nTargets > 1 || (msg->nTargets > 0 && msg->targets[0].mapping_type != M_SIMPLE))) {
         src = mputstr(src, "if (!in_translation_mode()) {\n");
       }
       /* the same message type goes through the external interface */
@@ -1731,7 +1755,8 @@ void defPortClass(const port_def* pdef, output_struct* output)
         "send_par.encode_text(text_buf);\n"
         "send_data(text_buf, destination_component);\n"
         "}\n", msg->dispname);
-      if (pdef->port_type == USER && !pdef->legacy && msg->nTargets > 1) {
+      if (pdef->port_type == USER && !pdef->legacy &&
+         (msg->nTargets > 1 || (msg->nTargets > 0 && msg->targets[0].mapping_type != M_SIMPLE))) {
         // If in translation mode then generate the send mappings and send
         // according to them.
         src = mputstr(src, "} else {\n");
@@ -2054,7 +2079,7 @@ void defPortClass(const port_def* pdef, output_struct* output)
       src = mputprintf(src, "void %s::remove_port(%s*) {\n p_%i = NULL;\n}\n\n", class_name, pdef->provider_msg_outlist.elements[i].name, (int)i);
     }
     
-    // in_translation_mode returns true if one of the port variables are not null
+    // in_translation_mode returns true if one of the port type variables are not null
     def = mputstr(def, "boolean in_translation_mode() const;\n");
     src = mputprintf(src, "boolean %s::in_translation_mode() const {\nreturn ", class_name);
     for (i = 0; i < pdef->provider_msg_outlist.nElements; i++) {
@@ -2064,8 +2089,14 @@ void defPortClass(const port_def* pdef, output_struct* output)
     }
     src = mputstr(src, ";\n}\n\n");
     
+    def = mputstr(def, "void change_port_state(translation_port_state state);\n");
+    src = mputprintf(src,
+      "void %s::change_port_state(translation_port_state state) {\n"
+      "port_state = state;\n"
+      "}\n\n", class_name);
+    
     def = mputstr(def, "private:\n");
-    // Resets all port variables to NULL
+    // Resets all port type variables to NULL
     def = mputstr(def, "void reset_port_variables();\n");
     src = mputprintf(src, "void %s::reset_port_variables() {\n", class_name);
     for (i = 0; i < pdef->provider_msg_outlist.nElements; i++) {
@@ -2073,8 +2104,8 @@ void defPortClass(const port_def* pdef, output_struct* output)
     }
     src = mputstr(src, "}\n\n");
   }
-  
-  if (pdef->port_type == PROVIDER && pdef->n_mapper_name > 0) {
+  // Port type variables in the provider types.
+  if (pdef->n_mapper_name > 0) {
     def = mputstr(def, "public:\n");
     // add_port and remove_port is called after the map and unmap statements.
     for (i = 0; i < pdef->n_mapper_name; i++) {
@@ -2085,7 +2116,7 @@ void defPortClass(const port_def* pdef, output_struct* output)
       src = mputprintf(src, "void %s::remove_port(%s*) {\n p_%i = NULL;\n}\n\n", class_name, pdef->mapper_name[i], (int)i);
     }
     def = mputstr(def, "private:\n");
-    // Resets all port variables to NULL
+    // Resets all port type variables to NULL
     def = mputstr(def, "void reset_port_variables();\n");
     src = mputprintf(src, "void %s::reset_port_variables() {\n", class_name);
     for (i = 0; i < pdef->n_mapper_name; i++) {
@@ -2161,7 +2192,7 @@ void defPortClass(const port_def* pdef, output_struct* output)
           if (found) {
             src = mputprintf(src, "outgoing_send(send_par);\n");
           } else {
-            src = mputprintf(src, "TTCN_error(\"Cannot send this correctly %s\");\n", pdef->msg_out.elements[i].name); // todo
+            src = mputprintf(src, "TTCN_error(\"Cannot send message correctly with type %s\");\n", pdef->msg_out.elements[i].name);
           }
           src = mputstr(src, "}\n\n");
         }
@@ -3153,7 +3184,7 @@ void generateTestPortSkeleton(const port_def *pdef)
       "\tvoid user_start();\n"
       "\tvoid user_stop();\n\n",
       class_name, base_class_name, class_name,
-      pdef->port_type == REGULAR ? " = NULL" : "", class_name);
+      pdef->port_type == REGULAR || pdef->port_type == USER ? " = NULL" : "", class_name);
 
     if (pdef->port_type == PROVIDER && pdef->n_mapper_name > 0) {
       fprintf(fp, "public:\n");
diff --git a/compiler2/ttcn3/port.h b/compiler2/ttcn3/port.h
index 930c50b43c332ebee0a05774f8d48ff2d5df19ed..9258329904dec42440252edb8e6ecaadaabeacd1 100644
--- a/compiler2/ttcn3/port.h
+++ b/compiler2/ttcn3/port.h
@@ -48,6 +48,7 @@ typedef struct port_msg_type_mapping_target_tag {
   msg_mapping_type_t mapping_type;
   union {
     struct {
+      const char *dispname;
       const char *name;
       function_prototype_t prototype;
     } function;
diff --git a/core/LegacyLogger.cc b/core/LegacyLogger.cc
index e4e787ceb39aaff51b72cad5e38339532fd7ee2f..5abd4be365a29cd380fbbdfac5672b5a75e56dcc 100644
--- a/core/LegacyLogger.cc
+++ b/core/LegacyLogger.cc
@@ -12,6 +12,7 @@
  *   Kovacs, Ferenc
  *   Raduly, Csaba
  *   Szabados, Kristof
+ *   Szabo, Bence Janos
  *   Szalai, Gabor
  *   Pandi, Krisztian
  *
@@ -1064,6 +1065,15 @@ extract_common:
       : "was discarded on port %s."),
       (const char*) dualop.port__name());
     break; }
+  
+  case API::PortEvent_choice::ALT_setState: {
+    API::Setstate const& setstate = pec.setState();
+    ret_val = mputprintf(ret_val, "The state of the %s port was changed by a setstate operation to %s.",
+      (const char*)setstate.port__name(), (const char*)setstate.state());
+    if (setstate.info().lengthof() != 0) {
+      ret_val = mputprintf(ret_val, " Information: %s", (const char*)setstate.info());
+    }
+    break; }
 
   case API::PortEvent_choice::ALT_portMisc: {
     API::Port__Misc const& pmisc = pec.portMisc();
diff --git a/core/Logger.cc b/core/Logger.cc
index 01291dbc5c15b82f7105f2e908f089216efbc346..ae87ef3694d857fcbf6fe5369c2815081eea0cb2 100644
--- a/core/Logger.cc
+++ b/core/Logger.cc
@@ -15,6 +15,7 @@
  *   Kovacs, Ferenc
  *   Raduly, Csaba
  *   Szabados, Kristof
+ *   Szabo, Bence Janos
  *   Szabo, Janos Zoltan – initial implementation
  *   Zalanyi, Balazs Andor
  *   Pandi, Krisztian
@@ -202,6 +203,7 @@ const char* TTCN_Logger::severity_subcategory_names[NUMBER_OF_LOGSEVERITIES] = {
   "DUALRECV",
   "DUALSEND",
   "UNQUALIFIED",
+  "SETSTATE",
   // STATISTICS:
   "VERDICT",
   "UNQUALIFIED",
@@ -392,6 +394,7 @@ char *TTCN_Logger::mputstr_severity(char *str, const TTCN_Logger::Severity& seve
   case TTCN_Logger::PORTEVENT_DUALRECV:
   case TTCN_Logger::PORTEVENT_DUALSEND:
   case TTCN_Logger::PORTEVENT_UNQUALIFIED:
+  case TTCN_Logger::PORTEVENT_SETSTATE:
     return mputstr(str, "PORTEVENT");
   case TTCN_Logger::STATISTICS_VERDICT:
   case TTCN_Logger::STATISTICS_UNQUALIFIED:
@@ -1417,6 +1420,12 @@ void TTCN_Logger::log_dualport_discard(boolean incoming, const char *target_type
     unhandled);
 }
 
+void TTCN_Logger::log_setstate(const char* port_name, translation_port_state state,
+  const CHARSTRING& info)
+{
+  get_logger_plugin_manager()->log_setstate(port_name, state, info);
+}
+
 void TTCN_Logger::log_port_misc(int reason, const char *port_name,
   int remote_component, const char *remote_port,
   const char *ip_address, int tcp_port, int new_size)
diff --git a/core/Logger.hh b/core/Logger.hh
index 18c74dcfcc4c0252b89e701b09d396f87292673e..a50f1edb67fb34ceeff952f1c6b172258e8ce33c 100644
--- a/core/Logger.hh
+++ b/core/Logger.hh
@@ -14,6 +14,7 @@
  *   Kovacs, Ferenc
  *   Raduly, Csaba
  *   Szabados, Kristof
+ *   Szabo, Bence Janos
  *   Szabo, Janos Zoltan – initial implementation
  *   Zalanyi, Balazs Andor
  *   Pandi, Krisztian
@@ -123,45 +124,46 @@ public:
     PORTEVENT_DUALRECV,
     PORTEVENT_DUALSEND,
     PORTEVENT_UNQUALIFIED, //35
+    PORTEVENT_SETSTATE,
 
     STATISTICS_VERDICT,
     STATISTICS_UNQUALIFIED,
 
     TIMEROP_READ,
-    TIMEROP_START,
-    TIMEROP_GUARD, //40
+    TIMEROP_START, //40
+    TIMEROP_GUARD,
     TIMEROP_STOP,
     TIMEROP_TIMEOUT,
     TIMEROP_UNQUALIFIED,
 
-    USER_UNQUALIFIED,
+    USER_UNQUALIFIED, //45
 
-    VERDICTOP_GETVERDICT, //45
+    VERDICTOP_GETVERDICT,
     VERDICTOP_SETVERDICT,
     VERDICTOP_FINAL,
     VERDICTOP_UNQUALIFIED,
 
-    WARNING_UNQUALIFIED,
+    WARNING_UNQUALIFIED, //50
 
     // MATCHING and DEBUG should be at the end (not included in LOG_ALL)
-    MATCHING_DONE, //50
+    MATCHING_DONE,
     MATCHING_TIMEOUT,
     MATCHING_PCSUCCESS,
     MATCHING_PCUNSUCC,
-    MATCHING_PMSUCCESS,
-    MATCHING_PMUNSUCC, //55
+    MATCHING_PMSUCCESS, //55
+    MATCHING_PMUNSUCC,
     MATCHING_MCSUCCESS,
     MATCHING_MCUNSUCC,
     MATCHING_MMSUCCESS,
-    MATCHING_MMUNSUCC,
-    MATCHING_PROBLEM, //60
+    MATCHING_MMUNSUCC, //60
+    MATCHING_PROBLEM,
     MATCHING_UNQUALIFIED,
 
     DEBUG_ENCDEC,
     DEBUG_TESTPORT,
     DEBUG_USER,
     DEBUG_FRAMEWORK,
-    DEBUG_UNQUALIFIED, //66
+    DEBUG_UNQUALIFIED, //67
 
     NUMBER_OF_LOGSEVERITIES, // must follow the last individual severity
     LOG_ALL_IMPORTANT
@@ -735,6 +737,8 @@ public:
     const CHARSTRING& value, int id);
   static void log_dualport_discard(boolean incoming, const char *target_type,
     const char *port_name, boolean unhaldled);
+  static void log_setstate(const char *port_name, translation_port_state state,
+    const CHARSTRING& info);
 
   static void log_port_misc(int reason, const char *port_name,
     int remote_component = NULL_COMPREF, const char *remote_port = NULL,
diff --git a/core/LoggerPluginManager.cc b/core/LoggerPluginManager.cc
index bcd5bf22f7d08bfcd91b782e63fd40ab9cca47fd..e3a2a6da1bcbb5af3a26206b8e4952e7b1d60106 100644
--- a/core/LoggerPluginManager.cc
+++ b/core/LoggerPluginManager.cc
@@ -12,6 +12,7 @@
  *   Kovacs, Ferenc
  *   Raduly, Csaba
  *   Szabados, Kristof
+ *   Szabo, Bence Janos
  *   Zalanyi, Balazs Andor
  *   Pandi, Krisztian
  *
@@ -1506,6 +1507,40 @@ void LoggerPluginManager::log_dualport_discard(boolean incoming, const char *tar
   log(event);
 }
 
+void LoggerPluginManager::log_setstate(const char *port_name, translation_port_state state,
+  const CHARSTRING& info)
+{
+  if (!TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_SETSTATE) && (TTCN_Logger::get_emergency_logging()<=0))
+    return;
+  API::TitanLogEvent event;
+  fill_common_fields(event, TTCN_Logger::PORTEVENT_SETSTATE);
+
+  API::Setstate& setstate = event.logEvent().choice().portEvent().choice().setState();
+  setstate.port__name() = port_name;
+  setstate.info() = (const char*)info;
+  switch (state) {
+    case UNSET:
+      setstate.state() = "unset";
+      break;
+    case TRANSLATED:
+      setstate.state() = "translated";
+      break;
+    case NOT_TRANSLATED:
+      setstate.state() = "not translated";
+      break;
+     case FRAGMENTED:
+      setstate.state() = "fragmented";
+      break;
+    case PARTIALLY_TRANSLATED:
+      setstate.state() = "partially translated";
+      break;
+    default:
+      TTCN_Logger::fatal_error("LoggerPluginManager::log_setstate(): unexpected port state");
+  }
+
+  log(event);
+}
+
 void LoggerPluginManager::log_port_misc(int reason, const char *port_name,
   int remote_component, const char *remote_port, const char *ip_address,
   int tcp_port, int new_size)
diff --git a/core/LoggerPluginManager.hh b/core/LoggerPluginManager.hh
index e31d1927a94aebd85d7fa1faf799f7dd5f94aa1d..e332ed1268dcf174007ff5eb75c686b5feaf51eb 100644
--- a/core/LoggerPluginManager.hh
+++ b/core/LoggerPluginManager.hh
@@ -11,6 +11,7 @@
  *   Kovacs, Ferenc
  *   Raduly, Csaba
  *   Szabados, Kristof
+ *   Szabo, Bence Janos
  *   Zalanyi, Balazs Andor
  *   Pandi, Krisztian
  *
@@ -224,6 +225,8 @@ public:
     const CHARSTRING& value, int id);
   void log_dualport_discard(boolean incoming, const char *target_type,
     const char *port_name, boolean unhandled);
+  void log_setstate(const char *port_name, translation_port_state state,
+    const CHARSTRING& info);
 
   void log_port_misc(int reason, const char *port_name, int remote_component,
     const char *remote_port, const char *ip_address, int tcp_port, int new_size);
diff --git a/core/LoggingBits.cc b/core/LoggingBits.cc
index 48189d8f0c920f856d68d63ba09f1e8f6bcc5472..4da48036e97f409d5e83053a393ec94c330a6683 100644
--- a/core/LoggingBits.cc
+++ b/core/LoggingBits.cc
@@ -9,6 +9,7 @@
  *   Balasko, Jeno
  *   Delic, Adam
  *   Raduly, Csaba
+ *   Szabo, Bence Janos
  *
  ******************************************************************************/
 #include "LoggingBits.hh"
@@ -120,7 +121,7 @@ const Logging_Bits Logging_Bits::log_all = {
     1,1, // FUNCTION
     1,1,1,1, // PARALLEL
     1,1,1, // TESTCASE
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1, // PORTEVENT
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // PORTEVENT
     1,1, // STATISTICS
     1,1,1,1,1,1, // TIMEROP
     1, // USER
@@ -133,7 +134,7 @@ const Logging_Bits Logging_Bits::log_all = {
 
 const Logging_Bits Logging_Bits::log_everything = {
   { 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }
 };
 
 // TTCN_ERROR | TTCN_WARNING | TTCN_ACTION | TTCN_TESTCASE | TTCN_STATISTICS
@@ -146,7 +147,7 @@ const Logging_Bits Logging_Bits::default_console_mask = {
     0,0, // FUNCTION
     0,0,0,0, // PARALLEL
     1,1,1, // TESTCASE
-    0,0,0,0,0,0,0,0,0,0,0,0,0,0, // PORTEVENT
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // PORTEVENT
     1,1, // STATISTICS
     0,0,0,0,0,0, // TIMEROP
     0, // USER
diff --git a/core/Port.cc b/core/Port.cc
index 0451572b05ad92e2688ce48daf072d93877dc82b..7fdfc1de480e6d90698ad08fd59b47a0413c234e 100644
--- a/core/Port.cc
+++ b/core/Port.cc
@@ -2215,6 +2215,10 @@ void PORT::reset_port_variables() {
   
 }
 
+void PORT::change_port_state(translation_port_state /*state*/) {
+  
+}
+
 void PORT::process_connect_listen(const char *local_port,
   component remote_component, const char *remote_port,
   transport_type_enum transport_type)
diff --git a/core/Port.hh b/core/Port.hh
index 4e1c582852744c044eaad086b0222f2bbae45317..f75927a288babf0373018a30bf4fe279735471b8 100644
--- a/core/Port.hh
+++ b/core/Port.hh
@@ -133,6 +133,9 @@ public:
   boolean check_port_state(const CHARSTRING& type) const;
   static boolean any_check_port_state(const CHARSTRING& type);
   static boolean all_check_port_state(const CHARSTRING& type);
+  
+  // Used by the setstate operation through TTCN_Runtime
+  virtual void change_port_state(translation_port_state state);
 
   virtual alt_status receive(const COMPONENT_template& sender_template =
     any_compref, COMPONENT *sender_ptr = NULL,
diff --git a/core/Runtime.cc b/core/Runtime.cc
index 64fad5f1f39d9064b38fd89a697fa6c13c63d8c5..67eee909ef904d3a79f39fee6a3257b4ea7da9b2 100644
--- a/core/Runtime.cc
+++ b/core/Runtime.cc
@@ -59,6 +59,8 @@
 #include "Fd_And_Timeout_User.hh"
 #include <TitanLoggerApi.hh>
 #include "Profiler.hh"
+#include "Integer.hh"
+#include "Port.hh"
 
 namespace API = TitanLoggerApi;
 
@@ -116,6 +118,31 @@ struct TTCN_Runtime::component_process_struct {
 } **TTCN_Runtime::components_by_compref = NULL,
   **TTCN_Runtime::components_by_pid = NULL;
 
+boolean TTCN_Runtime::translation_flag = FALSE;
+PORT* TTCN_Runtime::p = NULL;
+
+void TTCN_Runtime::set_port_state(const INTEGER& state, const CHARSTRING& info, boolean by_system) {
+  if (translation_flag) {
+    if (p != NULL) {
+      int lowed_end = by_system ? -1 : 0;
+      if (state < lowed_end || state > 3) {
+        TTCN_error("The value of the first parameter in the setstate operation must be 0, 1, 2 or 3.");
+      }
+      p->change_port_state((translation_port_state)((int)state));
+      TTCN_Logger::log_setstate(p->get_name(), (translation_port_state)((int)state), info);
+    } else {
+      TTCN_error("Internal error: TTCN_Runtime::set_port_state: The port is NULL.");
+    }
+  } else {
+    TTCN_error("setstate operation was called without being in a translation procedure.");
+  }
+}
+
+void TTCN_Runtime::set_translation_mode(boolean enabled, PORT* port) {
+  translation_flag = enabled;
+  p = port;
+}
+
 boolean TTCN_Runtime::is_idle()
 {
   switch (executor_state) {
diff --git a/core/Runtime.hh b/core/Runtime.hh
index 4be6bba6f44d8d1e0819819e821d26d70265e751..798f2e8e6c19e7977bfa92ce2c5a1c4cf2aad3df 100644
--- a/core/Runtime.hh
+++ b/core/Runtime.hh
@@ -29,6 +29,8 @@ class Text_Buf;
 class COMPONENT;
 class VERDICTTYPE;
 class CHARSTRING;
+class INTEGER;
+class PORT;
 
 extern "C" {
 typedef void (*signal_handler_type)(int);
@@ -93,6 +95,12 @@ private:
   struct component_process_struct;
   static component_process_struct **components_by_compref,
   **components_by_pid;
+  
+  // Translation flag is set to true before each port translation function called,
+  // and set to false after each port translation function.
+  static boolean translation_flag;
+  // The port which state will be changed by change_port_state
+  static PORT* p;
 
 public:
   inline static executor_state_enum get_state() { return executor_state; }
@@ -122,6 +130,9 @@ public:
   /** @} */
 
   static boolean is_in_ttcn_try_block() { return in_ttcn_try_block; }
+  
+  static void set_port_state(const INTEGER& state, const CHARSTRING& info, boolean by_system);
+  static void set_translation_mode(boolean enabled, PORT* port);
 
 private:
   inline static boolean in_controlpart()
diff --git a/core/TitanLoggerApi.xsd b/core/TitanLoggerApi.xsd
index 77c225ae9cc03ff2f2fcc0761c814f818c935b3f..a2afa7fcb7cb3119a0bcaf99a7bdeac4fcef6a60 100644
--- a/core/TitanLoggerApi.xsd
+++ b/core/TitanLoggerApi.xsd
@@ -271,6 +271,7 @@
 
     <element name="dualMapped"       type="TitanLoggerApi:Dualface_mapped" />
     <element name="dualDiscard"      type="TitanLoggerApi:Dualface_discard" />
+    <element name="setState"         type="TitanLoggerApi:Setstate" />
 
     <element name="portMisc"         type="TitanLoggerApi:Port_Misc" />
   </choice>
@@ -915,6 +916,14 @@
   </sequence>
 </complexType>
 
+<complexType name="Setstate">
+  <sequence>
+    <element name="port_name"   type="string" />
+    <element name="state"       type="string" />
+    <element name="info"        type="string" />
+  </sequence>
+</complexType>
+
 <complexType name="Port_Misc">
   <sequence>
     <element name="reason">
diff --git a/core/TitanLoggerControl.ttcn b/core/TitanLoggerControl.ttcn
index 2898b2a95cb1e8641c012b838de7b22d1ac9a62a..85b84c19befe53226b7d0413a2f8d40251ee692e 100644
--- a/core/TitanLoggerControl.ttcn
+++ b/core/TitanLoggerControl.ttcn
@@ -81,6 +81,7 @@ type enumerated Severity // copy-paste from Logger.hh
     PORTEVENT_DUALRECV,
     PORTEVENT_DUALSEND,
     PORTEVENT_UNQUALIFIED,
+    PORTEVENT_SETSTATE,
 
     STATISTICS_VERDICT,
     STATISTICS_UNQUALIFIED,
@@ -164,7 +165,7 @@ const Severities log_all :=
     PORTEVENT_PQUEUE, PORTEVENT_MQUEUE, PORTEVENT_STATE,
     PORTEVENT_PMIN, PORTEVENT_PMOUT, PORTEVENT_PCIN, PORTEVENT_PCOUT,
     PORTEVENT_MMRECV, PORTEVENT_MMSEND, PORTEVENT_MCRECV, PORTEVENT_MCSEND,
-    PORTEVENT_DUALRECV, PORTEVENT_DUALSEND, PORTEVENT_UNQUALIFIED,
+    PORTEVENT_DUALRECV, PORTEVENT_DUALSEND, PORTEVENT_UNQUALIFIED, PORTEVENT_SETSTATE,
 
     STATISTICS_VERDICT, STATISTICS_UNQUALIFIED,
 
@@ -198,7 +199,7 @@ const Severities log_everything :=
     PORTEVENT_PQUEUE, PORTEVENT_MQUEUE, PORTEVENT_STATE,
     PORTEVENT_PMIN, PORTEVENT_PMOUT, PORTEVENT_PCIN, PORTEVENT_PCOUT,
     PORTEVENT_MMRECV, PORTEVENT_MMSEND, PORTEVENT_MCRECV, PORTEVENT_MCSEND,
-    PORTEVENT_DUALRECV, PORTEVENT_DUALSEND, PORTEVENT_UNQUALIFIED,
+    PORTEVENT_DUALRECV, PORTEVENT_DUALSEND, PORTEVENT_UNQUALIFIED, PORTEVENT_SETSTATE,
 
     STATISTICS_VERDICT, STATISTICS_UNQUALIFIED,
 
diff --git a/core/Types.h b/core/Types.h
index 85b35525fd76bc7050af506d5e61ab530dbee13a..1ffd1dbf98460a6818c4ef8cbc8bdc64d49c969b 100644
--- a/core/Types.h
+++ b/core/Types.h
@@ -12,6 +12,7 @@
  *   Forstner, Matyas
  *   Kovacs, Ferenc
  *   Raduly, Csaba
+ *   Szabo, Bence Janos
  *   Szabo, Janos Zoltan – initial implementation
  *   Zalanyi, Balazs Andor
  *
@@ -128,4 +129,13 @@ struct namespace_t {
   const char * const px;
 };
 
+// States defined with the setstate operation.
+enum translation_port_state {
+  UNSET = -1,
+  TRANSLATED = 0,
+  NOT_TRANSLATED = 1,
+  FRAGMENTED = 2,
+  PARTIALLY_TRANSLATED = 3
+};
+
 #endif
diff --git a/core/config_process.l b/core/config_process.l
index b88b61ab4c363405dc7da1dbff974be2f3a82d45..3f8a760bc988fc17078bd9836b021510e8da9bf6 100644
--- a/core/config_process.l
+++ b/core/config_process.l
@@ -894,6 +894,10 @@ PORTEVENT_UNQUALIFIED		{
 	yylval.logseverity_val = TTCN_Logger::PORTEVENT_UNQUALIFIED;
 	return LoggingBit;
 	}
+PORTEVENT_SETSTATE		{
+	yylval.logseverity_val = TTCN_Logger::PORTEVENT_SETSTATE;
+	return LoggingBit;
+	}
 (TTCN_)?PORTEVENT		{
 	yylval.logseverity_val = TTCN_Logger::PORTEVENT_UNQUALIFIED;
 	return LoggingBitCollection;
diff --git a/core/config_process.y b/core/config_process.y
index 82ae8ed8e65dcdec9d72b1981f94175da0b5ed52..72bea827cf2a8e6649f0c51dea37e1a917d09e3a 100644
--- a/core/config_process.y
+++ b/core/config_process.y
@@ -1708,6 +1708,7 @@ LoggingBitOrCollection:
 	$$.add_sev(TTCN_Logger::PORTEVENT_DUALRECV);
 	$$.add_sev(TTCN_Logger::PORTEVENT_DUALSEND);
 	$$.add_sev(TTCN_Logger::PORTEVENT_UNQUALIFIED);
+  $$.add_sev(TTCN_Logger::PORTEVENT_SETSTATE);
 	break;
     case TTCN_Logger::TESTCASE_UNQUALIFIED:
 	$$.add_sev(TTCN_Logger::TESTCASE_START);
diff --git a/function_test/Semantic_Analyser/port_translation/Setstate_SE.ttcn b/function_test/Semantic_Analyser/port_translation/Setstate_SE.ttcn
new file mode 100644
index 0000000000000000000000000000000000000000..ca283746ee34b13468da0c1cf481614aa563f280
--- /dev/null
+++ b/function_test/Semantic_Analyser/port_translation/Setstate_SE.ttcn
@@ -0,0 +1,24 @@
+/******************************************************************************
+ * Copyright (c) 2000-2017 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:
+ *   Szabo, Bence Janos
+ *
+ ******************************************************************************/
+module Setstate_SE { //^In TTCN-3 module//
+
+	const integer i1 := 4;
+	const integer i2 := 9999999999999999999999999999999999999999999999999999;
+
+	function f() { //^In function definition \`f\'\://
+		port.setstate(-1); //^In setstate statement\:// //^In first parameter\:// //^error\: The value of the first parameter must be 0\, 1\, 2 or 3\.//
+		port.setstate(9999999999999999999999999999999999999999999999999999); //^In setstate statement\:// //^In first parameter\:// //^error\: The value of the first parameter must be 0\, 1\, 2 or 3\.//
+		port.setstate(i1); //^In setstate statement\:// //^In first parameter\:// //^error\: The value of the first parameter must be 0\, 1\, 2 or 3\.//
+		port.setstate(i2); //^In setstate statement\:// //^In first parameter\:// //^error\: The value of the first parameter must be 0\, 1\, 2 or 3\.//
+	}
+
+}
\ No newline at end of file
diff --git a/help/info/BNF.html b/help/info/BNF.html
index 6baa4bc511ecdd96a686f71bb06ddeed55a41cc3..918cf9fef08d82aa35c35965a93c0c2ce52783c4 100644
--- a/help/info/BNF.html
+++ b/help/info/BNF.html
@@ -374,6 +374,22 @@ This ABNF browser was generated from file &lt;mockup_bnf.txt&gt; on Tue Jul 20 1
     <TD></TD>
     <TD></TD>
   </TR>
+  <TR VALIGN=TOP>
+    <TD>
+    <P><A NAME="setstatedef"></a><A HREF="#Xref.SetstateDef">SetstateDef</A>
+    <TD VALIGN=TOP>=</TD>
+    <TD><A HREF="#portkeyword">PortKeyword</A> . <A HREF="#setstatekeyword">SetstateKeyword</A> ( <A HREF="#singleexpression">SingleExpression</A> "," [ <A HREF="#freetext">FreeText</A> | <A HREF="#templateinstance">TemplateInstance</A></TD>
+  </TR>
+  <TR VALIGN=TOP>
+    <TD>
+    <P><A NAME="setstatekeyword"></a><A HREF="#Xref.SetstateKeyword">SetstateKeyword</A>
+    <TD VALIGN=TOP>=</TD>
+    <TD>"<FONT COLOR="black">setstate</FONT>"</TD>
+  </TR>
+  <TR VALIGN=TOP>
+    <TD></TD>
+    <TD></TD>
+  </TR>
   <TR VALIGN=TOP>
     <TD>
     <P><A NAME="recordofdef"></a><A HREF="#Xref.RecordOfDef">RecordOfDef</A>
@@ -5796,7 +5812,7 @@ This ABNF browser was generated from file &lt;mockup_bnf.txt&gt; on Tue Jul 20 1
   </TR>
   <TR VALIGN=TOP>
     <TD><A NAME="Xref.FreeText"></a><A HREF="#freetext">FreeText</A></TD>
-    <TD><A HREF="#languagespec">LanguageSpec</A>, <A HREF="#attribspec">AttribSpec</A>, <A HREF="#sutstatements">SUTStatements</A>, <A HREF="#logstatement">LogStatement</A></TD>
+    <TD><A HREF="#languagespec">LanguageSpec</A>, <A HREF="#attribspec">AttribSpec</A>, <A HREF="#sutstatements">SUTStatements</A>, <A HREF="#logstatement">LogStatement</A>, <A HREF="#setstatedef">SetstateDef</A></TD>
   </TR>
   <TR VALIGN=TOP>
     <TD><A NAME="Xref.FromClause"></a><A HREF="#fromclause">FromClause</A></TD>
@@ -6496,7 +6512,7 @@ This ABNF browser was generated from file &lt;mockup_bnf.txt&gt; on Tue Jul 20 1
   </TR>
   <TR VALIGN=TOP>
     <TD><A NAME="Xref.PortKeyword"></a><A HREF="#portkeyword">PortKeyword</A></TD>
-    <TD><A HREF="#portdef">PortDef</A>, <A HREF="#portinstance">PortInstance</A>, <A HREF="#portorany">PortOrAny</A>, <A HREF="#portorall">PortOrAll</A></TD>
+    <TD><A HREF="#portdef">PortDef</A>, <A HREF="#portinstance">PortInstance</A>, <A HREF="#portorany">PortOrAny</A>, <A HREF="#portorall">PortOrAll</A>, <A HREF="#setstatedef">SetstateDef</A></TD>
   </TR>
   <TR VALIGN=TOP>
     <TD><A NAME="Xref.PortOrAll"></a><A HREF="#portorall">PortOrAll</A></TD>
@@ -6790,6 +6806,10 @@ This ABNF browser was generated from file &lt;mockup_bnf.txt&gt; on Tue Jul 20 1
     <TD><A NAME="Xref.SetOfDef"></a><A HREF="#setofdef">SetOfDef</A></TD>
     <TD><A HREF="#structuredtypedef">StructuredTypeDef</A></TD>
   </TR>
+  <TR VALIGN=TOP>
+    <TD><A NAME="Xref.SetstateKeyword"></a><A HREF="#setstatekeyword">SetstateKeyword</A></TD>
+    <TD><A HREF="#setstatedef">SetstateDef</A></TD>
+  </TR>
   <TR VALIGN=TOP>
     <TD><A NAME="Xref.SetVerdictKeyword"></a><A HREF="#setverdictkeyword">SetVerdictKeyword</A></TD>
     <TD><A HREF="#setlocalverdict">SetLocalVerdict</A></TD>
@@ -6856,7 +6876,7 @@ This ABNF browser was generated from file &lt;mockup_bnf.txt&gt; on Tue Jul 20 1
   <TR VALIGN=TOP>
     <TD><A NAME="Xref.SingleExpression"></a><A HREF="#singleexpression">SingleExpression</A></TD>
     <TD><A HREF="#fieldorbitnumber">FieldOrBitNumber</A>, <A HREF="#singlevalueorattrib">SingleValueOrAttrib</A>, <A HREF="#setlocalverdict">SetLocalVerdict</A>, <A HREF="#expression">Expression</A>,
-    <A HREF="#singleconstexpression">SingleConstExpression</A>, <A HREF="#booleanexpression">BooleanExpression</A>, <A HREF="#primary">Primary</A></TD>
+    <A HREF="#singleconstexpression">SingleConstExpression</A>, <A HREF="#booleanexpression">BooleanExpression</A>, <A HREF="#primary">Primary</A>, <A HREF="#setstatedef">SetstateDef</A></TD>
   </TR>
   <TR VALIGN=TOP>
     <TD><A NAME="Xref.SingleTimerInstance"></a><A HREF="#singletimerinstance">SingleTimerInstance</A></TD>
@@ -7049,7 +7069,7 @@ This ABNF browser was generated from file &lt;mockup_bnf.txt&gt; on Tue Jul 20 1
     <TD><A NAME="Xref.TemplateInstance"></a><A HREF="#templateinstance">TemplateInstance</A></TD>
     <TD><A HREF="#templateactualpar">TemplateActualPar</A>, <A HREF="#matchop">MatchOp</A>, <A HREF="#valueofop">ValueofOp</A>, <A HREF="#functionactualpar">FunctionActualPar</A>, <A
       HREF="#testcaseactualpar">TestcaseActualPar</A>, <A HREF="#sendparameter">SendParameter</A>, <A HREF="#callparameters">CallParameters</A>, <A HREF="#portreplyop">PortReplyOp</A>, <A
-      HREF="#portraiseop">PortRaiseOp</A>, <A HREF="#receiveparameter">ReceiveParameter</A>, <A HREF="#valuematchspec">ValueMatchSpec</A>, <A HREF="#catchopparameter">CatchOpParameter</A></TD>
+      HREF="#portraiseop">PortRaiseOp</A>, <A HREF="#receiveparameter">ReceiveParameter</A>, <A HREF="#valuematchspec">ValueMatchSpec</A>, <A HREF="#catchopparameter">CatchOpParameter</A>, <A HREF="#setstatedef">SetstateDef</A></TD>
   </TR>
   <TR VALIGN=TOP>
     <TD><A NAME="Xref.TemplateKeyword"></a><A HREF="#templatekeyword">TemplateKeyword</A></TD>
diff --git a/help/info/set.html b/help/info/set.html
index 3bca52eb20f994940e70eb2cc9f68ad8641a2eb0..7883c059de69297a21689770f4f7fb24363f5211 100644
--- a/help/info/set.html
+++ b/help/info/set.html
@@ -32,7 +32,7 @@
     <td><a href="../titan_main.html" alt="contents"><img border="0" src="../images/ao.jpg" width="53" height="40"></a></td>
     <td><a href="../titan_index.html" alt="index"><img border="0" src="../images/up.jpg" width="53" height="40"></a></td>
     <td><a href="sender.html" alt="previous"><img border="0" src="../images/left.jpg" width="53" height="40"></a></td>
-    <td><a href="setverdict.html" alt="next"><img border="0" src="../images/right.jpg" width="53" height="40"></a></td>
+    <td><a href="setstate.html" alt="next"><img border="0" src="../images/right.jpg" width="53" height="40"></a></td>
   </tr>
 </table>
 <p><br clear="all">
diff --git a/help/info/setstate.html b/help/info/setstate.html
new file mode 100644
index 0000000000000000000000000000000000000000..63d74017a66424ad1fd8949d13916e539ded80c0
--- /dev/null
+++ b/help/info/setstate.html
@@ -0,0 +1,81 @@
+<!--
+ Copyright (c) 2000-2017 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:
+  Szabo, Bence Janos
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<meta http-equiv="Content-Language" content="en-us">
+<title>set</title>
+</head>
+<body bgcolor="#DAD3C5" vlink="#0094D2" link="#003258">
+<table align="left" border="0" cellspacing="0" cellpadding="0" valign=top>
+  <tr>
+    <td width=105 height=40><a href="https://projects.eclipse.org/projects/tools.titan"><img src="../images/titan_transparent.gif" border=0 width=105 height=40 align="left" alt="Titan"></a></td>
+  </tr>
+</table>
+<table border="0" align="right" cellpadding="0" cellspacing="0">
+  <tr>
+    <td><a href="../titan_main.html" alt="contents"><img border="0" src="../images/ao.jpg" width="53" height="40"></a></td>
+    <td><a href="../titan_index.html" alt="index"><img border="0" src="../images/up.jpg" width="53" height="40"></a></td>
+    <td><a href="set.html" alt="previous"><img border="0" src="../images/left.jpg" width="53" height="40"></a></td>
+    <td><a href="setverdict.html" alt="next"><img border="0" src="../images/right.jpg" width="53" height="40"></a></td>
+  </tr>
+</table>
+<p><br clear="all">
+</p>
+<hr>
+<h1>setstate</h1>
+<hr align="left" width="75%">
+<p>The setstate operation can change the state of the port during a translation procedure. It can only be used inside a function that is called during a translation procedure to translate a sent or received message.
+<ul>
+  <li>The setstate operation has two parameters. The second parameter is optional.</li>
+  <li>The first parameter has to be a type of integer and only the 0 (translated), 1 (not translated), 2 (fragmented) and 3 (partially translated) values are accepted.</li>
+  <li>The second parameter can be used for logging purposes.</li>
+</ul>
+<p>Related keywords:</p>
+<ul>
+  <li><a href="port.html"><font face="Courier New" color="#003258" size="4"><b>port</b></font></a></li>
+  <li><a href="map.html"><font face="Courier New" color="#003258" size="4"><b>map</b></font></a></li>
+</ul>
+<hr align="left" width="50%">
+<div align="center">
+<center>
+<table border="0" width="90%" bgcolor="#FFB599" cellpadding="4">
+  <tr>
+    <td width="100%">
+    <h3 align="center"><font face="Courier New" color="#003258" size="5"><b>port.setstate</b>&nbsp;</font> (<i>SimpleExpression&nbsp; ,</i> <font
+      face="Courier New" color="#003258" size="5"><b> {</b></font>&nbsp; <i>Freetext | TemplateInstance</i>&nbsp;[ <font face="Courier New" color="#003258" size="5"><b>optional</b></font>
+    ]<font face="Courier New" color="#003258" size="5"><b>};</b></font></h3>
+    </td>
+  </tr>
+</table>
+</center>
+</div>
+<ul>
+  <li>
+  <p><i>SimpleExpression</i> is the&nbsp; state which the ports state will be changed, and has to be of integer type.</p>
+  </li>
+  <li>
+  <p><i>FreeText or TemplateInstance</i> can be used&nbsp; for logging. Its value will be present in the logfile.</p>
+  </li>
+</ul>
+<hr align="left" width="50%">
+<p><a name="Example 1">Example 1</a>: set ports state to translated without additional information
+<p><font face="Courier New">port.setstate(0);
+</font>
+<hr align="left" width="50%">
+<p><a name="Example 2">Example 2</a>: set the state of the port to not translated with additional information
+<p><font face="Courier New">port.setstate(1, "Not successful");<br>
+</font>
+<hr align="left" width="25%">
+<hr align="left" width="25%">
+<p><a HREF="BNF.html#setstatedef">BNF definition</a> of <font face="Courier New"> setstate</font></p>
+</body>
+</html>
diff --git a/help/info/setverdict.html b/help/info/setverdict.html
index 548121660d933fca0e574f50f8a74332b1a5672f..5fb4e802f4a6a26bc0c6f689090cee146971af6c 100644
--- a/help/info/setverdict.html
+++ b/help/info/setverdict.html
@@ -28,7 +28,7 @@
   <tr>
     <td><a href="../titan_main.html" alt="contents"><img border="0" src="../images/ao.jpg" width="53" height="40"></a></td>
     <td><a href="../titan_index.html" alt="index"><img border="0" src="../images/up.jpg" width="53" height="40"></a></td>
-    <td><a alt="previous" href="set.html"><img border="0" src="../images/left.jpg" width="53" height="40"></a></td>
+    <td><a alt="previous" href="setstate.html"><img border="0" src="../images/left.jpg" width="53" height="40"></a></td>
     <td><a href="signature.html" alt="next"><img border="0" src="../images/right.jpg" width="53" height="40"></a></td>
   </tr>
 </table>
diff --git a/help/titan_index.html b/help/titan_index.html
index 905aeff535aa0bdbc02d179f297a538176f586d3..16437d6d5e741e1b82fc8657037c8aa13c929c75 100644
--- a/help/titan_index.html
+++ b/help/titan_index.html
@@ -16,6 +16,7 @@
   Kovacs, Ferenc
   Raduly, Csaba
   Szabados, Kristof
+  Szabo, Bence Janos
   Zalanyi, Balazs Andor
 -->
 <html>
@@ -321,26 +322,26 @@
     <td width="17%"><a href="info/send.html">send</a></td>
     <td width="17%"><a href="info/sender.html">sender</a></td>
     <td width="17%"><a href="info/set.html">set</a></td>
+    <td width="17%"><a href="info/setstate.html">setstate</a></td>
     <td width="17%"><a href="info/setverdict.html">setverdict</a></td>
-    <td width="17%"><a href="info/signature.html">signature</a></td>
   </tr>
   <tr>
+    <td width="17%"><a href="info/signature.html">signature</a></td>
     <td width="17%"><a href="info/sizeof.html">sizeof</a></td>
     <td width="17%"><a href="info/start.html">start</a></td>
     <td width="17%"><a href="info/stop.html">stop</a></td>
     <td width="17%"><a href="info/str2bit.html">str2bit</a></td>
     <td width="17%"><a href="info/str2float.html">str2float</a></td>
     <td width="17%"><a href="info/str2hex.html">str2hex</a></td>
-    <td width="17%"><a href="info/str2int.html">str2int</a></td>
   </tr>
   <tr>
+    <td width="17%"><a href="info/str2int.html">str2int</a></td>
     <td width="17%"><a href="info/str2oct.html">str2oct</a></td>
     <td width="17%"><a href="info/subset.html">subset</a></td>
     <td width="17%"><a href="info/substr.html">substr</a></td>
     <td width="17%"><a href="info/superset.html">superset</a></td>
     <td width="17%"><a href="info/system.html">system</a></td>
     <td width="17%">&nbsp;</td>
-    <td width="17%">&nbsp;</td>
   </tr>
   <tr>
     <td width="17%"><a name="t"></a><a href="info/template.html">template</a></td>
diff --git a/mctr2/cli/config_read.l b/mctr2/cli/config_read.l
index c19066b9f129c05d7478376dab4c2831b282d362..5b232c98e2885b131c39ca93faed1a5a8f0fae52 100644
--- a/mctr2/cli/config_read.l
+++ b/mctr2/cli/config_read.l
@@ -579,6 +579,7 @@ PORTEVENT_PMOUT |
 PORTEVENT_PQUEUE |
 PORTEVENT_STATE |
 PORTEVENT_UNQUALIFIED |
+PORTEVENT_SETSTATE |
 STATISTICS_UNQUALIFIED |
 STATISTICS_VERDICT |
 TESTCASE_FINISH |
diff --git a/regression_test/compileonly/portTranslation/PortTranslate.ttcn b/regression_test/compileonly/portTranslation/PortTranslate.ttcn
index 1d6ef2304e0bcdb0a248ae63a686eba1339bfd53..d0d1e74ad7d44aacb5cf6bb973a8b6504ea2d758 100644
--- a/regression_test/compileonly/portTranslation/PortTranslate.ttcn
+++ b/regression_test/compileonly/portTranslation/PortTranslate.ttcn
@@ -293,7 +293,14 @@ module PortTranslate {
 	}
 
 
+	type component Comp1 {
+		port PT16 pt16[4][5][5];
+		port P22  p22[3][5][6];
+	}
 
+	testcase tc_port_arr() runs on Comp1 {
+		map(self:pt16[1][2][3], system:p22[1][2][3]);
+	}
 
 	/* Conversion functions */
 
@@ -426,4 +433,5 @@ module PortTranslate {
 	}
 
 
+
 }
\ No newline at end of file
diff --git a/regression_test/portTranslation/Makefile b/regression_test/portTranslation/Makefile
index 2e832903ba7a2b97403099e05cb420c9492ca2e4..108ffb482c566d1bcc76ef3097a497c3b0160563 100644
--- a/regression_test/portTranslation/Makefile
+++ b/regression_test/portTranslation/Makefile
@@ -47,14 +47,14 @@ TTCN3_LIB = ttcn3$(RT2_SUFFIX)-parallel$(DYNAMIC_SUFFIX)
 
 
 # TTCN-3 modules of this project:
-TTCN3_MODULES = PortTranslation.ttcn
+TTCN3_MODULES = PortTranslation.ttcn Setstate_neg.ttcn
 
 # ASN.1 modules of this project:
 ASN1_MODULES =
 
 # C++ source & header files generated from the TTCN-3 & ASN.1 modules of
 # this project:
-GENERATED_SOURCES = $(TTCN3_MODULES:.ttcn=.cc) $(ASN1_MODULES:.asn=.cc)
+GENERATED_SOURCES = $(TTCN3_MODULES:.ttcn=.cc) $(ASN1_MODULES:.asn=.cc) NP1.cc NPT2.cc
 GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh)
 ifdef SPLIT_TO_SLICES
 POSTFIXES := $(foreach file, $(SPLIT_TO_SLICES), $(addsuffix $(file), _part_))
@@ -114,7 +114,7 @@ compile:: $(TTCN3_DIR)/bin/compiler # $(TTCN3_COMPILER)
 	@if [ -f $@ ]; then $(RM) compile; $(MAKE) compile; fi
 
 compile:: $(TTCN3_MODULES) $(ASN1_MODULES)
-	$(TTCN3_COMPILER) $(COMPILER_FLAGS) $^ - $?
+	$(TTCN3_COMPILER) $(COMPILER_FLAGS) -t $^ - $?
 	touch $@
 
 clean distclean:
diff --git a/regression_test/portTranslation/P3.cc b/regression_test/portTranslation/P3.cc
index 91d1624a49d66f75ab6694ca8815d28e71416a44..0125a047e6ef4864869ed8a4fba61ee98b95dfc1 100644
--- a/regression_test/portTranslation/P3.cc
+++ b/regression_test/portTranslation/P3.cc
@@ -87,5 +87,15 @@ void P3::outgoing_send(const OCTETSTRING& /*send_par*/)
 
 }
 
+void P3::outgoing_send(const HEXSTRING& /*send_par*/)
+{
+
+}
+
+void P3::outgoing_send(const INTEGER& /*send_par*/)
+{
+
+}
+
 } /* end of namespace */
 
diff --git a/regression_test/portTranslation/P3.hh b/regression_test/portTranslation/P3.hh
index ee06a1b105f727bf8b84257ee5d05d8f8d079ab4..c2ecf73f8e61cb0aeceb6e902bdc7f68e811e23c 100644
--- a/regression_test/portTranslation/P3.hh
+++ b/regression_test/portTranslation/P3.hh
@@ -42,6 +42,8 @@ protected:
 	void outgoing_send(const MyRec& send_par);
 	void outgoing_send(const BITSTRING& send_par);
 	void outgoing_send(const OCTETSTRING& send_par);
+	void outgoing_send(const HEXSTRING& send_par);
+	void outgoing_send(const INTEGER& send_par);
 };
 
 } /* end of namespace */
diff --git a/regression_test/portTranslation/PT2.cc b/regression_test/portTranslation/PT2.cc
index 096f62da2c8fc37200e3f1dd4e98a06b0aae9817..e68cf3d33c61754f2832d39aa4146fb5023f9e0d 100644
--- a/regression_test/portTranslation/PT2.cc
+++ b/regression_test/portTranslation/PT2.cc
@@ -87,5 +87,10 @@ void PT2::outgoing_send(const BITSTRING& /*send_par*/)
 
 }
 
+void PT2::outgoing_send(const HEXSTRING& /*send_par*/)
+{
+
+}
+
 } /* end of namespace */
 
diff --git a/regression_test/portTranslation/PT2.hh b/regression_test/portTranslation/PT2.hh
index 504c09268f0cc0a2bfb3e192d2632b560a082724..613efe348e56fad4845d96ec1174f0cf6c6bda27 100644
--- a/regression_test/portTranslation/PT2.hh
+++ b/regression_test/portTranslation/PT2.hh
@@ -42,6 +42,7 @@ protected:
 	void outgoing_send(const MyRec& send_par);
 	void outgoing_send(const OCTETSTRING& send_par);
 	void outgoing_send(const BITSTRING& send_par);
+	void outgoing_send(const HEXSTRING& send_par);
 };
 
 } /* end of namespace */
diff --git a/regression_test/portTranslation/PortTranslation.ttcn b/regression_test/portTranslation/PortTranslation.ttcn
index fbf89f62d9b0d0b034990f534cbf6fb77c5be6de..a628adc6bbe20752e1485aa0e73676438617ac74 100644
--- a/regression_test/portTranslation/PortTranslation.ttcn
+++ b/regression_test/portTranslation/PortTranslation.ttcn
@@ -13,12 +13,12 @@ module PortTranslation {
 
 /* Converter functions */
 
-	// Temporarily if the out param of the mapping functions are unbound it will
-	// try the next one in order
-
 	function MyRec_to_oct(in MyRec i, out octetstring j) {
 		if (i.types == Oct) {
 			j := i.val;
+			port.setstate(0, "Some message"); // translated
+		} else {
+			port.setstate(1); // not translated
 		}
 	} with {
 		extension "prototype(fast)";
@@ -27,6 +27,9 @@ module PortTranslation {
 	function MyRec_to_int(in MyRec i, out integer j) {
 		if (i.types == Int) {
 			j := oct2int(i.val);
+			port.setstate(0); // translated
+		} else {
+			port.setstate(1); // not translated
 		}
 	} with {
 		extension "prototype(fast)";
@@ -35,6 +38,9 @@ module PortTranslation {
 	function MyRec_to_MyRec(in MyRec i, out MyRec j) {
 		if (i.types == MyRec) {
 			j := i;
+			port.setstate(0); // translated
+		} else {
+			port.setstate(1); // not translated
 		}
 	} with {
 		extension "prototype(fast)";
@@ -43,6 +49,9 @@ module PortTranslation {
 	function MyRec_to_char(in MyRec i, out charstring j) {
 		if (i.types == Char) {
 			j := oct2str(i.val);
+			port.setstate(0); // translated
+		} else {
+			port.setstate(1); // not translated
 		}
 	} with {
 		extension "prototype(fast)";
@@ -51,6 +60,9 @@ module PortTranslation {
 	function char_to_hex(in charstring i, out hexstring j) {
 		if (i == "0001") {
 			j := str2hex(i);
+			port.setstate(0); // translated
+		} else {
+			port.setstate(1); // not translated
 		}
 	} with {
 		extension "prototype(fast)";
@@ -59,6 +71,9 @@ module PortTranslation {
 	function char_to_hex2(in charstring i, out hexstring j) {
 		if (i == "0002") {
 			j := str2hex(i);
+			port.setstate(0); // translated
+		} else {
+			port.setstate(1); // not translated
 		}
 	} with {
 		extension "prototype(fast)";
@@ -67,6 +82,9 @@ module PortTranslation {
 	function char_to_char(in charstring i, out charstring j) {
 		if (i == oct2char('010203'O)) {
 			j := "";
+			port.setstate(0); // translated
+		} else {
+			port.setstate(1); // not translated
 		}
 	} with {
 		extension "prototype(fast)";
@@ -75,11 +93,40 @@ module PortTranslation {
 	function MyRec_to_hex(in MyRec i, out hexstring j) {
 		if (i.types == Hex) {
 			j := oct2hex(i.val);
+			port.setstate(0); // translated
+		} else {
+			port.setstate(1); // not translated
+		}
+	} with {
+		extension "prototype(fast)";
+	}
+
+	function hex_to_bit(in hexstring i, out bitstring j) {
+		if (lengthof(i) > 4) {
+			j := hex2bit(substr(i, 0, 4));
+			i := substr(i, 4, lengthof(i)-4);
+			port.setstate(3); // partially translated, more messages to decode
+		} else {
+			j := hex2bit(substr(i, 0, lengthof(i)));
+			port.setstate(0); // translated
 		}
 	} with {
 		extension "prototype(fast)";
 	}
 
+	function hex_to_char(in hexstring i, out charstring j) {
+		// dummy
+	} with {
+		extension "prototype(fast)";
+	}
+
+	function int_to_bit_bad(in integer i, out bitstring j) {
+		// do nothing.
+		// Will generate error because the state of the port stays unset.
+	} with {
+		extension "prototype(fast)";
+	}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 	/* Types */
@@ -110,7 +157,7 @@ module PortTranslation {
 
 	type port P3 message {
 		out MyRec
-		out bitstring
+		out bitstring, hexstring, integer
 		inout octetstring
 	}
 
@@ -120,6 +167,7 @@ module PortTranslation {
 		out MyRec to octetstring with MyRec_to_oct() : integer with MyRec_to_int() : MyRec with MyRec_to_MyRec() : charstring with MyRec_to_char() : hexstring with MyRec_to_hex()
 		out octetstring
 		inout bitstring
+		out hexstring to bitstring with hex_to_bit() : charstring with hex_to_char()
 	}
 
 
@@ -409,6 +457,20 @@ module PortTranslation {
 		t.stop;
 	}
 
+	testcase tc_send_partially_translated() runs on MyComp system System {
+		map(self:p, system:p1);
+		var hexstring hs := '12345678ABCDEF'H;
+		p.send(hs);
+		// TODO: wait for port variables
+	}
+
+	testcase tc_send_fragmented() runs on MyComp system System {
+		map(self:p, system:p1);
+		var hexstring hs := '12345678ABCDEF'H;
+		p.send(hs);
+		// TODO: wait for port variables
+	}
+
 
 	control {
 		execute(tc_send())
@@ -418,6 +480,9 @@ module PortTranslation {
 		execute(tc_receive2());
 
 		execute(tc_send_and_receive_without_mapping());
+
+		//execute(tc_send_partially_translated());
+		//execute(tc_send_fragmented());
 	}
 
 }
\ No newline at end of file
diff --git a/regression_test/portTranslation/Setstate_neg.ttcn b/regression_test/portTranslation/Setstate_neg.ttcn
new file mode 100644
index 0000000000000000000000000000000000000000..5bc69d32a4fe225845a9e6007c0bfe7390e7c097
--- /dev/null
+++ b/regression_test/portTranslation/Setstate_neg.ttcn
@@ -0,0 +1,126 @@
+/******************************************************************************
+ * Copyright (c) 2000-2017 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:
+ *   Szabo, Bence Janos
+ *
+ ******************************************************************************/
+module Setstate_neg {
+
+	function int_to_char_bad(in integer i, out charstring j) {
+		if (i == -1) {
+			port.setstate(i);
+		} else {
+			port.setstate(1); // Not translated
+		}
+	} with {
+		extension "prototype(fast)";
+	}
+
+	function int_to_char_bad2(in integer i, out charstring j) {
+		if (i == 4) {
+			port.setstate(i);
+		} else {
+			port.setstate(1); // Not translated
+		}
+	} with {
+		extension "prototype(fast)";
+	}
+
+	function int_to_char_bad3(in integer i, out charstring j) {
+		if (i != 5) {
+			port.setstate(1); // Not translated
+		}
+		// otherwise the state will remain unset which will cause an error.
+	} with {
+		extension "prototype(fast)";
+	}
+
+	function int_to_char(in integer i, out charstring j) {
+		j := "abc";
+		port.setstate(0); // translated
+	} with {
+		extension "prototype(fast)";
+	}
+
+	/* Types */
+
+	type port NP1 message {
+		out charstring
+	} with {
+		extension "provider"
+	}
+
+	type port NPT2 message map to NP1 {
+		out integer to charstring with int_to_char_bad() : charstring with int_to_char_bad2() : charstring with int_to_char_bad3() : charstring with int_to_char()
+	}
+
+
+	type component MyComp {
+		port NPT2 p;
+	}
+
+	type component System {
+		port NP1 p1
+	}
+
+
+	testcase tc_setstate_neg_test() runs on MyComp system System {
+		map(self:p, system:p1);
+		@try {
+			p.send(-1);
+			setverdict(fail);
+		} @catch(e) {
+			if (match(e, "Dynamic test case error: The value of the first parameter in the setstate operation must be 0, 1, 2 or 3.")) {
+				setverdict(pass);
+			} else {
+				setverdict(fail);
+			}
+		}
+
+		@try {
+			p.send(4);
+			setverdict(fail);
+		} @catch(e) {
+			if (match(e, "Dynamic test case error: The value of the first parameter in the setstate operation must be 0, 1, 2 or 3.")) {
+				setverdict(pass);
+			} else {
+				setverdict(fail);
+			}
+		}
+
+		@try {
+			p.send(5);
+			setverdict(fail);
+		} @catch(e) {
+			if (match(e, "Dynamic test case error: The state of the port p remained unset after the mapping function @Setstate_neg.int_to_char_bad3 finished.")) {
+				setverdict(pass);
+			} else {
+				setverdict(fail);
+			}
+		}
+
+		@try {
+			var charstring cs;
+			int_to_char(4, cs);
+			setverdict(fail);
+		} @catch(e) {
+			if (match(e, "Dynamic test case error: setstate operation was called without being in a translation procedure.")) {
+				setverdict(pass);
+			} else {
+				setverdict(fail);
+			}
+		}
+
+		// Will be successful
+		p.send(6);
+	}
+
+	control {
+		execute(tc_setstate_neg_test());
+	}
+}
\ No newline at end of file
diff --git a/regression_test/portTranslation/config.cfg b/regression_test/portTranslation/config.cfg
index cb3e7ee1b8d66fbce3bf42b86b5fcd3cdc368919..c4e964a2b01d626b6235f99583c6e01a3ec14475 100644
--- a/regression_test/portTranslation/config.cfg
+++ b/regression_test/portTranslation/config.cfg
@@ -11,3 +11,4 @@
 ###############################################################################
 [EXECUTE]
 PortTranslation.control
+Setstate_neg.control