diff --git a/compiler2/AST.cc b/compiler2/AST.cc
index d448f0ce336307f094599e4c9c636d5bdb4689e1..88ffb738d6cae82f220fcb5e0d99a5e13420a856 100644
--- a/compiler2/AST.cc
+++ b/compiler2/AST.cc
@@ -1927,6 +1927,11 @@ namespace Common {
   {
     return 0;
   }
+  
+  Type *Assignment::get_PortType()
+  {
+    return 0;
+  }
 
   void Assignment::chk_ttcn_id()
   {
diff --git a/compiler2/AST.hh b/compiler2/AST.hh
index 0be4137b53bae36aea0aa6fe77b275c71d189716..9a5b303ff1ff39a53a654807524a2a91f65ac5a5 100644
--- a/compiler2/AST.hh
+++ b/compiler2/AST.hh
@@ -18,6 +18,7 @@
  *   Kovacs, Ferenc
  *   Raduly, Csaba
  *   Szabados, Kristof
+ *   Szabo, Bence Janos
  *   Szabo, Janos Zoltan – initial implementation
  *   Szalai, Gabor
  *   Zalanyi, Balazs Andor
@@ -588,6 +589,9 @@ namespace Common {
     /** Returns the component type referred by the 'runs on' clause of a
      * TTCN-3 definition */
     virtual Type *get_RunsOnType();
+    /** Returns the port type referred by the 'port' clause of a
+     * TTCN-3 function definition */
+    virtual Type *get_PortType();
     /** Semantic check */
     virtual void chk() = 0;
     /** Checks whether the assignment has a valid TTCN-3 identifier,
diff --git a/compiler2/Setting.cc b/compiler2/Setting.cc
index 5dc5c31a3332213dd5f4b006b3c3bc1b94a05a7f..3f4a4158ec9afb4bd28582a72971b86891093d82 100644
--- a/compiler2/Setting.cc
+++ b/compiler2/Setting.cc
@@ -18,6 +18,7 @@
  *   Kovacs, Ferenc
  *   Raduly, Csaba
  *   Szabados, Kristof
+ *   Szabo, Bence Janos
  *   Szabo, Janos Zoltan – initial implementation
  *   Tatarka, Gabor
  *
@@ -571,6 +572,12 @@ namespace Common {
     if (parent_scope) return parent_scope->get_scope_runs_on();
     else return 0;
   }
+  
+  Ttcn::PortScope *Scope::get_scope_port()
+  {
+    if (parent_scope) return parent_scope->get_scope_port();
+    else return 0;
+  }
 
   Assignments *Scope::get_scope_asss()
   {
diff --git a/compiler2/Setting.hh b/compiler2/Setting.hh
index 1c84988b88f90b522cdd7b5ec6e17316a02acca8..3a1a11c6132a4b44a5f81d5cc885747b371efb35 100644
--- a/compiler2/Setting.hh
+++ b/compiler2/Setting.hh
@@ -18,6 +18,7 @@
  *   Kovacs, Ferenc
  *   Raduly, Csaba
  *   Szabados, Kristof
+ *   Szabo, Bence Janos
  *   Szabo, Janos Zoltan – initial implementation
  *   Tatarka, Gabor
  *   Zalanyi, Balazs Andor
@@ -55,6 +56,7 @@ namespace Ttcn {
   class FieldOrArrayRefs;
   class ActualParList;
   class RunsOnScope;
+  class PortScope;
   class StatementBlock;
   struct ErroneousDescriptor;
   class ErroneousDescriptors;
@@ -597,6 +599,9 @@ public:
     /** Returns the scope unit of the hierarchy that belongs to a
      * 'runs on' clause. */
     virtual Ttcn::RunsOnScope *get_scope_runs_on();
+    /** Returns the scope unit of the hierarchy that belongs to a
+     * 'port' clause. */
+    virtual Ttcn::PortScope *get_scope_port();
     /** Returns the assignments/module definitions scope. */
     virtual Assignments *get_scope_asss();
     /** Gets the module scope. This function returns this scope or a
diff --git a/compiler2/Type.cc b/compiler2/Type.cc
index 1885e5d2f99e7d05257bb9c3fba12bd0a1264f3e..cdb774e41af243d50eaaf74ce3bf1a68e6e55c5c 100644
--- a/compiler2/Type.cc
+++ b/compiler2/Type.cc
@@ -4556,7 +4556,7 @@ namespace Common {
             maps = encode ? maps : inmaps;
             maps->set_my_scope(this->get_my_scope());
             // The first param should be true, the other is not important if the first is true
-            maps->chk(true, false);
+            maps->chk(this, true, false);
             // look for coding settings
             t = encode ? this : Type::get_pooltype(T_BSTR);
             mapping = maps->get_mapping_byType(t);
diff --git a/compiler2/Type.hh b/compiler2/Type.hh
index 1715ce1ff14d1dda8b69a292e63fe73deea1cb4a..cb886ab93925ab2f4d56d8de0a24684278a81779 100644
--- a/compiler2/Type.hh
+++ b/compiler2/Type.hh
@@ -259,6 +259,7 @@ namespace Common {
       OT_OCFT, ///< another Type (T_OCFT), ASN.1 obj.class field type
       OT_TEMPLATE_INST, ///< a TemplateInstance (TTCN-3)
       OT_RUNSON_SCOPE, ///< a RunsOnScope (TTCN-3)
+      OT_PORT_SCOPE, ///< a port scope
       OT_EXC_SPEC, ///< exception Specification (ExcSpec)
       OT_SIG_PAR, ///< signature parameter (SignatureParam)
       OT_POOL ///< It's a pool type, owned by the type pool
diff --git a/compiler2/ttcn3/AST_ttcn3.cc b/compiler2/ttcn3/AST_ttcn3.cc
index d15eab0d55bf2209f894f652fb448ccb14bc53ca..d568e92c78e9af2c07e1f7d7e5011ee5b1906f75 100644
--- a/compiler2/ttcn3/AST_ttcn3.cc
+++ b/compiler2/ttcn3/AST_ttcn3.cc
@@ -1212,6 +1212,77 @@ namespace Ttcn {
       || parent_scope->has_ass_withId(p_id);
   }
   
+  // =================================
+  // ===== PortScope
+  // =================================
+
+  PortScope::PortScope(Type *p_porttype)
+    : Scope(), port_type(p_porttype)
+  {
+    if (!p_porttype || p_porttype->get_typetype() != Type::T_PORT)
+      FATAL_ERROR("PortScope::PortScope()");
+    port_type->set_ownertype(Type::OT_PORT_SCOPE, this);
+    PortTypeBody* ptb = p_porttype->get_PortBody();
+    if (!ptb)
+      FATAL_ERROR("PortScope::PortScope()");
+    vardefs = ptb->get_vardefs();
+    set_scope_name("port `" + p_porttype->get_fullname() + "'");
+  }
+
+  PortScope *PortScope::clone() const
+  {
+    FATAL_ERROR("PortScope::clone()");
+  }
+
+  void PortScope::chk_uniq()
+  {
+    if (!vardefs) return;
+    if (vardefs->get_nof_asss() == 0) return;
+    // do not perform this check if the port type is defined in the same
+    // module as the 'port' clause
+    if (parent_scope->get_scope_mod() == vardefs->get_scope_mod())
+      return;
+    
+    size_t nof_defs = vardefs->get_nof_asss();
+    for (size_t i = 0; i < nof_defs; i++) {
+      Common::Assignment *vardef = vardefs->get_ass_byIndex(i);
+      const Identifier& id = vardef->get_id();
+      if (parent_scope->has_ass_withId(id)) {
+        vardef->warning("Imported port element definition `%s' hides a "
+          "definition at module scope", vardef->get_fullname().c_str());
+        Reference ref(0, id.clone());
+        Common::Assignment *hidden_ass = parent_scope->get_ass_bySRef(&ref);
+        hidden_ass->warning("Hidden definition `%s' is here",
+          hidden_ass->get_fullname().c_str());
+      }
+    }
+  }
+
+  PortScope *PortScope::get_scope_port()
+  {
+    return this;
+  }
+
+  Common::Assignment *PortScope::get_ass_bySRef(Ref_simple *p_ref)
+  {
+    if (!p_ref) FATAL_ERROR("Ttcn::PortScope::get_ass_bySRef()");
+    if (p_ref->get_modid()) return parent_scope->get_ass_bySRef(p_ref);
+    else {
+      const Identifier& id = *p_ref->get_id();
+      if (vardefs->has_local_ass_withId(id)) {
+        Common::Assignment* ass = vardefs->get_local_ass_byId(id);
+        if (!ass) FATAL_ERROR("Ttcn::PortScope::get_ass_bySRef()");
+        return ass;
+      } else return parent_scope->get_ass_bySRef(p_ref);
+    }
+  }
+
+  bool PortScope::has_ass_withId(const Identifier& p_id)
+  {
+    return vardefs->has_ass_withId(p_id)
+      || parent_scope->has_ass_withId(p_id);
+  }
+
   // =================================
   // ===== FriendMod
   // =================================
@@ -2238,6 +2309,9 @@ namespace Ttcn {
     for (size_t i = 0; i < runs_on_scopes.size(); i++)
       delete runs_on_scopes[i];
     runs_on_scopes.clear();
+    for (size_t i = 0; i < port_scopes.size(); i++)
+      delete port_scopes[i];
+    port_scopes.clear();
     delete w_attrib_path;
   }
 
@@ -2766,7 +2840,15 @@ namespace Ttcn {
     ret_val->chk_uniq();
     return ret_val;
   }
-
+  
+  PortScope *Module::get_port_scope(Type *porttype)
+  {
+    PortScope *ret_val = new PortScope(porttype);
+    port_scopes.add(ret_val);
+    ret_val->set_parent_scope(asss);
+    ret_val->chk_uniq();
+    return ret_val;
+  }
 
   void Module::dump(unsigned level) const
   {
@@ -6178,13 +6260,15 @@ namespace Ttcn {
   // =================================
 
   Def_Function::Def_Function(Identifier *p_id, FormalParList *p_fpl,
-                             Reference *p_runs_on_ref, Type *p_return_type,
+                             Reference *p_runs_on_ref, Reference *p_port_ref,
+                             Type *p_return_type,
                              bool returns_template,
                              template_restriction_t p_template_restriction,
                              StatementBlock *p_block)
     : Def_Function_Base(false, p_id, p_fpl, p_return_type, returns_template,
         p_template_restriction),
-        runs_on_ref(p_runs_on_ref), runs_on_type(0), block(p_block),
+        runs_on_ref(p_runs_on_ref), runs_on_type(0),
+        port_ref(p_port_ref), port_type(0), block(p_block),
         is_startable(false), transparent(false)
   {
     if (!p_block) FATAL_ERROR("Def_Function::Def_Function()");
@@ -6194,6 +6278,7 @@ namespace Ttcn {
   Def_Function::~Def_Function()
   {
     delete runs_on_ref;
+    delete port_ref;
     delete block;
   }
 
@@ -6206,6 +6291,7 @@ namespace Ttcn {
   {
     Def_Function_Base::set_fullname(p_fullname);
     if (runs_on_ref) runs_on_ref->set_fullname(p_fullname + ".<runs_on_type>");
+    if (port_ref) port_ref->set_fullname(p_fullname + ".<port_type>");
     block->set_fullname(p_fullname + ".<statement_block>");
   }
 
@@ -6216,6 +6302,7 @@ namespace Ttcn {
 
     Def_Function_Base::set_my_scope(&bridgeScope);
     if (runs_on_ref) runs_on_ref->set_my_scope(&bridgeScope);
+    if (port_ref) port_ref->set_my_scope(&bridgeScope);
     block->set_my_scope(fp_list);
   }
 
@@ -6224,6 +6311,12 @@ namespace Ttcn {
     if (!checked) chk();
     return runs_on_type;
   }
+  
+  Type *Def_Function::get_PortType()
+  {
+    if (!checked) chk();
+    return port_type;
+  }
 
   RunsOnScope *Def_Function::get_runs_on_scope(Type *comptype)
   {
@@ -6232,12 +6325,23 @@ namespace Ttcn {
     return my_module->get_runs_on_scope(comptype);
   }
   
+  PortScope *Def_Function::get_port_scope(Type *porttype)
+  {
+    Module *my_module = dynamic_cast<Module*>(my_scope->get_scope_mod());
+    if (!my_module) FATAL_ERROR("Def_Function::get_port_scope()");
+    return my_module->get_port_scope(porttype);
+  }
+
   void Def_Function::chk()
   {
     if (checked) return;
     checked = true;
     Error_Context cntxt(this, "In function definition `%s'",
       id->get_dispname().c_str());
+    // `runs on' clause and `port' clause are mutually exclusive
+    if (runs_on_ref && port_ref) {
+      runs_on_ref->error("A `runs on' and a `port' clause cannot be present at the same time.");
+    }
     // checking the `runs on' clause
     if (runs_on_ref) {
       Error_Context cntxt2(runs_on_ref, "In `runs on' clause");
@@ -6249,39 +6353,7 @@ namespace Ttcn {
         fp_list->set_my_scope(runs_on_scope);
       }
     }
-    // checking the formal parameter list
-    fp_list->chk(asstype);
-    // checking of return type
-    if (return_type) {
-      Error_Context cntxt2(return_type, "In return type");
-      return_type->chk();
-      return_type->chk_as_return_type(asstype == A_FUNCTION_RVAL,"function");
-    }
-    // decision of startability
-    is_startable = runs_on_ref != 0;
-    if (is_startable && !fp_list->get_startability()) is_startable = false;
-    if (is_startable && return_type && return_type->is_component_internal())
-          is_startable = false;
-    // checking of statement block
-    block->chk();
-    if (return_type) {
-      // checking the presence of return statements
-      switch (block->has_return()) {
-      case StatementBlock::RS_NO:
-        error("The function has return type, but it does not have any return "
-          "statement");
-        break;
-      case StatementBlock::RS_MAYBE:
-            error("The function has return type, but control might leave it "
-          "without reaching a return statement");
-      default:
-        break;
-      }
-    }
-    if (!semantic_check_only) {
-      fp_list->set_genname(get_genname());
-      block->set_code_section(GovernedSimple::CS_INLINE);
-    }
+    
     if (w_attrib_path) {
       w_attrib_path->chk_global_attrib();
       w_attrib_path->chk_no_qualif();
@@ -6325,8 +6397,65 @@ namespace Ttcn {
       }
     }
     chk_prototype();
+    
+    // checking the `port' clause
+   if (port_ref) {
+      Error_Context cntxt2(port_ref, "In `port' clause");
+      Assignment *ass = port_ref->get_refd_assignment();
+      if (ass) {
+        port_type = ass->get_Type();
+        if (port_type) {
+          switch (port_type->get_typetype()) {
+            case Type::T_PORT: {
+              Scope *port_scope = get_port_scope(port_type);
+              port_scope->set_parent_scope(my_scope);
+              fp_list->set_my_scope(port_scope);
+              break; }
+            default:
+              port_ref->error(
+                "Reference `%s' does not refer to a port type.",
+                port_ref->get_dispname().c_str());
+          }
+        } else {
+          FATAL_ERROR("Def_Function::chk()");
+        }
+      }
+    }
+    // checking the formal parameter list
+    fp_list->chk(asstype);
+    // checking of return type
+    if (return_type) {
+      Error_Context cntxt2(return_type, "In return type");
+      return_type->chk();
+      return_type->chk_as_return_type(asstype == A_FUNCTION_RVAL,"function");
+    }
+    // decision of startability
+    is_startable = runs_on_ref != 0;
+    if (is_startable && !fp_list->get_startability()) is_startable = false;
+    if (is_startable && return_type && return_type->is_component_internal())
+          is_startable = false;
+    // checking of statement block
+    block->chk();
+    if (return_type) {
+      // checking the presence of return statements
+      switch (block->has_return()) {
+      case StatementBlock::RS_NO:
+        error("The function has return type, but it does not have any return "
+          "statement");
+        break;
+      case StatementBlock::RS_MAYBE:
+            error("The function has return type, but control might leave it "
+          "without reaching a return statement");
+      default:
+        break;
+      }
+    }
+    if (!semantic_check_only) {
+      fp_list->set_genname(get_genname());
+      block->set_code_section(GovernedSimple::CS_INLINE);
+    }
   }
-
+    
   bool Def_Function::chk_startable()
   {
     if (!checked) chk();
@@ -6346,8 +6475,14 @@ namespace Ttcn {
     return false;
   }
 
-  void Def_Function::generate_code(output_struct *target, bool)
+  void Def_Function::generate_code(output_struct *target, bool clean_up)
   {
+    // Functions with 'port' clause are generated into the port type's class def
+    // Reuse of clean_up variable to allow or disallow the generation.
+    // clean_up is true when it is called from PortTypeBody::generate_code())
+    if (port_type && !clean_up) {
+      return;
+    }
     transparency_holder glass(*this);
     const string& t_genname = get_genname();
     const char *genname_str = t_genname.c_str();
@@ -6384,15 +6519,21 @@ namespace Ttcn {
     fp_list->generate_code_defval(target);
     // function prototype
     target->header.function_prototypes =
-      mputprintf(target->header.function_prototypes, "extern %s %s(%s);\n",
+      mputprintf(target->header.function_prototypes, "%s%s %s(%s);\n",
+        get_PortType() && clean_up ? "" : "extern ",
         return_type_str, genname_str, formal_par_list);
 
     // function body    
     target->source.function_bodies = mputprintf(target->source.function_bodies,
-      "%s %s(%s)\n"
+      "%s %s%s%s%s(%s)\n"
       "{\n"
       "%s"
-      "}\n\n", return_type_str, genname_str, formal_par_list, body);
+      "}\n\n",
+      return_type_str,
+      port_type && clean_up ? port_type->get_genname_own().c_str() : "",
+      port_type && clean_up && port_type->get_PortBody()->get_testport_type() != PortTypeBody::TP_INTERNAL ? "_BASE" : "",
+      port_type && clean_up ? "::" : "",
+      genname_str, formal_par_list, body);
     Free(formal_par_list);
     Free(body);
 
diff --git a/compiler2/ttcn3/AST_ttcn3.hh b/compiler2/ttcn3/AST_ttcn3.hh
index de7ac9ffa53477fc2b0e5dd69e83e924cb139391..85d246bfd0b1945d4076c7835f9031023ea06cc9 100644
--- a/compiler2/ttcn3/AST_ttcn3.hh
+++ b/compiler2/ttcn3/AST_ttcn3.hh
@@ -457,6 +457,37 @@ namespace Ttcn {
     virtual Common::Assignment *get_ass_bySRef(Ref_simple *p_ref);
     virtual bool has_ass_withId(const Identifier& p_id);
   };
+  
+  /**
+   * Class Ttcn::PortScope.
+   * Implements the scoping rules for functions that
+   * have a 'port' clause. First looks for the variable definitions in the given
+   * port type first then it searches in its parent scope.
+   * Note: This scope unit cannot access the parent scope of the port type.
+   */
+  class PortScope : public Scope {
+    /** Points to the port type. */
+    Type *port_type;
+    /** Shortcut to the definitions within \a port_type. */
+    Definitions *vardefs;
+
+    /** Not implemented. Causes \a FATAL_ERROR. */
+    PortScope(const PortScope& p);
+    /** %Assignment not implemented */
+    PortScope& operator=(const PortScope& p);
+  public:
+    PortScope(Type *p_porttype);
+    virtual PortScope *clone() const;
+
+    Type *get_port_type() const { return port_type; }
+    /** Checks the uniqueness of definitions within \a portdefs and
+     * reports warnings in case of hiding. */
+    void chk_uniq();
+
+    virtual PortScope *get_scope_port();
+    virtual Common::Assignment *get_ass_bySRef(Ref_simple *p_ref);
+    virtual bool has_ass_withId(const Identifier& p_id);
+  };
 
   /**
    * Class Ttcn::Definitions.
@@ -599,8 +630,9 @@ namespace Ttcn {
     Imports *imp;
     ControlPart* controlpart;
     /** For caching the scope objects that are created in
-     * \a get_runs_on_scope(). */
+     * \a get_runs_on_scope() and get_port_scope(). */
     vector<RunsOnScope> runs_on_scopes;
+    vector<PortScope> port_scopes;
   private:
     /** Copy constructor not implemented */
     Module(const Module& p);
@@ -638,6 +670,10 @@ namespace Ttcn {
      * object has been created for a component type it will be returned later
      * instead of creating a new one. */
     RunsOnScope *get_runs_on_scope(Type *comptype);
+    /* The same as get_runs_on_scope except that the returned scope can access
+     * the port types definitions.
+     */
+    PortScope *get_port_scope(Type *porttype);
     virtual void dump(unsigned level) const;
     void set_language_spec(const char *p_language_spec);
     void add_ass(Definition* p_ass);
@@ -858,7 +894,6 @@ namespace Ttcn {
       : Common::Assignment(p), genname(), parentgroup(0),
         w_attrib_path(0), erroneous_attrs(0), local_scope(false)
       { }
-    virtual string get_genname() const;
 
     namedbool has_implicit_omit_attr() const;
   private:
@@ -879,13 +914,14 @@ namespace Ttcn {
     /** Marks the (template) definition as local to a func/altstep/default */
     inline void set_local() { local_scope = true; }
 
+    virtual string get_genname() const;
     void set_genname(const string& p_genname) { genname = p_genname; }
     /** Check if two definitions are (almost) identical, the type and dimensions
      * must always be identical, the initial values can be different depending
      * on the definition type. If error was reported the return value is false.
      * The initial values (if applicable) may be present/absent, different or
      * unfoldable. The function must be overridden to be used.
-     */
+     */ 
     virtual bool chk_identical(Definition *p_def);
     /** Parse and check the erroneous attribute data,
       * returns erroneous attributes or NULL */
@@ -1366,6 +1402,14 @@ namespace Ttcn {
      * It is NULL if the function has no 'runs on' clause or \a runs_on_ref is
      * erroneous. */
     Type *runs_on_type;
+    /** The 'port' clause (i.e. a reference to a TTCN-3 port type)
+     * It is NULL if the function has no 'port' clause. */
+    Reference *port_ref;
+    /** Points to the object describing the port type referred by
+     * 'port' clause.
+     * It is NULL if the function has no 'port' clause or \a port_ref is
+     * erroneous. */
+    Type *port_type;
     /** The body of the function */
     StatementBlock *block;
     /** Indicates whether the function is startable. That is, it can be
@@ -1389,13 +1433,15 @@ namespace Ttcn {
      * @param p_id function name
      * @param p_fpl formal parameter list
      * @param p_runs_on_ref "runs on", else NULL
+     * @param p_port_ref "port", else NULL
      * @param p_return_type return type, may be NULL
      * @param returns_template true if the return value is a template
      * @param p_template_restriction restriction type
      * @param p_block the body of the function
      */
     Def_Function(Identifier *p_id, FormalParList *p_fpl,
-                 Reference *p_runs_on_ref, Type *p_return_type,
+                 Reference *p_runs_on_ref, Reference *p_port_ref,
+                 Type *p_return_type,
                  bool returns_template,
                  template_restriction_t p_template_restriction,
                  StatementBlock *p_block);
@@ -1404,9 +1450,13 @@ namespace Ttcn {
     virtual void set_fullname(const string& p_fullname);
     virtual void set_my_scope(Scope *p_scope);
     virtual Type *get_RunsOnType();
+    virtual Type *get_PortType();
     /** Returns a scope that can access the definitions within component type
      * \a comptype and its parent is \a parent_scope.*/
     RunsOnScope *get_runs_on_scope(Type *comptype);
+    /** Returns a scope that can access the definitions within port type
+     * \a porttype and its parent is \a parent_scope.*/
+    PortScope *get_port_scope(Type *porttype);
     virtual void chk();
     /** Checks and returns whether the function is startable.
      * Reports the appropriate error message(s) if not. */
@@ -1414,6 +1464,8 @@ namespace Ttcn {
 
     bool is_transparent() const { return transparent; }
 
+    // Reuse of clean_up variable to allow or disallow the generation.
+    // clean_up is true when it is called from PortTypeBody::generate_code()
     virtual void generate_code(output_struct *target, bool clean_up = false);
     virtual void generate_code(CodeGenHelper& cgh);
     virtual void dump_internal(unsigned level) const;
diff --git a/compiler2/ttcn3/Statement.cc b/compiler2/ttcn3/Statement.cc
index b498f732c6ef89aab491fe51078e95e931c5314d..e831aba13d33f340272f2459f1e6226852a4d796 100644
--- a/compiler2/ttcn3/Statement.cc
+++ b/compiler2/ttcn3/Statement.cc
@@ -3121,10 +3121,13 @@ error:
   {
     Error_Context cntxt(this, "In function instance");
     Common::Assignment *t_ass = ref_pard->get_refd_assignment();
+    if (t_ass->get_PortType()) {
+      ref_pard->error("Function with `port' clause cannot be called directly.");
+    }
     my_sb->chk_runs_on_clause(t_ass, *ref_pard, "call");
     if (t_ass->get_Type())
       ref_pard->warning("The value returned by %s is not used",
-	t_ass->get_description().c_str());
+	      t_ass->get_description().c_str());
   }
 
   void Statement::chk_block()
diff --git a/compiler2/ttcn3/Ttcnstuff.cc b/compiler2/ttcn3/Ttcnstuff.cc
index 2d6676ae41e0f57f798545a75d670fcf9cd2315c..18c882d9c8555b784a97a89ccb4640c5dadf967b 100644
--- a/compiler2/ttcn3/Ttcnstuff.cc
+++ b/compiler2/ttcn3/Ttcnstuff.cc
@@ -375,7 +375,7 @@ namespace Ttcn {
     }
   }
 
-  void TypeMappingTarget::chk_function(Type *source_type, bool legacy, bool incoming)
+  void TypeMappingTarget::chk_function(Type *source_type, Type *port_type, bool legacy, bool incoming)
   {
     Error_Context cntxt(this, "In `function' mapping");
     Assignment *t_ass = u.func.function_ref->get_refd_assignment(false);
@@ -478,6 +478,17 @@ namespace Ttcn {
             output_type->get_typename().c_str());
         }
       }
+      
+      // Check that if the function has a port clause it matches the port type
+      // that it is defined in.
+      Type *port_clause = u.func.function_ptr->get_PortType();
+      if (!legacy && port_clause && port_clause != port_type) {
+        u.func.function_ref->error("The function %s has a port clause of `%s'"
+          " but referenced in another port `%s'",
+          u.func.function_ptr->get_description().c_str(),
+          port_type->get_dispname().c_str(),
+          port_clause->get_dispname().c_str());
+      }
     }
   }
 
@@ -517,7 +528,7 @@ namespace Ttcn {
     if (u.encdec.eb_list) u.encdec.eb_list->chk();
   }
 
-  void TypeMappingTarget::chk(Type *source_type, bool legacy, bool incoming)
+  void TypeMappingTarget::chk(Type *source_type, Type *port_type, bool legacy, bool incoming)
   {
     if (checked) return;
     checked = true;
@@ -532,7 +543,7 @@ namespace Ttcn {
     case TM_DISCARD:
       break;
     case TM_FUNCTION:
-      chk_function(source_type, legacy, incoming);
+      chk_function(source_type, port_type, legacy, incoming);
       break;
     case TM_ENCODE:
       chk_encode(source_type);
@@ -726,7 +737,7 @@ namespace Ttcn {
     targets->set_my_scope(p_scope);
   }
 
-  void TypeMapping::chk(bool legacy, bool incoming)
+  void TypeMapping::chk(Type *port_type, bool legacy, bool incoming)
   {
     Error_Context cntxt(this, "In type mapping");
     {
@@ -737,7 +748,7 @@ namespace Ttcn {
     bool has_sliding = false, has_non_sliding = false;
     for (size_t i = 0; i < nof_targets; i++) {
       TypeMappingTarget *target = targets->get_target_byIndex(i);
-      target->chk(source_type, legacy, incoming);
+      target->chk(source_type, port_type, legacy, incoming);
       if (nof_targets > 1) {
         switch (target->get_mapping_type()) {
         case TypeMappingTarget::TM_DISCARD:
@@ -862,14 +873,14 @@ namespace Ttcn {
     return mappings_m[p_type->get_typename()];
   }
 
-  void TypeMappings::chk(bool legacy, bool incoming)
+  void TypeMappings::chk(Type *port_type, bool legacy, bool incoming)
   {
     if (checked) return;
     checked = true;
     size_t nof_mappings = mappings_v.size();
     for (size_t i = 0; i < nof_mappings; i++) {
       TypeMapping *mapping = mappings_v[i];
-      mapping->chk(legacy, incoming);
+      mapping->chk(port_type, legacy, incoming);
       Type *source_type = mapping->get_source_type();
       if (source_type->get_type_refd_last()->get_typetype() != Type::T_ERROR) {
         const string& source_type_name = source_type->get_typename();
@@ -1023,7 +1034,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)
+    bool p_in_all, bool p_out_all, bool p_inout_all, Definitions *defs)
     : 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),
@@ -1031,7 +1042,7 @@ 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(), mapper_types(),
-    in_mappings(0), out_mappings(0)
+    in_mappings(0), out_mappings(0), vardefs(defs)
   {
   }
 
@@ -1052,6 +1063,7 @@ namespace Ttcn {
     mapper_types.clear();
     delete in_mappings;
     delete out_mappings;
+    delete vardefs;
   }
 
   PortTypeBody *PortTypeBody::clone() const
@@ -1073,8 +1085,8 @@ namespace Ttcn {
       provider_refs[i]->set_fullname(p_fullname + ".<provider_ref>");
     }
     if (in_mappings) in_mappings->set_fullname(p_fullname + ".<in_mappings>");
-    if (out_mappings)
-      out_mappings->set_fullname(p_fullname + ".<out_mappings>");
+    if (out_mappings) out_mappings->set_fullname(p_fullname + ".<out_mappings>");
+    vardefs->set_fullname(p_fullname + ".<port_var>");
   }
 
   void PortTypeBody::set_my_scope(Scope *p_scope)
@@ -1087,6 +1099,7 @@ 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);
   }
 
   void PortTypeBody::set_my_type(Type *p_type)
@@ -1119,6 +1132,12 @@ namespace Ttcn {
     if (!checked) FATAL_ERROR("PortTypeBody::get_out_sigs()");
     return out_sigs;
   }
+  
+  Definitions *PortTypeBody::get_vardefs() const
+  {
+    if (!checked) FATAL_ERROR("PortTypeBody::get_vardefs()");
+    return vardefs;
+  }
 
   bool PortTypeBody::has_queue() const
   {
@@ -1528,7 +1547,7 @@ namespace Ttcn {
     // checking the incoming mappings
     if (legacy && in_mappings) {
       Error_Context cntxt2(in_mappings, "In `in' mappings");
-      in_mappings->chk(legacy, true);
+      in_mappings->chk(my_type, legacy, true);
       // checking source types
       if (provider_body) {
         if (provider_body->in_msgs) {
@@ -1587,7 +1606,7 @@ namespace Ttcn {
     // checking the outgoing mappings
     if (legacy && out_mappings) {
       Error_Context cntxt2(out_mappings, "In `out' mappings");
-      out_mappings->chk(legacy, false);
+      out_mappings->chk(my_type, legacy, false);
       // checking source types
       if (out_msgs) {
         // check if all source types are present on the `out' list
@@ -1710,12 +1729,14 @@ namespace Ttcn {
     }
     if (!legacy) {
       if (out_mappings) {
-        out_mappings->chk(legacy, false);
+        out_mappings->chk(my_type, legacy, false);
       }
       if (in_mappings) {
-        in_mappings->chk(legacy, true);
+        in_mappings->chk(my_type, legacy, true);
       }
       chk_map_translation();
+      vardefs->chk_uniq();
+      vardefs->chk();
     }
   }
 
@@ -1753,6 +1774,10 @@ namespace Ttcn {
       Error_Context cntxt(inout_list, "In `inout' list");
       chk_list(inout_list, true, true);
     }
+    
+    if (provider_refs.size() == 0 && vardefs->get_nof_asss() > 0) {
+      error("Port variables can only be used when the port is a translation port.");
+    }
   }
 
   void PortTypeBody::chk_attributes(Ttcn::WithAttribPath *w_attrib_path)
@@ -1810,8 +1835,13 @@ namespace Ttcn {
           ea.warning("Duplicate attribute `provider'");
           break; }
         case PortTypeBody::PT_USER: {
+          if (legacy) {
           ea.error("Attributes `user' and `provider' "
             "cannot be used at the same time");
+          } else {
+            ea.error("The `provider' attribute "
+            "cannot be used on translation ports");
+          }
           break; }
         default:
           FATAL_ERROR("coding_attrib_parse(): invalid testport type");
@@ -1828,7 +1858,11 @@ namespace Ttcn {
             "cannot be used at the same time");
           break; }
         case PortTypeBody::PT_USER: {
-          ea.error("Duplicate attribute `user'");
+          if (legacy) {
+            ea.error("Duplicate attribute `user'");
+          } else {
+            ea.error("Attribute `user' cannot be used on translation ports.");
+          }
           break; }
         default:
           FATAL_ERROR("coding_attrib_parse(): invalid testport type");
@@ -2318,6 +2352,84 @@ namespace Ttcn {
             } // for mapping->get_nof_targets()
           } // for in_mappings->get_nof_mappings()
         } // if in_mappings // todo inout?
+        
+        // Variable declarations and definitions
+        for (size_t i = 0; i < vardefs->get_nof_asss(); i++) {
+          Definition* def = static_cast<Definition*>(vardefs->get_ass_byIndex(i));
+          string type;
+          switch (def->get_asstype()) {
+            case Assignment::A_VAR:
+            case Assignment::A_CONST:
+              type = def->get_Type()->get_genname_value(my_scope);
+              break;
+            case Assignment::A_VAR_TEMPLATE:
+              type = def->get_Type()->get_genname_template(my_scope);
+              break;
+            default:
+              FATAL_ERROR("PortTypeBody::generate_code()");
+          }
+          
+          pdef.var_decls = 
+            mputprintf(pdef.var_decls,
+              "%s %s;\n",
+              type.c_str(),
+              def->get_genname().c_str());
+
+          size_t len = pdef.var_defs ? strlen(pdef.var_defs) : 0;
+          pdef.var_defs = def->generate_code_init_comp(pdef.var_defs, def);
+          
+          // If the def does not have default value then clean it up to
+          // restore to unbound. (for constants the generate_code_init_comp does nothing)
+          if ((pdef.var_defs == NULL || len == strlen(pdef.var_defs)) && def->get_asstype() != Assignment::A_CONST) {
+            pdef.var_defs = mputprintf(pdef.var_defs, "%s.clean_up();\n",
+              def->get_genname().c_str());
+          }
+        }
+        
+        
+        // Collect the generated code of functions with 'port' clause 
+        // which belongs to this port type
+        output_struct os;
+        Code::init_output(&os);
+        map<Def_Function_Base*, int> funs;
+        if (out_mappings) {
+          for (size_t i = 0; i < out_mappings->get_nof_mappings(); i++) {
+            TypeMapping* tm = out_mappings->get_mapping_byIndex(i);
+            for (size_t j = 0; j < tm->get_nof_targets(); j++) {
+              TypeMappingTarget* tmt = tm->get_target_byIndex(j);
+              if (tmt->get_mapping_type() == TypeMappingTarget::TM_FUNCTION) {
+                Def_Function_Base* fun = tmt->get_function();
+                Type * fun_port_type = fun->get_PortType();
+                if (fun_port_type && fun_port_type == my_type && !funs.has_key(fun)) {
+                  // Reuse of clean_up parameter here.
+                  fun->generate_code(&os, true);
+                  funs.add(fun, 0);
+                }
+              }
+            }
+          }
+        }
+        if (in_mappings) {
+          for (size_t i = 0; i < in_mappings->get_nof_mappings(); i++) {
+            TypeMapping* tm = in_mappings->get_mapping_byIndex(i);
+            for (size_t j = 0; j < tm->get_nof_targets(); j++) {
+              TypeMappingTarget* tmt = tm->get_target_byIndex(j);
+              if (tmt->get_mapping_type() == TypeMappingTarget::TM_FUNCTION) {
+                Def_Function_Base* fun = tmt->get_function();
+                Type * fun_port_type = fun->get_PortType();
+                if (fun_port_type && fun_port_type == my_type && !funs.has_key(fun)) {
+                  // Reuse of clean_up parameter here.
+                  fun->generate_code(&os, true);
+                  funs.add(fun, 0);
+                }
+              }
+            }
+          }
+        }
+        pdef.mapping_func_decls = mcopystr(os.header.function_prototypes);
+        pdef.mapping_func_defs = mcopystr(os.source.function_bodies);
+        funs.clear();
+        Code::free_output(&os);
       } // if legacy
     } else {
       // "internal provider" is the same as "internal"
@@ -2337,7 +2449,7 @@ namespace Ttcn {
         pdef.mapper_name[i] = pool.add(mapper_types[i]->get_genname_value(my_scope));
       }
     }
-
+    
     defPortClass(&pdef, target);
     if (generate_skeleton && testport_type != TP_INTERNAL &&
         (port_type != PT_USER || !legacy)) generateTestPortSkeleton(&pdef);
@@ -2355,6 +2467,10 @@ namespace Ttcn {
       Free(pdef.provider_msg_outlist.elements[i].out_msg_type_names);
     Free(pdef.provider_msg_outlist.elements);
     Free(pdef.mapper_name);
+    Free(pdef.var_decls);
+    Free(pdef.var_defs);
+    Free(pdef.mapping_func_decls);
+    Free(pdef.mapping_func_defs);
   }
 
   void PortTypeBody::dump(unsigned level) const
diff --git a/compiler2/ttcn3/Ttcnstuff.hh b/compiler2/ttcn3/Ttcnstuff.hh
index 3b02f2e5f9519f83b48dc3b7d2fb21c4c5ae7420..88ecdaa39fe7eb2f744333ef7406962f52e5e686 100644
--- a/compiler2/ttcn3/Ttcnstuff.hh
+++ b/compiler2/ttcn3/Ttcnstuff.hh
@@ -180,7 +180,7 @@ private:
    *               syntax in the standard was used.
      Param incoming: true if the mapping is in the in list of port, false if the
    *                 mapping is in the out list of the port.*/
-  void chk_function(Common::Type *source_type, bool legacy, bool incoming);
+  void chk_function(Common::Type *source_type, Common::Type *port_type, bool legacy, bool incoming);
   /** Check "encode()" mapping. */
   void chk_encode(Common::Type *source_type);
   /** Check "decode()" mapping. */
@@ -190,7 +190,7 @@ public:
    *               syntax in the standard was used.
      Param incoming: true if the mapping is in the in list of port, false if the
    *                 mapping is in the out list of the port.*/
-  void chk(Common::Type *source_type, bool legacy, bool incoming);
+  void chk(Common::Type *source_type, Common::Type *port_type, bool legacy, bool incoming);
   /** Fills the appropriate data structure \a target for code generation. */
   bool fill_type_mapping_target(port_msg_type_mapping_target *target,
     Common::Type *source_type, Common::Scope *p_scope, stringpool& pool);
@@ -249,7 +249,7 @@ public:
    *               syntax in the standard was used.
      Param incoming: true if the mapping is in the in list of port, false if the
    *                 mapping is in the out list of the port.*/
-  void chk(bool legacy, bool incoming);
+  void chk(Common::Type *port_type, bool legacy, bool incoming);
   virtual void dump(unsigned level) const;
 };
 
@@ -278,7 +278,7 @@ public:
    *               syntax in the standard was used.
      Param incoming: true if the mapping is in the in list of port, false if the
    *                 mapping is in the out list of the port.*/
-  void chk(bool legacy, bool incoming);
+  void chk(Common::Type *port_type, bool legacy, bool incoming);
   virtual void dump(unsigned level) const;
 };
 
@@ -404,6 +404,7 @@ private:
   vector<Common::Type> mapper_types; ///< the types that map this port.
                                      ///< only for PT_USER && !legacy
   TypeMappings *in_mappings, *out_mappings; ///< mappings for PT_USER
+  Definitions *vardefs; ///< variable definitions inside the port
   /** Copy constructor not implemented */
   PortTypeBody(const PortTypeBody& p);
   /** Assignment disabled */
@@ -411,7 +412,7 @@ private:
 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);
+    bool p_in_all, bool p_out_all, bool p_inout_all, Definitions *defs);
   ~PortTypeBody();
   virtual PortTypeBody *clone() const;
   virtual void set_fullname(const string& p_fullname);
@@ -422,6 +423,7 @@ public:
   TypeSet *get_out_msgs() const;
   TypeSet *get_in_sigs() const;
   TypeSet *get_out_sigs() const;
+  Definitions *get_vardefs() const;
   bool has_queue() const;
   bool getreply_allowed() const;
   bool catch_allowed() const;
diff --git a/compiler2/ttcn3/compiler.y b/compiler2/ttcn3/compiler.y
index 5728f63f66a625a6290c72f7b440921d9d75eab7..a19e4d53aaa22d6bcc2ce579c4cef8077b795852 100644
--- a/compiler2/ttcn3/compiler.y
+++ b/compiler2/ttcn3/compiler.y
@@ -284,6 +284,8 @@ static const string anyname("anytype");
     Ttcn::Types *in_list, *out_list, *inout_list;
     bool in_all, out_all, inout_all;
     TypeMappings *in_mappings, *out_mappings;
+    size_t varnElements;
+    Ttcn::Definition **varElements;
   } portdefbody;
   
   struct {
@@ -1018,7 +1020,7 @@ static const string anyname("anytype");
 %type <refpard> FunctionInstance AltstepInstance
 %type <reference> PortType optDerivedDef DerivedDef IndexSpec Signature
   VariableRef TimerRef Port PortOrAll ValueStoreSpec
-  SenderSpec ComponentType optRunsOnSpec RunsOnSpec optSystemSpec
+  SenderSpec ComponentType optRunsOnSpec RunsOnSpec optSystemSpec optPortSpec
 %type <reference_or_any> PortOrAny TimerRefOrAny
 %type <valuerange> Range
 %type <type> NestedEnumDef NestedRecordDef NestedRecordOfDef NestedSetDef
@@ -1049,7 +1051,7 @@ AllOrTypeListWithTo TypeListWithFrom TypeListWithTo
 %type <def_list> AltstepLocalDef AltstepLocalDefList ComponentElementDef
   ConstDef ExtConstDef FunctionLocalDef FunctionLocalInst ModuleDef ModulePar
   ModuleParDef MultiTypedModuleParList PortInstance TimerInstance TimerList
-  VarInstance
+  VarInstance PortElementVarDef
 %type <stmt_list> FunctionStatementOrDef ControlStatementOrDef
 
 %type <rangedef> RangeDef
@@ -1500,6 +1502,7 @@ FriendModuleDef
 USI
 UIDlike
 PortTypeList
+PortElementVarDef
 
 
 %destructor {
@@ -1533,6 +1536,10 @@ StructOfDefBody
   delete $$.inout_list;
   delete $$.in_mappings;
   delete $$.out_mappings;
+  for (size_t i = 0; i < $$.varnElements; i++) {
+    delete $$.varElements[i];
+  }
+  delete $$.varElements;
 }
 PortDefList
 PortDefLists
@@ -1866,12 +1873,12 @@ optDecodedModifier
 %left '*' '/' ModKeyword RemKeyword
 %left UnarySign
 
-%expect 65
+%expect 66
 
 %start GrammarRoot
 
 /*
-XXX Source of conflicts (65 S/R):
+XXX Source of conflicts (66 S/R):
 
 1.) 9 conflicts in one state
 The Expression after 'return' keyword is optional in ReturnStatement.
@@ -1942,6 +1949,9 @@ ex.: template octetstring t := 'AB'O & ? length (3);
 Because the parser shifts, the length restriction here is applied to the '?'
 instead of the concatenation result, which is the expected behavior.
 
+12.) 1 conflict in PortDefLists
+PortElementVarDef contains optSemicolon which causes 1 conflict
+
 Note that the parser implemented by bison always chooses to shift instead of
 reduce in case of conflicts.
 */
@@ -2803,9 +2813,14 @@ PortDefBody: // 57
 PortDefAttribs: // 60
   PortOperationMode PortDefLists
   {
+    Definitions * defs = new Definitions();
+    for (size_t i = 0; i < $2.varnElements; i++) {
+      defs->add_ass($2.varElements[i]);
+    }
+    Free($2.varElements);
     PortTypeBody *body = new PortTypeBody($1,
       $2.in_list, $2.out_list, $2.inout_list,
-      $2.in_all, $2.out_all, $2.inout_all);
+      $2.in_all, $2.out_all, $2.inout_all, defs);
     body->set_location(infile, @$);
     $$ = new Type(Type::T_PORT, body);
     $$->set_location(infile, @$);
@@ -2815,9 +2830,14 @@ PortDefAttribs: // 60
 | 
   PortOperationMode MapKeyword ToKeyword PortTypeList PortDefLists
   {
+    Definitions * defs = new Definitions();
+    for (size_t i = 0; i < $5.varnElements; i++) {
+      defs->add_ass($5.varElements[i]);
+    }
+    Free($5.varElements);
     PortTypeBody *body = new PortTypeBody($1,
       $5.in_list, $5.out_list, $5.inout_list,
-      $5.in_all, $5.out_all, $5.inout_all);
+      $5.in_all, $5.out_all, $5.inout_all, defs);
     body->set_location(infile, @$);
     $$ = new Type(Type::T_PORT, body);
     body->add_user_attribute($4.elements, $4.nElements, $5.in_mappings, $5.out_mappings, false);
@@ -2845,6 +2865,8 @@ PortDefLists:
     $$.inout_all = false;
     $$.in_mappings = 0;
     $$.out_mappings = 0;
+    $$.varnElements = 0;
+    $$.varElements = 0;
   }
 ;
 
@@ -2905,6 +2927,16 @@ seqPortDefList:
         loc.warning("Duplicate directive `inout all' in port type definition");
       } else $$.inout_all = true;
     }
+    if ($2.varnElements > 0) {
+      size_t i = $$.varnElements;
+      $$.varnElements += $2.varnElements;
+      $$.varElements = static_cast<Ttcn::Definition**>(Realloc($$.varElements, $$.varnElements * sizeof(Ttcn::Definition*)));
+      // Intentional j start
+      for (size_t j = 0; i < $$.varnElements; i++, j++) {
+        $$.varElements[i] = $2.varElements[j];
+      }
+      Free($2.varElements);
+    }
   }
 ;
 
@@ -2930,6 +2962,8 @@ PortDefList:
     $$.inout_list = 0;
     $$.out_mappings = 0;
     $$.inout_all = false;
+    $$.varnElements = 0;
+    $$.varElements = 0;
   }
 | OutParKeyword AllOrTypeListWithTo
   {
@@ -2952,6 +2986,8 @@ PortDefList:
     $$.in_mappings = 0;
     $$.inout_list = 0;
     $$.inout_all = false;
+    $$.varnElements = 0;
+    $$.varElements = 0;
   }
 | InOutParKeyword AllOrTypeList
   {
@@ -2970,6 +3006,8 @@ PortDefList:
     delete $2.mappings;
     $$.in_mappings = 0;
     $$.out_mappings = 0;
+    $$.varnElements = 0;
+    $$.varElements = 0;
   }
 | InParKeyword error
   {
@@ -2981,6 +3019,8 @@ PortDefList:
     $$.inout_all = false;
     $$.in_mappings = 0;
     $$.out_mappings = 0;
+    $$.varnElements = 0;
+    $$.varElements = 0;
   }
 | OutParKeyword error
   {
@@ -2992,6 +3032,8 @@ PortDefList:
     $$.inout_all = false;
     $$.in_mappings = 0;
     $$.out_mappings = 0;
+    $$.varnElements = 0;
+    $$.varElements = 0;
   }
 | InOutParKeyword error
   {
@@ -3003,7 +3045,25 @@ PortDefList:
     $$.inout_all = false;
     $$.in_mappings = 0;
     $$.out_mappings = 0;
+    $$.varnElements = 0;
+    $$.varElements = 0;
   }
+| PortElementVarDef optSemiColon {
+    $$.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 = $1.nElements;
+    $$.varElements = static_cast<Ttcn::Definition**>(Malloc($$.varnElements * sizeof(Ttcn::Definition*)));
+    for (size_t i = 0; i < $$.varnElements; i++) {
+      $$.varElements[i] = $1.elements[i];
+    }
+    delete $1.elements;
+}
 ;
 
 WithList:
@@ -3109,6 +3169,10 @@ TypeListWithTo:
 | TypeListWithTo optError ',' error { $$ = $1; }
 ;
 
+PortElementVarDef:
+  VarInstance { $$ = $1; }
+| ConstDef { $$ = $1; }
+
 ComponentDef: // 78
   ComponentKeyword IDentifier
   optExtendsDef
@@ -4099,11 +4163,11 @@ ValueofOp: // 162
 
 FunctionDef: // 164
   FunctionKeyword optDeterministicModifier IDentifier '(' optFunctionFormalParList ')'
-  optRunsOnSpec optReturnType optError StatementBlock
+  optRunsOnSpec optPortSpec optReturnType optError StatementBlock
   {
     $5->set_location(infile, @4, @6);
-    $$ = new Def_Function($3, $5, $7, $8.type, $8.returns_template,
-                          $8.template_restriction, $10);
+    $$ = new Def_Function($3, $5, $7, $8, $9.type, $9.returns_template,
+                          $9.template_restriction, $11);
     $$->set_location(infile, @$);
   }
 ;
@@ -4190,6 +4254,12 @@ RunsOnSpec: // 171
   RunsKeyword OnKeyword ComponentType { $$ = $3; }
 ;
 
+optPortSpec:
+  /* empty */ { $$ = 0; }
+| PortKeyword Port { $$ = $2; }
+;
+
+
   /* StatementBlock changed in 4.1.2 to explicitly prevent statements
    * followed by definitions. TITAN still allows them to be mixed. */
 StatementBlock: /* StatementBlock *statementblock */ // 175
diff --git a/compiler2/ttcn3/port.c b/compiler2/ttcn3/port.c
index c4a876e2956cd049151d1dd25cc85caf10ddfe81..6f9eea304af6191d2aa791df0cd7562ff7dd4c5c 100644
--- a/compiler2/ttcn3/port.c
+++ b/compiler2/ttcn3/port.c
@@ -1654,6 +1654,26 @@ void defPortClass(const port_def* pdef, output_struct* output)
       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");
+    
+    // Declarations of port variables
+    if (pdef->var_decls != NULL) {
+      def = mputstr(def, pdef->var_decls);
+    }
+    
+    if (pdef->var_defs != NULL) {
+      def = mputstr(def, "void init_port_variables();\n");
+      src = mputprintf(src,
+        "void %s::init_port_variables() {\n%s}\n\n", class_name, pdef->var_defs);
+    }
+    
+    // Declarations of mapping function which have this port in the 'port' clause
+    if (pdef->mapping_func_decls != NULL) {
+      def = mputstr(def, pdef->mapping_func_decls);
+    }
+    
+    if (pdef->mapping_func_defs != NULL) {
+      src = mputstr(src,  pdef->mapping_func_defs);
+    }
   }
   
   // Port type variables in the provider types.
@@ -2073,19 +2093,19 @@ void defPortClass(const port_def* pdef, output_struct* output)
     // add_port and remove_port is called after the map and unmap statements.
     for (i = 0; i < pdef->provider_msg_outlist.nElements; i++) {
       def = mputprintf(def, "void add_port(%s* p);\n", pdef->provider_msg_outlist.elements[i].name);
-      src = mputprintf(src, "void %s::add_port(%s*p) {\n p_%i = p;\n}\n\n", class_name, pdef->provider_msg_outlist.elements[i].name, (int)i);
+      src = mputprintf(src, "void %s::add_port(%s*p) {\np_%i = p;\n}\n\n", class_name, pdef->provider_msg_outlist.elements[i].name, (int)i);
       
       def = mputprintf(def, "void remove_port(%s*);\n", pdef->provider_msg_outlist.elements[i].name);
-      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);
+      src = mputprintf(src, "void %s::remove_port(%s*) {\np_%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 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++) {
-      src = mputprintf(src, "p_%i != NULL %s",
+      src = mputprintf(src, "p_%i != NULL%s",
         (int)i,
-        i != pdef->provider_msg_outlist.nElements - 1 ? "|| " : "");
+        i != pdef->provider_msg_outlist.nElements - 1 ? " || " : "");
     }
     src = mputstr(src, ";\n}\n\n");
     
@@ -2103,6 +2123,7 @@ void defPortClass(const port_def* pdef, output_struct* output)
       src = mputprintf(src, "p_%i = NULL;\n", (int)i);
     }
     src = mputstr(src, "}\n\n");
+    
   }
   // Port type variables in the provider types.
   if (pdef->n_mapper_name > 0) {
diff --git a/compiler2/ttcn3/port.h b/compiler2/ttcn3/port.h
index 9258329904dec42440252edb8e6ecaadaabeacd1..795f783e187d5db647d6363618967a008976c707 100644
--- a/compiler2/ttcn3/port.h
+++ b/compiler2/ttcn3/port.h
@@ -120,6 +120,10 @@ typedef struct port_def_tag {
   port_msg_mapped_type_list provider_msg_in;
   boolean has_sliding;
   boolean legacy;
+  char *var_decls;
+  char *var_defs;
+  char *mapping_func_decls;
+  char *mapping_func_defs;
 } port_def;
 
 #ifdef __cplusplus
diff --git a/core/Port.cc b/core/Port.cc
index 7fdfc1de480e6d90698ad08fd59b47a0413c234e..3ec64918f80e644af9e7754cef8ccc876a4b74ba 100644
--- a/core/Port.cc
+++ b/core/Port.cc
@@ -2149,6 +2149,12 @@ void PORT::map(const char *system_port)
   TTCN_Logger::log_port_misc(
     TitanLoggerApi::Port__Misc_reason::port__was__mapped__to__system,
     port_name, SYSTEM_COMPREF, system_port);
+  
+  // Only has effect when the translation port has port variables with
+  // default values. Only call when it is mapped first.
+  if (n_system_mappings == 0) {
+    init_port_variables();
+  }
 
   // the mapping shall be registered in the table only if user_map() was
   // successful
@@ -2202,7 +2208,9 @@ void PORT::unmap(const char *system_port)
   // Currently the requirement is that the port needs to map only when mapped 
   // to one port. If it would be mapped to more ports then this call would
   // remove all translation capability.
-  reset_port_variables();
+  if (n_system_mappings == 0) {
+    reset_port_variables();
+  }
 
   TTCN_Logger::log_port_misc(
     TitanLoggerApi::Port__Misc_reason::port__was__unmapped__from__system,
@@ -2215,6 +2223,10 @@ void PORT::reset_port_variables() {
   
 }
 
+void PORT::init_port_variables() {
+  
+}
+
 void PORT::change_port_state(translation_port_state /*state*/) {
   
 }
diff --git a/core/Port.hh b/core/Port.hh
index f75927a288babf0373018a30bf4fe279735471b8..e89b72fcec916d07520fd0e5314ef160bcd2f7bf 100644
--- a/core/Port.hh
+++ b/core/Port.hh
@@ -302,8 +302,12 @@ protected:
   virtual boolean process_exception(const char *signature_name,
     Text_Buf& incoming_buf, component sender_component);
   
+  // Resets the port type variables to NULL after unmap
   virtual void reset_port_variables();
   
+  // Initializes the port variables after map
+  virtual void init_port_variables();
+  
 private:
   port_connection *add_connection(component remote_component,
     const char *remote_port, transport_type_enum transport_type);
diff --git a/function_test/Semantic_Analyser/port_translation/PortClause_SE.ttcn b/function_test/Semantic_Analyser/port_translation/PortClause_SE.ttcn
new file mode 100644
index 0000000000000000000000000000000000000000..b505ead3aec4f62a166bf4c37264218b155cf7ba
--- /dev/null
+++ b/function_test/Semantic_Analyser/port_translation/PortClause_SE.ttcn
@@ -0,0 +1,62 @@
+/******************************************************************************
+ * 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
+ *
+ ******************************************************************************/
+
+// Tests of standard ES 202 781 Ports with translation capability
+
+module PortClause_SE { //^In TTCN-3 module//
+
+	type component MyComp {
+
+	}
+
+	type port P1 message { //^In type definition \`P1\'\:// //^error\: Port variables can only be used when the port is a translation port\.//
+		in integer
+		var integer i := 6;
+	} with {
+		extension "provider"
+	}
+
+	type port P2 message map to P1 { //^In type definition \`P2\'\:// //^In type mapping\:// //^In \`function\' mapping\:// //^In translation capability\:// //^error\: The function function \`\@PortClause_SE\.int_to_int\' has a port clause of \`P2\' but referenced in another port \`P3\'//
+		in integer from integer with int_to_int();
+		var integer i := 6;  //^Previous definition with identifier \`i\' in higher scope unit is here//
+	}
+
+	type port P3 message {
+		in integer
+	}
+
+	function f() port MyPort { //^In function definition \`f\'\:// //^In \`port\' clause\:// //^error\: There is no local or imported definition with name \`MyPort\'//
+
+	} 
+
+	function g() port MyComp { //^In function definition \`g\'\:// //^In \`port\' clause\:// //^error\: Reference \`MyComp\' does not refer to a port type\.//
+
+	}
+
+	function h() runs on MyComp port P1 { //^In function definition \`h\'\://  //^error\: A \`runs on\' and a \`port\' clause cannot be present at the same time\.//
+
+	} 
+
+	function j() port P2 { //^In function definition \`j\'\:// 
+		var integer i := 4; //^error\: Definition with identifier \`i\' is not unique in the scope hierarchy//
+	} 
+
+	function int_to_int(in integer input, out integer output) port P3 {
+
+	} with {
+		extension "prototype(fast)"
+	}
+
+	control { //^In control part\://
+		j(); //^In function instance\:// //^error\: Function with \`port\' clause cannot be called directly\.//
+	}
+}
\ No newline at end of file
diff --git a/function_test/Semantic_Analyser/port_translation/PortTranslate_SE.ttcn b/function_test/Semantic_Analyser/port_translation/PortTranslate_SE.ttcn
index 949d45a4f1343595ab41d138c8f8f28576c6e223..bdfe868160ab24cc54f566ed5a859a881acc7047 100644
--- a/function_test/Semantic_Analyser/port_translation/PortTranslate_SE.ttcn
+++ b/function_test/Semantic_Analyser/port_translation/PortTranslate_SE.ttcn
@@ -9,6 +9,9 @@
  *   Szabo, Bence Janos
  *
  ******************************************************************************/
+
+// Tests of standard ES 202 781 Ports with translation capability
+
 module PortTranslate_SE { //^In TTCN-3 module//
 
 	type integer MyInt;
@@ -194,4 +197,16 @@ module PortTranslate_SE { //^In TTCN-3 module//
 	with {
 		extension "prototype(fast)"
 	}
+
+	type port PT16 message map to P9 { //^In type definition \`PT16\'\://
+		out hexstring
+	} with {
+		extension "provider"  //^error\: The \`provider\' attribute cannot be used on translation ports//
+	}
+
+	type port PT17 message map to P9 { //^In type definition \`PT17\'\://
+		out hexstring
+	} with {
+		extension "user P9 out(hexstring -> hexstring: simple)"; //^error\: Attribute \`user\' cannot be used on translation ports\.//
+	}
 }
\ No newline at end of file
diff --git a/function_test/Semantic_Analyser/port_translation/Setstate_SE.ttcn b/function_test/Semantic_Analyser/port_translation/Setstate_SE.ttcn
index ca283746ee34b13468da0c1cf481614aa563f280..7c1d38cd3d99f17151e71db94c927e1da60b838f 100644
--- a/function_test/Semantic_Analyser/port_translation/Setstate_SE.ttcn
+++ b/function_test/Semantic_Analyser/port_translation/Setstate_SE.ttcn
@@ -9,6 +9,9 @@
  *   Szabo, Bence Janos
  *
  ******************************************************************************/
+
+// Tests of standard ES 202 781 Ports with translation capability
+
 module Setstate_SE { //^In TTCN-3 module//
 
 	const integer i1 := 4;
diff --git a/function_test/Semantic_Analyser/xer/untagged_charenc_optional_SE.ttcn b/function_test/Semantic_Analyser/xer/untagged_charenc_optional_SE.ttcn
index a28a1a98a06c34ed16020cc1f3e68ab8f513f44a..372dace8af7d59a3f905202425db21d6b6baa5ed 100644
--- a/function_test/Semantic_Analyser/xer/untagged_charenc_optional_SE.ttcn
+++ b/function_test/Semantic_Analyser/xer/untagged_charenc_optional_SE.ttcn
@@ -39,7 +39,6 @@ type union uni {
 	variant "untagged";
 }
 
-// No top level untagged warning for unions and anytype
 external function enc_uni(in uni u) return octetstring
 with { extension "prototype(convert) encode(XER:XER_EXTENDED)" }
 
diff --git a/regression_test/portTranslation/Makefile b/regression_test/portTranslation/Makefile
index 108ffb482c566d1bcc76ef3097a497c3b0160563..315962998592ab1b80bff062c8b2500b0d64567a 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 Setstate_neg.ttcn
+TTCN3_MODULES = PortTranslation.ttcn Setstate_neg.ttcn PortVariables.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) NP1.cc NPT2.cc
+GENERATED_SOURCES = $(TTCN3_MODULES:.ttcn=.cc) $(ASN1_MODULES:.asn=.cc) NP1.cc NPT2.cc NVP1.cc
 GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh)
 ifdef SPLIT_TO_SLICES
 POSTFIXES := $(foreach file, $(SPLIT_TO_SLICES), $(addsuffix $(file), _part_))
@@ -64,7 +64,7 @@ GENERATED_SOURCES += $(GENERATED_SOURCES2)
 endif
 # C/C++ Source & header files of Test Ports, external functions and
 # other modules:
-USER_SOURCES = PT2.cc P1.cc P2.cc P3.cc
+USER_SOURCES = PT2.cc P1.cc P2.cc P3.cc VP1.cc NVP1.cc
 USER_HEADERS = $(USER_SOURCES:.cc=.hh)
 
 # Object files of this project that are needed for the executable test suite:
diff --git a/regression_test/portTranslation/PortTranslation.ttcn b/regression_test/portTranslation/PortTranslation.ttcn
index a628adc6bbe20752e1485aa0e73676438617ac74..d57dde601f8674d6e1c2e489e3e26e5996e75a7a 100644
--- a/regression_test/portTranslation/PortTranslation.ttcn
+++ b/regression_test/portTranslation/PortTranslation.ttcn
@@ -16,9 +16,9 @@ module PortTranslation {
 	function MyRec_to_oct(in MyRec i, out octetstring j) {
 		if (i.types == Oct) {
 			j := i.val;
-			port.setstate(0, "Some message"); // translated
+			port.setstate(0, "Translated"); // translated
 		} else {
-			port.setstate(1); // not translated
+			port.setstate(1, "Not translated"); // not translated
 		}
 	} with {
 		extension "prototype(fast)";
diff --git a/regression_test/portTranslation/PortVariables.ttcn b/regression_test/portTranslation/PortVariables.ttcn
new file mode 100644
index 0000000000000000000000000000000000000000..780d7231021a48259fc970921a356aa0ed05dadf
--- /dev/null
+++ b/regression_test/portTranslation/PortVariables.ttcn
@@ -0,0 +1,303 @@
+/******************************************************************************
+ * 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 PortVariables {
+
+	type record of integer RoI;
+
+	type port VP1 message {
+		out integer, charstring, RoI;
+		in integer, charstring, RoI;
+	} with {
+		extension "provider"
+	}
+
+	type port NVP1 message map to VP1 {
+		out charstring to integer with char_to_default_int_template() : charstring with char_to_default_char() : charstring with char_to_default_const_char() : RoI with char_to_default_roi() : integer with char_to_int();
+		in integer, charstring, RoI;
+
+		const charstring c_cs := "DefaultConst"
+		var charstring cs := "Default";
+		var template integer i := 3;
+		var template RoI roi := {1,2,3};
+		var integer num;
+	}
+
+	function char_to_default_int_template(in charstring input, out integer output) port NVP1 {
+		if (input == "int template") {
+			output := valueof(i);
+			port.setstate(0);
+			i := 666;
+		} else {
+			port.setstate(1);
+		}
+	} with {
+		extension "prototype(fast)";
+	}
+
+	function char_to_default_char(in charstring input, out charstring output) port NVP1 {
+		if (input == "charstring") {
+			output := cs;
+			port.setstate(0);
+			cs := "Modified";
+		} else {
+			port.setstate(1);
+		}
+	} with {
+		extension "prototype(fast)";
+	}
+
+	function char_to_default_const_char(in charstring input, out charstring output) port NVP1 {
+		if (input == "const charstring") {
+			output := c_cs;
+			port.setstate(0);
+		} else {
+			port.setstate(1);
+		}
+	} with {
+		extension "prototype(fast)";
+	}
+
+	function char_to_default_roi(in charstring input, out RoI output) port NVP1 {
+		if (input == "RoI") {
+			output := valueof(roi);
+			port.setstate(0);
+			roi := {6,6,6};
+		} else {
+			port.setstate(1);
+		}
+	} with {
+		extension "prototype(fast)";
+	}
+
+	function char_to_int(in charstring input, out integer output) port NVP1 {
+		if (input == "Unbound") {
+			if (isbound(num)) {
+				output := num;
+			} else {
+				output := 0;
+			}
+			port.setstate(0);
+			num := 666;
+		} else {
+			port.setstate(1);
+		}
+	} with {
+		extension "prototype(fast)";
+	}
+
+
+
+
+
+	type component MyComp {
+		port NVP1 p[2];
+	}
+
+	type component System {
+		port VP1 p1;
+		port VP1 p2;
+	}
+
+
+	testcase tc_variable_change_test(boolean test_changed) runs on MyComp system System {
+		map(self:p[0], system:p1);
+
+		// Test that the default values of port variables are set
+		// and change them inside the translation functions
+		p[0].send("int template");
+		timer t := 0.5;
+		t.start;
+		alt {
+			[] p[0].receive(3) { setverdict(pass); }
+			[] t.timeout    { setverdict(fail); }
+		}
+		t.stop;
+
+		p[0].send("charstring");
+		t.start;
+		alt {
+			[] p[0].receive("Default") { setverdict(pass); }
+			[] t.timeout    { setverdict(fail); }
+		}
+		t.stop;
+
+		p[0].send("const charstring");
+		t.start;
+		alt {
+			[] p[0].receive("DefaultConst") { setverdict(pass); }
+			[] t.timeout    { setverdict(fail); }
+		}
+		t.stop;
+
+		var RoI roi := {1,2,3};
+		p[0].send("RoI");
+		t.start;
+		alt {
+			[] p[0].receive(roi) { setverdict(pass); }
+			[] t.timeout    { setverdict(fail); }
+		}
+		t.stop;
+
+		p[0].send("Unbound");
+		t.start;
+		alt {
+			// 0 means that num is unbound
+			[] p[0].receive(0) { setverdict(pass); }
+			[] t.timeout    { setverdict(fail); }
+		}
+		t.stop;
+
+		// Test that the variables are changed
+		if (test_changed) {
+			p[0].send("int template");
+			t.start;
+			alt {
+				[] p[0].receive(666) { setverdict(pass); }
+				[] t.timeout    { setverdict(fail); }
+			}
+			t.stop;
+
+			p[0].send("charstring");
+			t.start;
+			alt {
+				[] p[0].receive("Modified") { setverdict(pass); }
+				[] t.timeout    { setverdict(fail); }
+			}
+			t.stop;
+
+			// The const did not change
+			p[0].send("const charstring");
+			t.start;
+			alt {
+				[] p[0].receive("DefaultConst") { setverdict(pass); }
+				[] t.timeout    { setverdict(fail); }
+			}
+			t.stop;
+
+			roi := {6,6,6};
+			p[0].send("RoI");
+			t.start;
+			alt {
+				[] p[0].receive(roi) { setverdict(pass); }
+				[] t.timeout    { setverdict(fail); }
+			}
+			t.stop;
+
+			p[0].send("Unbound");
+			t.start;
+			alt {
+				[] p[0].receive(666) { setverdict(pass); }
+				[] t.timeout    { setverdict(fail); }
+			}
+			t.stop;
+		}
+
+		// p[0] and p[1] should have different port variable instances
+		// Theese tests would fail if they would share the variables
+		map(self:p[1], system:p2);
+
+		// Test that the default values of port variables are set
+		// and change them inside the translation functions
+		p[1].send("int template");
+		t.start;
+		alt {
+			[] p[1].receive(3) { setverdict(pass); }
+			[] t.timeout    { setverdict(fail); }
+		}
+		t.stop;
+
+		p[1].send("charstring");
+		t.start;
+		alt {
+			[] p[1].receive("Default") { setverdict(pass); }
+			[] t.timeout    { setverdict(fail); }
+		}
+		t.stop;
+
+		p[1].send("const charstring");
+		t.start;
+		alt {
+			[] p[1].receive("DefaultConst") { setverdict(pass); }
+			[] t.timeout    { setverdict(fail); }
+		}
+		t.stop;
+
+		roi := {1,2,3};
+		p[1].send("RoI");
+		t.start;
+		alt {
+			[] p[1].receive(roi) { setverdict(pass); }
+			[] t.timeout    { setverdict(fail); }
+		}
+		t.stop;
+
+		p[1].send("Unbound");
+			t.start;
+			alt {
+				[] p[1].receive(0) { setverdict(pass); }
+				[] t.timeout    { setverdict(fail); }
+			}
+			t.stop;
+
+		// Test that the variables are changed
+		if (test_changed) {
+			p[1].send("int template");
+			t.start;
+			alt {
+				[] p[1].receive(666) { setverdict(pass); }
+				[] t.timeout    { setverdict(fail); }
+			}
+			t.stop;
+
+			p[1].send("charstring");
+			t.start;
+			alt {
+				[] p[1].receive("Modified") { setverdict(pass); }
+				[] t.timeout    { setverdict(fail); }
+			}
+			t.stop;
+
+			// The const did not change
+			p[1].send("const charstring");
+			t.start;
+			alt {
+				[] p[1].receive("DefaultConst") { setverdict(pass); }
+				[] t.timeout    { setverdict(fail); }
+			}
+			t.stop;
+
+			roi := {6,6,6};
+			p[1].send("RoI");
+			t.start;
+			alt {
+				[] p[1].receive(roi) { setverdict(pass); }
+				[] t.timeout    { setverdict(fail); }
+			}
+			t.stop;
+
+			p[1].send("Unbound");
+			t.start;
+			alt {
+				[] p[1].receive(666) { setverdict(pass); }
+				[] t.timeout    { setverdict(fail); }
+			}
+			t.stop;
+		}
+
+	}
+
+	control {
+		execute(tc_variable_change_test(true));
+		// Test that the variables are restored to the default values
+		execute(tc_variable_change_test(false));
+	}
+}
\ No newline at end of file
diff --git a/regression_test/portTranslation/VP1.cc b/regression_test/portTranslation/VP1.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7c6050dd698530d48956dd1af4b5ea9bafd8330f
--- /dev/null
+++ b/regression_test/portTranslation/VP1.cc
@@ -0,0 +1,91 @@
+/******************************************************************************
+ * 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
+ *
+ ******************************************************************************/
+
+#include "VP1.hh"
+#include "PortVariables.hh"
+
+namespace PortVariables {
+
+VP1_PROVIDER::VP1_PROVIDER(const char *par_port_name)
+	: PORT(par_port_name)
+{
+
+}
+
+VP1_PROVIDER::~VP1_PROVIDER()
+{
+
+}
+
+void VP1_PROVIDER::set_parameter(const char * /*parameter_name*/,
+	const char * /*parameter_value*/)
+{
+
+}
+
+/*void VP1_PROVIDER::Handle_Fd_Event(int fd, boolean is_readable,
+	boolean is_writable, boolean is_error) {}*/
+
+void VP1_PROVIDER::Handle_Fd_Event_Error(int /*fd*/)
+{
+
+}	
+
+void VP1_PROVIDER::Handle_Fd_Event_Writable(int /*fd*/)
+{
+
+}
+
+void VP1_PROVIDER::Handle_Fd_Event_Readable(int /*fd*/)
+{
+
+}
+
+/*void VP1_PROVIDER::Handle_Timeout(double time_since_last_call) {}*/
+
+void VP1_PROVIDER::user_map(const char * /*system_port*/)
+{
+
+}
+
+void VP1_PROVIDER::user_unmap(const char * /*system_port*/)
+{
+
+}
+
+void VP1_PROVIDER::user_start()
+{
+
+}
+
+void VP1_PROVIDER::user_stop()
+{
+
+}
+
+void VP1_PROVIDER::outgoing_send(const INTEGER& send_par)
+{
+	incoming_message(send_par);
+}
+
+void VP1_PROVIDER::outgoing_send(const CHARSTRING& send_par)
+{
+	incoming_message(send_par);
+}
+
+void VP1_PROVIDER::outgoing_send(const RoI& send_par)
+{
+	incoming_message(send_par);
+}
+
+} /* end of namespace */
+
diff --git a/regression_test/portTranslation/VP1.hh b/regression_test/portTranslation/VP1.hh
new file mode 100644
index 0000000000000000000000000000000000000000..fbafa34ad9e9c4da77b853d7c1e30173ae60bdc3
--- /dev/null
+++ b/regression_test/portTranslation/VP1.hh
@@ -0,0 +1,59 @@
+/******************************************************************************
+ * 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
+ *
+ ******************************************************************************/
+
+#ifndef VP1_HH
+#define VP1_HH
+
+#include <TTCN3.hh>
+
+// Note: Header file PortVariables.hh must not be included into this file!
+// (because it includes this file)
+// Please add the declarations of message types manually.
+
+namespace PortVariables {
+
+typedef PreGenRecordOf::PREGEN__RECORD__OF__INTEGER RoI;
+
+class VP1_PROVIDER : public PORT {
+public:
+	VP1_PROVIDER(const char *par_port_name);
+	~VP1_PROVIDER();
+
+	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);
+	void user_unmap(const char *system_port);
+
+	void user_start();
+	void user_stop();
+
+public:
+	void outgoing_send(const INTEGER& send_par);
+	void outgoing_send(const CHARSTRING& send_par);
+	void outgoing_send(const RoI& send_par);
+	virtual void incoming_message(const INTEGER& incoming_par) = 0;
+	virtual void incoming_message(const CHARSTRING& incoming_par) = 0;
+	virtual void incoming_message(const RoI& incoming_par) = 0;
+};
+
+} /* end of namespace */
+
+#endif
diff --git a/regression_test/portTranslation/config.cfg b/regression_test/portTranslation/config.cfg
index c4e964a2b01d626b6235f99583c6e01a3ec14475..367d96b9f8eb68dc1587d091b8d7e4c0d8a0f638 100644
--- a/regression_test/portTranslation/config.cfg
+++ b/regression_test/portTranslation/config.cfg
@@ -12,3 +12,4 @@
 [EXECUTE]
 PortTranslation.control
 Setstate_neg.control
+PortVariables.control
\ No newline at end of file