First code commit
diff --git a/doc/Thrift_TP_Gen_CNL113785_1551.doc b/doc/Thrift_TP_Gen_CNL113785_1551.doc
new file mode 100644
index 0000000..e0f5e82
--- /dev/null
+++ b/doc/Thrift_TP_Gen_CNL113785_1551.doc
Binary files differ
diff --git a/doc/Thrift_TP_Gen_CNL113785_PRI.doc b/doc/Thrift_TP_Gen_CNL113785_PRI.doc
new file mode 100644
index 0000000..2283fb1
--- /dev/null
+++ b/doc/Thrift_TP_Gen_CNL113785_PRI.doc
Binary files differ
diff --git a/src/TTPG.awk b/src/TTPG.awk
new file mode 100644
index 0000000..b4dfcce
--- /dev/null
+++ b/src/TTPG.awk
@@ -0,0 +1,2120 @@
+#/******************************************************************************
+#* Copyright (c) 2000-2018 Ericsson Telecom AB
+#* All rights reserved. This program and the accompanying materials
+#* are made available under the terms of the Eclipse Public License v2.0
+#* which accompanies this distribution, and is available at
+#* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+#*
+#******************************************************************************/
+
+
+function cc_prefix_thrift_type(typename,orig_module, type_module,dot_pos,tn,prefix,enum_suffix){
+  dot_pos=index(typename,".")
+  if(dot_pos>0){
+    type_module=substr(typename,1,dot_pos-1)
+    tn=substr(typename,dot_pos+1)
+  } else {
+    type_module=orig_module
+    tn=typename
+  }
+  if(is_basetype(tn,type_module)!=0){
+    if( type_module SUBSEP "TYPEDEF" SUBSEP tn in AST){
+      if(type_module SUBSEP "NAMESPACE" in AST){
+        prefix="::" dot_to_colon(AST[type_module SUBSEP "NAMESPACE"]) "::"
+      } else {
+        prefix="::"
+      }
+    } else {
+      prefix=""
+    }
+  } else if ( type_module SUBSEP "LIST_TYPES" SUBSEP tn in AST ) {
+    return "std::vector<" cc_prefix_thrift_type(AST[type_module SUBSEP "LIST_TYPES" SUBSEP tn],type_module) ">"
+  } else {
+    if(type_module SUBSEP "NAMESPACE" in AST){
+      prefix="::" dot_to_colon(AST[type_module SUBSEP "NAMESPACE"]) "::"
+    } else {
+      prefix="::"
+    }
+    if(is_enum(tn,type_module)!=0){
+      enum_suffix="::type"
+    } else {
+      enum_suffix=""
+    }
+  }
+  
+  return prefix get_basetype(tn) enum_suffix
+}
+function basename(pn) {
+        sub(/^.*\//, "", pn)
+        return pn
+}
+
+
+function gen_outgoing_hh(services_data,s,module_name,temp_serv_name,temp_serv,serv_mod,dot_ind,func_data,func_num){
+      delete func_data
+      get_subarray(services_data,"FUNCS",func_data)
+      func_num=get_array_length(func_data)
+      for(i=1;i<=func_num;i++){
+        print "  void outgoing_call(const "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_call& call_par," >> hh_file_name
+        print "    const INTEGER *destination_address);" >> hh_file_name
+        print "  void outgoing_reply(const "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_reply& reply_par," >> hh_file_name
+        print "    const INTEGER *destination_address);" >> hh_file_name
+        print "  void outgoing_raise(const "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_exception& raise_par," >> hh_file_name
+        print "    const INTEGER *destination_address);" >> hh_file_name
+
+      }
+      if("EXTENDS" in services_data){
+        delete temp_serv
+        dot_ind=index(services_data["EXTENDS"],".")
+        if(dot_ind>0){
+          serv_mod=substr(services_data["EXTENDS"],1,dot_ind-1)
+          temp_serv_name=substr(services_data["EXTENDS"],dot_ind+1)
+        } else {
+          serv_mod=module_name
+          temp_serv_name=services_data["EXTENDS"]
+        }
+        get_subarray(AST,serv_mod SUBSEP "SERVICES" SUBSEP temp_serv_name,temp_serv)
+        gen_outgoing_hh(temp_serv,s,serv_mod)
+      }
+}
+
+function gen_service_hh(services_data,s,module_name,i,k,exception_data,comm,temp_serv_name,temp_serv,serv_mod,dot_ind,func_data,arg_data,func_num,arg_num,except_num,temp_cc_prefix,ret_name,first_arg,ref){
+      delete func_data
+      get_subarray(services_data,"FUNCS",func_data)
+
+      func_num=get_array_length(func_data)
+      for(i=1;i<=func_num;i++){
+        print "" >> hh_file_name
+     
+        delete arg_data
+        get_subarray(func_data,i SUBSEP "FIELDS",arg_data)
+        arg_num=get_array_length(arg_data)
+        if (func_data[i SUBSEP "RETTYPE"] != "void") {
+          if(is_basetype(func_data[i SUBSEP "RETTYPE"],module_name) == 1){
+            ret_name=get_basetype(func_data[i SUBSEP "RETTYPE"]) " "
+            first_arg=""
+          } else {
+            if(arg_num==0){
+              comm = ""
+            } else {
+              comm =", "
+            }
+            ret_name="void "
+            first_arg=cc_prefix_thrift_type(func_data[i SUBSEP "RETTYPE"],module_name) "& " comm
+          }
+        } else {
+          ret_name="void "
+          first_arg=""
+        }     
+        
+        print "  " ret_name  " " func_data[i SUBSEP "NAME"] " ( " first_arg >> hh_file_name
+
+        for(k=1;k<=arg_num;k++){
+          if(k==arg_num){
+            comm = ""
+          } else {
+            comm =","
+          }
+          if((is_basetype(arg_data[k SUBSEP "TYPE"],module_name)==1) || (is_enum(arg_data[k SUBSEP "TYPE"],module_name)==1)){
+            ref = ""
+          } else {
+            ref = "&"
+          }
+          print "    const " cc_prefix_thrift_type(arg_data[k SUBSEP "TYPE"],module_name) ref comm >> hh_file_name
+        }
+        print "  );" >> hh_file_name
+      }
+      if("EXTENDS" in services_data){
+        delete temp_serv
+        dot_ind=index(services_data["EXTENDS"],".")
+        if(dot_ind>0){
+          serv_mod=substr(services_data["EXTENDS"],1,dot_ind-1)
+          temp_serv_name=substr(services_data["EXTENDS"],dot_ind+1)
+        } else {
+          serv_mod=module_name
+          temp_serv_name=services_data["EXTENDS"]
+        }
+        get_subarray(AST,serv_mod SUBSEP "SERVICES" SUBSEP temp_serv_name,temp_serv)
+        gen_service_hh(temp_serv,s,serv_mod)
+      }
+}
+function gen_service_event_call_cc(services_data,s,module_name,func_num_base,i,k,exception_data,comm,temp_serv_name,temp_serv,serv_mod,dot_ind,func_data,arg_data,func_num,arg_num,except_num,temp_cc_prefix,ret_name,first_arg,ref){
+
+      delete func_data
+      get_subarray(services_data,"FUNCS",func_data)
+
+      func_num=get_array_length(func_data)
+      for(i=1;i<=func_num;i++){
+        print "" >> cc_file_name
+     
+        delete arg_data
+        get_subarray(func_data,i SUBSEP "FIELDS",arg_data)
+        arg_num=get_array_length(arg_data)
+
+        print "        case "func_num_base+i":{" >> cc_file_name
+        print "            "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_call call_par;" >> cc_file_name
+
+        for(k=1;k<=arg_num;k++){
+          print "            conv_thrift_ttcn(*(("cc_prefix_thrift_type(arg_data[k SUBSEP "TYPE"],module_name)"*)(_push_data["k-1"])),call_par."double_und(arg_data[k SUBSEP "NAME"])"());" >> cc_file_name
+        }
+        print "            incoming_call(call_par,&addr);" >> cc_file_name
+        print "          }" >> cc_file_name
+        print "          break;" >> cc_file_name
+      }
+      if("EXTENDS" in services_data){
+        delete temp_serv
+        dot_ind=index(services_data["EXTENDS"],".")
+        if(dot_ind>0){
+          serv_mod=substr(services_data["EXTENDS"],1,dot_ind-1)
+          temp_serv_name=substr(services_data["EXTENDS"],dot_ind+1)
+        } else {
+          serv_mod=module_name
+          temp_serv_name=services_data["EXTENDS"]
+        }
+        get_subarray(AST,serv_mod SUBSEP "SERVICES" SUBSEP temp_serv_name,temp_serv)
+        gen_service_event_call_cc(temp_serv,s,serv_mod,func_num_base+func_num)
+      }
+}
+function gen_service_outgoing_cc(services_data,s,module_name,func_num_base,i,k,exception_data,comm,temp_serv_name,temp_serv,serv_mod,dot_ind,func_data,arg_data,func_num,arg_num,except_num,temp_cc_prefix,ret_name,first_arg,ref){
+
+      delete func_data
+      get_subarray(services_data,"FUNCS",func_data)
+
+      func_num=get_array_length(func_data)
+      for(i=1;i<=func_num;i++){
+
+        print "void "double_und(s)"__PT::outgoing_call(const "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_call& call_par," >> cc_file_name
+        print "  const INTEGER * /*destination_address*/)" >> cc_file_name
+        print "{" >> cc_file_name
+        print "  if(port_mode!=1){" >> cc_file_name
+        print "    Thrift__Common::Thrift__port__error error_exception;" >> cc_file_name
+        print "    error_exception.error__code()=1;" >> cc_file_name
+        print "    error_exception.error__text()=\"The port is not in client mode\";" >> cc_file_name
+        print "    "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_exception ex(error_exception);" >> cc_file_name
+        print "    incoming_exception(ex,NULL);" >> cc_file_name
+        print "    return;" >> cc_file_name
+        print "  }" >> cc_file_name
+        print "" >> cc_file_name
+
+        delete arg_data
+        get_subarray(func_data,i SUBSEP "FIELDS",arg_data)
+        arg_num=get_array_length(arg_data)
+        for(k=1;k<=arg_num;k++){
+          print "  " cc_prefix_thrift_type(arg_data[k SUBSEP "TYPE"],module_name) " " arg_data[k SUBSEP "NAME"] ";" >> cc_file_name
+          print "  conv_ttcn_thrift(call_par." double_und(arg_data[k SUBSEP "NAME"]) "()," arg_data[k SUBSEP "NAME"] ");" >> cc_file_name
+          
+        }
+        if (func_data[i SUBSEP "RETTYPE"] != "void") {
+          print "  "cc_prefix_thrift_type(func_data[i SUBSEP "RETTYPE"],module_name)" _return_val;" >> cc_file_name
+        }
+        print "  " >> cc_file_name
+
+        print "" >> cc_file_name
+        print "  try{" >> cc_file_name
+        first_arg=""          
+        if (func_data[i SUBSEP "RETTYPE"] != "void") {
+          if(is_basetype(func_data[i SUBSEP "RETTYPE"],module_name)==1){
+            print "    _return_val=" >> cc_file_name
+          } else {
+            if(arg_num==0){
+              comm = ""
+            } else {
+              comm =", "
+            }
+            first_arg=" _return_val" comm
+          }
+        }
+        print "      client_handler->"func_data[i SUBSEP "NAME"]"(" first_arg  >> cc_file_name
+        for(k=1;k<=arg_num;k++){
+          if(k==arg_num){
+            comm = ""
+          } else {
+            comm =", "
+          }
+          print "         "arg_data[k SUBSEP "NAME"] comm >> cc_file_name
+        }
+        print "      );" >> cc_file_name
+
+        delete exception_data
+        get_subarray(func_data,i SUBSEP "THROWS",exception_data)
+        except_num=get_array_length(exception_data)
+        for(k=1;k<=except_num;k++){
+          print "  } catch ( " cc_prefix_thrift_type(exception_data[k SUBSEP "TYPE"],module_name) " " exception_data[k SUBSEP "NAME"] " ) {" >> cc_file_name
+          print "    "double_und(exception_data[k SUBSEP "TYPE"])" _"exception_data[k SUBSEP "NAME"]";" >> cc_file_name
+          print "    conv_thrift_ttcn("exception_data[k SUBSEP "NAME"]",_"exception_data[k SUBSEP "NAME"]");" >> cc_file_name
+          print "   " >> cc_file_name
+          print "    "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_exception ex(_ouch);" >> cc_file_name
+          print "    incoming_exception(ex,NULL);" >> cc_file_name
+          print "    return;" >> cc_file_name
+        }
+        print "  } catch (...) {" >> cc_file_name
+        print "    Thrift__Common::Thrift__port__error error_exception;" >> cc_file_name
+        print "    error_exception.error__code()=1;" >> cc_file_name
+        print "    error_exception.error__text()=\"The Thrift libary have thrown an exception\";" >> cc_file_name
+        print "    "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_exception ex(error_exception);" >> cc_file_name
+        print "    incoming_exception(ex,NULL);" >> cc_file_name
+        print "    return;" >> cc_file_name
+        print "  }" >> cc_file_name
+        print "" >> cc_file_name
+        print "  "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_reply _reply;" >> cc_file_name
+        if (func_data[i SUBSEP "RETTYPE"] != "void") {
+          print "  conv_thrift_ttcn(_return_val,_reply.return_value());" >> cc_file_name
+        }
+        print "  incoming_reply(_reply,NULL);" >> cc_file_name
+        print "}" >> cc_file_name
+        print "" >> cc_file_name
+
+
+        print "void "double_und(s)"__PT::outgoing_reply(const "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_reply& reply_par," >> cc_file_name
+        print "  const INTEGER * destination_address)" >> cc_file_name
+        print "{" >> cc_file_name
+        print "  if(destination_address==NULL){" >> cc_file_name
+        print "    TTCN_error(\"Reply can not be sent. There address is missing\");" >> cc_file_name
+        print "  }" >> cc_file_name
+        print "  int cp=*destination_address;" >> cc_file_name
+        print "  if(clients.count(cp)==0){" >> cc_file_name
+        print "    TTCN_error(\"Reply can not be sent. Wrong address %d\",cp);" >> cc_file_name
+        print "  }" >> cc_file_name
+        print "" >> cc_file_name
+        print "  std::map<int,void*>::iterator it=client_data.find(cp);" >> cc_file_name
+        print "  " >> cc_file_name
+        print "  if(it==client_data.end()){" >> cc_file_name
+        print "    TTCN_error(\"Reply can not be sent. Wrong address %d\",cp);" >> cc_file_name
+        print "  }" >> cc_file_name
+        print "" >> cc_file_name
+        print "  struct internal_comm_struct *comm_buff=(struct internal_comm_struct *)it->second;" >> cc_file_name
+        print "  comm_buff->code=0;" >> cc_file_name
+        if (func_data[i SUBSEP "RETTYPE"] != "void") {
+          print "  conv_ttcn_thrift(reply_par.return_value(),*("cc_prefix_thrift_type(func_data[i SUBSEP "RETTYPE"],module_name)"*)comm_buff->data["arg_num"]);" >> cc_file_name
+        }
+        print "  write(cp,&comm_buff,sizeof(void*));" >> cc_file_name
+        print "  client_data.erase(it);" >> cc_file_name
+        print "}" >> cc_file_name
+
+	      print "void "double_und(s)"__PT::outgoing_raise(const "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_exception& raise_exception," >> cc_file_name
+	      print "	const INTEGER * destination_address)" >> cc_file_name
+	      print "{" >> cc_file_name
+	      print "  if(destination_address==NULL){" >> cc_file_name
+	      print "    TTCN_error(\"Exception can not be sent. There address is missing\");" >> cc_file_name
+	      print "  }" >> cc_file_name
+	      print "  int cp=*destination_address;" >> cc_file_name
+	      print "  if(clients.count(cp)==0){" >> cc_file_name
+	      print "    TTCN_error(\"Exception can not be sent. Wrong address %d\",cp);" >> cc_file_name
+	      print "  }" >> cc_file_name
+	      print "" >> cc_file_name
+	      print "  std::map<int,void*>::iterator it=client_data.find(cp);" >> cc_file_name
+	      print "  " >> cc_file_name
+	      print "  if(it==client_data.end()){" >> cc_file_name
+	      print "    TTCN_error(\"Exception can not be sent. Wrong address %d\",cp);" >> cc_file_name
+	      print "  }" >> cc_file_name
+	      print "" >> cc_file_name
+	      print "  switch(raise_exception.get_selection()){" >> cc_file_name
+
+        for(k=1;k<=except_num;k++){
+	        print "    case "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_exception::ALT_"double_und(f)"__TypesAndPorts_"double_und(exception_data[k SUBSEP "TYPE"])":{" >> cc_file_name
+	        print "      struct internal_comm_struct *comm_buff=(struct internal_comm_struct *)it->second;" >> cc_file_name
+	        print "" >> cc_file_name
+	        print "      comm_buff->code=1;" >> cc_file_name
+	        print "      conv_ttcn_thrift(raise_exception."double_und(f)"__TypesAndPorts_"double_und(exception_data[k SUBSEP "TYPE"])"_field(),*(" cc_prefix_thrift_type(exception_data[k SUBSEP "TYPE"],module_name)"*)comm_buff->data["arg_num+k"]);" >> cc_file_name
+	        print "      write(cp,&comm_buff,sizeof(void*));" >> cc_file_name
+	        print "      client_data.erase(it);" >> cc_file_name
+	        print "      }" >> cc_file_name
+	        print "      break;" >> cc_file_name
+        }
+
+	      print "    default:" >> cc_file_name
+	      print "      TTCN_error(\"Invalid exception was sent.\");" >> cc_file_name
+	      print "      break;" >> cc_file_name
+	      print "  }" >> cc_file_name
+	      print "}" >> cc_file_name
+
+      }
+
+      if("EXTENDS" in services_data){
+        delete temp_serv
+        dot_ind=index(services_data["EXTENDS"],".")
+        if(dot_ind>0){
+          serv_mod=substr(services_data["EXTENDS"],1,dot_ind-1)
+          temp_serv_name=substr(services_data["EXTENDS"],dot_ind+1)
+        } else {
+          serv_mod=module_name
+          temp_serv_name=services_data["EXTENDS"]
+        }
+        get_subarray(AST,serv_mod SUBSEP "SERVICES" SUBSEP temp_serv_name,temp_serv)
+        gen_service_outgoing_cc(temp_serv,s,serv_mod,func_num_base+func_num)
+      }
+}
+
+function gen_service_cc(services_data,s,module_name,func_num_base,i,k,exception_data,comm,temp_serv_name,temp_serv,serv_mod,dot_ind,func_data,arg_data,func_num,arg_num,except_num,temp_cc_prefix,ret_name,first_arg,ref){
+      delete func_data
+      get_subarray(services_data,"FUNCS",func_data)
+
+      func_num=get_array_length(func_data)
+      for(i=1;i<=func_num;i++){
+        print "" >> cc_file_name
+     
+        delete arg_data
+        get_subarray(func_data,i SUBSEP "FIELDS",arg_data)
+        arg_num=get_array_length(arg_data)
+        if (func_data[i SUBSEP "RETTYPE"] != "void") {
+          if(is_basetype(func_data[i SUBSEP "RETTYPE"],module_name) == 1){
+            ret_name=get_basetype(func_data[i SUBSEP "RETTYPE"]) " "
+            first_arg=""
+          } else {
+            if(arg_num==0){
+              comm = ""
+            } else {
+              comm =", "
+            }
+            ret_name="void "
+            first_arg=cc_prefix_thrift_type(func_data[i SUBSEP "RETTYPE"],module_name) "& _ret_val" comm
+          }
+        } else {
+          ret_name="void "
+          first_arg=""
+        }     
+        
+        print "  " ret_name  " "s"Handler::" func_data[i SUBSEP "NAME"] " ( " first_arg >> cc_file_name
+
+        for(k=1;k<=arg_num;k++){
+          if(k==arg_num){
+            comm = ""
+          } else {
+            comm =","
+          }
+          if((is_basetype(arg_data[k SUBSEP "TYPE"],module_name)==1) || (is_enum(arg_data[k SUBSEP "TYPE"],module_name)==1)){
+            ref = ""
+          } else {
+            ref = "&"
+          }
+          print "    const " cc_prefix_thrift_type(arg_data[k SUBSEP "TYPE"],module_name) ref " " arg_data[k SUBSEP "NAME"] comm >> cc_file_name
+        }
+        print "  ){" >> cc_file_name
+        is_return=0
+        if (func_data[i SUBSEP "RETTYPE"] != "void") {
+          if(is_basetype(func_data[i SUBSEP "RETTYPE"],module_name) == 1){
+            print "  " get_basetype(func_data[i SUBSEP "RETTYPE"]) " _ret_val;" >> cc_file_name
+            is_return=1
+          }
+        } else {
+          is_return=2
+        }
+
+        delete exception_data
+        get_subarray(func_data,i SUBSEP "THROWS",exception_data)
+        except_num=get_array_length(exception_data)
+        for(k=1;k<=except_num;k++){
+          print "  " cc_prefix_thrift_type(exception_data[k SUBSEP "TYPE"],module_name) " " exception_data[k SUBSEP "NAME"] ";" >> cc_file_name
+        }
+        print "" >> cc_file_name
+        print "    int _s=connect();" >> cc_file_name
+        print "    void * _push_data["arg_num+1+except_num"];" >> cc_file_name
+        print "    struct internal_comm_struct _comm_buff;" >> cc_file_name
+        print "" >> cc_file_name
+        for(k=1;k<=arg_num;k++){
+          print "    _push_data["k-1"]=(void*)&"arg_data[k SUBSEP "NAME"]";" >> cc_file_name
+        }
+        if(is_return!=2){
+          print "    _push_data["arg_num"]=(void*)&_ret_val;" >> cc_file_name
+        }
+        for(k=1;k<=except_num;k++){
+          print "    _push_data["k+arg_num"]=(void*)&"exception_data[k SUBSEP "NAME"]";" >> cc_file_name
+        }
+        print "" >> cc_file_name
+        print "    _comm_buff.code="func_num_base+i";" >> cc_file_name
+        print "    _comm_buff.data=(void **)&_push_data;" >> cc_file_name
+        print "" >> cc_file_name    
+    
+        print "    void *_dp=(void*)&_comm_buff;" >> cc_file_name
+        print "    write(_s,&_dp,sizeof(void *));" >> cc_file_name
+        print "    read(_s,&_dp,sizeof(void *));" >> cc_file_name
+        print "" >> cc_file_name    
+        print "    int code=((struct internal_comm_struct*)_dp)->code;" >> cc_file_name
+        print "" >> cc_file_name
+        print "    switch(code){" >> cc_file_name
+        print "      case 0:" >> cc_file_name
+        print "        break;" >> cc_file_name
+        for(k=1;k<=except_num;k++){
+        print "      case "k":" >> cc_file_name
+        print "        throw "exception_data[k SUBSEP "NAME"]";" >> cc_file_name
+        print "        break;" >> cc_file_name
+        }
+
+
+        print "      default:" >> cc_file_name
+        print "        break;" >> cc_file_name   
+        print "    }" >> cc_file_name
+        print "    close(_s);" >> cc_file_name
+
+
+        if(is_return==1){
+          print "  return _ret_val;" >> cc_file_name
+        }
+        print "}" >> cc_file_name
+      }
+      if("EXTENDS" in services_data){
+        delete temp_serv
+        dot_ind=index(services_data["EXTENDS"],".")
+        if(dot_ind>0){
+          serv_mod=substr(services_data["EXTENDS"],1,dot_ind-1)
+          temp_serv_name=substr(services_data["EXTENDS"],dot_ind+1)
+        } else {
+          serv_mod=module_name
+          temp_serv_name=services_data["EXTENDS"]
+        }
+        get_subarray(AST,serv_mod SUBSEP "SERVICES" SUBSEP temp_serv_name,temp_serv)
+        gen_service_cc(temp_serv,s,serv_mod,func_num_base+func_num)
+      }
+}
+
+function is_basetype(tn,module,type_list, type_module,dot_pos,typename){
+  type_list["bool"]=1
+  type_list["byte"]=1
+  type_list["i16"]=1
+  type_list["i32"]=1
+  type_list["i64"]=1
+  type_list["double"]=1
+  type_list["string"]=2
+  type_list["binary"]=2
+  
+  if(tn in type_list ){
+    return type_list[tn]
+  } else {
+    typename=tn
+    dot_pos=index(typename,".")
+    if(dot_pos>0){
+      type_module=substr(typename,1,dot_pos-1)
+      tn=substr(typename,dot_pos+1)
+      return is_basetype(tn,type_module)
+    } else {
+      if( module SUBSEP "TYPEDEF" SUBSEP tn in AST){
+        return is_basetype(AST[module SUBSEP "TYPEDEF" SUBSEP tn],module)
+      }
+    }
+    
+    return 0
+  }
+}
+function is_enum(tn,module, type_module,dot_pos){
+  if(is_basetype(tn,module)!=0){
+    return 0
+  } else {
+    dot_pos=index(typename,".")
+    if(dot_pos>0){
+      type_module=substr(typename,1,dot_pos-1)
+      tn=substr(typename,dot_pos+1)
+      return is_enum(tn,type_module)
+    } else {
+      if( module SUBSEP "ENUMS" SUBSEP tn SUBSEP "NAME" in AST){
+        return 1
+      }
+    }
+    
+    return 0
+  }
+}
+function is_basetype_ttcn(tn,type_list){
+  type_list["bool"]=1
+  type_list["byte"]=1
+  type_list["i16"]=1
+  type_list["i32"]=1
+  type_list["i64"]=1
+  type_list["double"]=1
+  type_list["string"]=1
+  type_list["binary"]=1
+  
+  if(tn in type_list ){
+    return 1
+  } else {
+    return 0
+  }
+}
+
+function get_basetype(tn,type_list){
+  type_list["bool"]="bool"
+  type_list["byte"]="int8_t"
+  type_list["i16"]="int16_t"
+  type_list["i32"]="int32_t"
+  type_list["i64"]="int64_t"
+  type_list["double"]="double"
+  type_list["string"]="std::string"
+  type_list["binary"]="std::string"
+  
+  
+  if(tn in type_list ){
+    return type_list[tn]
+  } else {
+    return tn
+  }
+}
+
+function prefix_type(typename,orig_module, type_module,dot_pos,tn){
+  dot_pos=index(typename,".")
+  if(dot_pos>0){
+    type_module=substr(typename,1,dot_pos-1)
+    tn=substr(typename,dot_pos+1)
+  } else {
+    type_module=orig_module
+    tn=typename
+  }
+  if(is_basetype_ttcn(tn)==1){
+    type_module=f
+  }
+  if(type_module!=f){
+    return type_module "_TypesAndPorts." res_word(tn)
+  } else {
+    return res_word(tn)
+  }
+}
+
+function gen_service(services_data,s,module_name,i,k,exception_data,comm,temp_serv_name,temp_serv,serv_mod,dot_ind,func_data,arg_data,func_num,arg_num,except_num){
+      print "" >> file_name
+      delete func_data
+      get_subarray(services_data,"FUNCS",func_data)
+      func_num=get_array_length(func_data)
+      for(i=1;i<=func_num;i++){
+        print "  signature " s "_" func_data[i SUBSEP "NAME"] " ( " >> file_name
+        delete arg_data
+        get_subarray(func_data,i SUBSEP "FIELDS",arg_data)
+        arg_num=get_array_length(arg_data)
+        for(k=1;k<=arg_num;k++){
+          if(k==arg_num){
+            comm = ""
+          } else {
+            comm =","
+          }
+          print "    in " prefix_type(arg_data[k SUBSEP "TYPE"],module_name) " " res_word(arg_data[k SUBSEP "NAME"]) comm >> file_name
+        }
+        print "  )" >> file_name
+        if( func_data[i SUBSEP "RETTYPE"] != "void") {
+          print "    return " prefix_type(func_data[i SUBSEP "RETTYPE"],module_name) >> file_name
+        }
+        delete exception_data
+        get_subarray(func_data,i SUBSEP "THROWS",exception_data)
+
+        except_num=get_array_length(exception_data)
+        
+        print "    exception ("  >> file_name
+
+        if(except_num>0){
+          comm = ","
+        } else {
+          comm =""
+        }
+        print "      Thrift_port_error" comm   >> file_name
+        if(except_num>0){
+          for(k=1;k<=except_num;k++){
+            if(k==except_num){
+              comm = ""
+            } else {
+              comm =","
+            }
+            print "      " prefix_type(exception_data[k SUBSEP "TYPE"],module_name) comm >> file_name
+          }
+        }
+        print "  )" >> file_name
+        print "" >> file_name
+      }
+      if("EXTENDS" in services_data){
+        delete temp_serv
+        dot_ind=index(services_data["EXTENDS"],".")
+        if(dot_ind>0){
+          serv_mod=substr(services_data["EXTENDS"],1,dot_ind-1)
+          temp_serv_name=substr(services_data["EXTENDS"],dot_ind+1)
+        } else {
+          serv_mod=module_name
+          temp_serv_name=services_data["EXTENDS"]
+        }
+        get_subarray(AST,serv_mod SUBSEP "SERVICES" SUBSEP temp_serv_name,temp_serv)
+        gen_service(temp_serv,s,serv_mod)
+      }
+}
+
+function gen_port_proc(services_data,s,module_name,temp_serv_name,temp_serv,serv_mod,dot_ind,func_data,func_num){
+      delete func_data
+      get_subarray(services_data,"FUNCS",func_data)
+      func_num=get_array_length(func_data)
+      for(i=1;i<=func_num;i++){
+        print "    inout " s "_" func_data[i SUBSEP "NAME"] >> file_name
+      }
+      if("EXTENDS" in services_data){
+        delete temp_serv
+        dot_ind=index(services_data["EXTENDS"],".")
+        if(dot_ind>0){
+          serv_mod=substr(services_data["EXTENDS"],1,dot_ind-1)
+          temp_serv_name=substr(services_data["EXTENDS"],dot_ind+1)
+        } else {
+          serv_mod=module_name
+          temp_serv_name=services_data["EXTENDS"]
+        }
+        get_subarray(AST,serv_mod SUBSEP "SERVICES" SUBSEP temp_serv_name,temp_serv)
+        gen_port_proc(temp_serv,s,serv_mod)
+      }
+}
+
+function res_word(data,map){
+  map["value"]="value_"
+  
+  if(data in map){
+    return map[data]
+  } else {
+    return data
+  }
+}
+
+function double_und(orig,ret_val){
+  ret_val=orig;
+  gsub(/_/,"__",ret_val);
+  return ret_val;
+}
+function dot_to_colon(orig,ret_val){
+  ret_val=orig;
+  gsub(/\./,"::",ret_val);
+  return ret_val;
+}
+
+function get_subarray(arr, ind, ret_val,x){
+#  ret_val[1]=1;
+#  delete ret_val;
+  
+  for(x in arr){
+    match(x,"^"ind SUBSEP )
+    if(RSTART > 0 ){
+      ret_val[substr(x,RLENGTH+1)]=arr[x]
+    }
+  }
+#  return ret_val;
+}
+
+
+function get_array_length(arr,ret_val,a,x){
+  delete ret_val
+  for(x in arr){
+    split(x,a,SUBSEP);
+    ret_val[a[1]]=a[1]
+  }
+  return length(ret_val)
+}
+
+function push_state(new_state){
+  ++state_stack_level;
+  state_stack[state_stack_level]=parser_state;
+  parser_state=new_state;
+#  print "push "  state_stack_level, " " state_stack[state_stack_level]
+}
+     function walk_array(arr, name,      i,k,l,p)
+     {
+#print "walk array start " name
+        delete p
+        for (i in arr) {
+#print "process " i
+          split(i,k,SUBSEP)
+          if(length(k)>1){
+#print "subaaray found"
+            if(!(k[1] in p)){
+#print "subaaray process"
+              delete l;
+              get_subarray(arr,k[1],l)
+              walk_array(l, name "[" k[1] "]")
+              p[k[1]]=k[1]
+            }
+          } else {
+            printf("%s[%s] = %s\n", name, i, arr[i])
+          }
+        }
+#print "walk array end " name
+     }
+
+function pop_state(){
+  parser_state=state_stack[state_stack_level];
+  --state_stack_level;
+#  print "pop "  state_stack_level, " " state_stack[state_stack_level]
+}
+
+function start_state(){
+     parser_state="START";
+     state_stack_level=1;
+}
+
+ BEGIN {
+     comment= 0;
+     parser_state="START";
+     processed_files[ARGV[1]]=ARGV[1];
+     state_stack_level=1;
+     state_stack[1]="NONE"
+     definition_type_name=""
+     const_name=""
+     enum_name=""
+     field_id=""
+     fieldReq=""
+     fieldName=""
+     struct_name=""
+     save_def_val=0;
+     oneway=0;
+     if(!myserver){
+       myserver_name="TThreadedServer";
+       myserver_include="<thrift/server/TThreadedServer.h>"
+     } else {
+       myserver_name="myTThreadedServer";
+       myserver_include="\"myTThreadedServer.h\""
+     }
+     for(i=1;i<ARGC;i++){
+       match(ARGV[i],/\.thrift/)
+       AST["FILES" SUBSEP basename(substr(ARGV[i],1,RSTART-1))]=basename(substr(ARGV[i],1,RSTART-1));
+     }
+ }
+{
+#  print " !!! ", $0
+  match(FILENAME,/\.thrift/)
+  t_file=basename(substr(FILENAME,1,RSTART-1))
+  while($0)    # Get fields by pattern, not by delimiter
+  {
+    # should be run with gawk < 4.0.0 so FPAT can not be used
+    match($0, "((//)|[#]|([/][\\*])|([\\*]/)|[,]|[=]|(\"[^\"]+\")|('[^']+')|[{]|[}]|[<]|[>]|[:]|[(]|[)]|[;]|([[:alnum:]._+-]+))")    # Find a token
+    if(RSTART > 0) { # token found
+      token = substr($0, RSTART, RLENGTH) # Get the located token
+      if(token ~ /(\"[^\"]+\")|('[^']+')/){
+        token=substr(token,2,RLENGTH-2)
+      }
+#               printf("$0 before = <%s>\n",$0)
+#               printf("token = <%s>\n",token)
+#               print "RSTART = ",RSTART, " RLENGTH = " ,RLENGTH;
+      if( token ~ "(//)|[#]" ) { # Skip line comments
+       next;
+      } else if ( token ~ "[/][*].*" ){ # Skip block comment
+       comment = 1;
+      }  else if (token ~ ".*[*][/].*" ) {  # end of block comment
+       comment = 0;
+      } else  if (comment == 0) { # process the token
+#       printf("%s = <%s>\n",parser_state , token)
+        if(!( token ~ /[,]|[;]/ ) ){ # always skip the list separator
+
+          if(parser_state== "START"){
+              if ( token == "include"){
+                  push_state("INCLUDE")
+                  
+                } else if ( token == "cpp_include"){
+                } else if ( token == "php_namespace"){
+                } else if ( token == "xsd_namespace"){
+                } else if ( token == "smalltalk.category"){
+                } else if ( token == "smalltalk.prefix"){
+                  push_state("SKIP_1")
+                  
+                } else if ( token == "namespace"){
+                  push_state("NAMESPACE");
+                  
+                } else if ( token == "typedef"){
+                  push_state("TYPEDEF");
+                  push_state("DEFINITIONTYPE")
+                  
+                } else if ( token == "const"){
+                  push_state("CONSTDEF");
+                  push_state("DEFINITIONTYPE")
+                  
+                } else if ( token == "enum"){
+                  push_state("ENUMNAME");
+                  enum_senum="ENUMS"
+                  
+                } else if ( token == "senum"){
+                  push_state("ENUMNAME");
+                  enum_senum="SENUMS"
+                  
+                } else if ( token == "struct"){
+                  push_state("STRUCTNAME");
+                  struct_execption="STRUCTS"
+                  
+                } else if ( token == "exception"){
+                  push_state("STRUCTNAME");
+                  struct_execption="EXCEPTIONS"
+                  
+                } else if ( token == "service"){
+                  push_state("SERVICE_ID")
+                  
+                } #default{
+                  
+              
+            } else if (parser_state== "SERVICE_ID"){
+              if ( token == "extends"){
+                  pop_state()
+                  push_state("SERVICE_EXTENDS")
+                  
+                } else if ( token == "{"){
+                  func_num=0;
+                  pop_state()
+                  push_state("SERVICE_FUNCTIONS")
+                  
+                } else {
+                  service_name=token;
+                  AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "NAME"]=service_name;
+    }
+                  
+              
+            } else if (parser_state==  "SERVICE_EXTENDS"){
+              if(token == "{" ){
+                  func_num=0;
+                  pop_state()
+                  push_state("SERVICE_FUNCTIONS")
+              } else {
+                  AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "EXTENDS"]=token;
+              }
+              
+            } else if (parser_state==  "SERVICE_FUNCTIONS"){
+              if ( token == "oneway"){
+                  oneway=1;
+                  
+                } else if ( token == "throws"){
+                  push_state("THROWS")
+                  
+                } else if ( token == "}"){
+                  pop_state()
+                  
+                } else if ( token == "map"){
+                  print "map is unsupported"
+                  definition_type_name="dummy";
+                  push_state("FUNCNAME")
+                  push_state("MAP_END");
+                  
+                } else if ( token == "list"){
+                  push_state("FUNCNAME")
+                  push_state("LIST_BEGIN");
+                  
+                } else if ( token == "set"){
+                  push_state("FUNCNAME")
+                  push_state("SET_BEGIN");
+                  
+                } else {
+                  definition_type_name=token;
+                  push_state("FUNCNAME")
+    }
+                  
+                  
+              
+            } else if (parser_state== "FUNCNAME"){
+              if(token=="("){
+                filed_num=0
+                pop_state()
+                push_state("FUNCFIELD")
+              } else {
+                func_num++
+                if(oneway==1) {
+                  AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "ONEWAY"]=fieldReq
+                  oneway=0
+                }
+                AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "RETTYPE"]=definition_type_name
+                definition_type_name=""
+                AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "NAME"]=token
+              }
+              
+            } else if (parser_state== "FUNCFIELD"){
+              if(save_def_val == 1){
+                save_def_val=0;
+                AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "FIELDS" SUBSEP filed_num SUBSEP "DEFVAL"]=builded_const
+                builded_const="";
+              }
+              if ( token ~ /^[0-9+-]+$/ ){
+                  field_id=token
+                  
+                } else if ( token == ":"){ # just skip it
+                  
+                } else if ( token == "optional"){
+                  fieldReq=token
+                } else if ( token == "required"){
+                  fieldReq=token
+                  
+                } else if ( token == "="){
+                  save_def_val=1;
+                  push_state("CONST_VALUE_BUILD")
+                  
+                } else if ( token == ")"){
+                  pop_state()
+                  
+                } else if ( token == "map"){
+                  print "map is unsupported"
+                  definition_type_name="dummy";
+                  pop_state()
+                  push_state("FUNCFIELDNAME")
+                  push_state("MAP_END");
+                  
+                } else if ( token == "list"){
+                  pop_state()
+                  push_state("FUNCFIELDNAME")
+                  push_state("LIST_BEGIN");
+                  
+                } else if ( token == "set"){
+                  pop_state()
+                  push_state("FUNCFIELDNAME")
+                  push_state("SET_BEGIN");
+                  
+                } else {
+                  definition_type_name=token;
+                  pop_state()
+                  push_state("FUNCFIELDNAME")
+    }
+                  
+                  
+            } else if (parser_state== "FUNCFIELDNAME"){
+              filed_num++
+              AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "FIELDS" SUBSEP filed_num SUBSEP "ID"]=field_id
+              field_id=""
+              if(fieldReq!="optional") {fieldReq="required"}
+              AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "FIELDS" SUBSEP filed_num SUBSEP "REQ"]=fieldReq
+              fieldReq=""
+              AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "FIELDS" SUBSEP filed_num SUBSEP "TYPE"]=definition_type_name
+              definition_type_name=""
+              AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "FIELDS" SUBSEP filed_num SUBSEP "NAME"]=token
+                  pop_state()
+                  push_state("FUNCFIELD")
+              
+            } else if (parser_state== "THROWS"){
+              if(token=="("){
+                filed_num=0
+                pop_state()
+                push_state("THROWSFIELD")
+              }
+              
+            } else if (parser_state== "THROWSFIELD"){
+              if(save_def_val == 1){
+                save_def_val=0;
+                AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "THROWS" SUBSEP filed_num SUBSEP "DEFVAL"]=builded_const
+                builded_const="";
+              }
+              if ( token ~ /^[0-9+-]+$/ ){
+                  field_id=token
+                  
+                } else if ( token == ":"){ # just skip it
+                  
+                } else if ( token == "optional"){
+                  fieldReq=token
+                } else if ( token == "required"){
+                  fieldReq=token
+                  
+                } else if ( token == "="){
+                  save_def_val=1;
+                  push_state("CONST_VALUE_BUILD")
+                  
+                } else if ( token == ")"){
+                  pop_state()
+                  
+                } else if ( token == "map"){
+                  print "map is unsupported"
+                  definition_type_name="dummy";
+                  pop_state()
+                  push_state("THROWSFIELDNAME")
+                  push_state("MAP_END");
+                  
+                } else if ( token == "list"){
+                  pop_state()
+                  push_state("THROWSFIELDNAME")
+                  push_state("LIST_BEGIN");
+                  
+                } else if ( token == "set"){
+                  pop_state()
+                  push_state("THROWSFIELDNAME")
+                  push_state("SET_BEGIN");
+                  
+                } else {
+                  definition_type_name=token;
+                  pop_state()
+                  push_state("THROWSFIELDNAME")
+                  
+                  
+              }
+              
+            } else if (parser_state== "THROWSFIELDNAME"){
+              filed_num++
+              AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "THROWS" SUBSEP filed_num SUBSEP "ID"]=field_id
+              field_id=""
+              if(fieldReq!="optional") {fieldReq="required"}
+              AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "THROWS" SUBSEP filed_num SUBSEP "REQ"]=fieldReq
+              fieldReq=""
+              AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "THROWS" SUBSEP filed_num SUBSEP "TYPE"]=definition_type_name
+              definition_type_name=""
+              AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "THROWS" SUBSEP filed_num SUBSEP "NAME"]=token
+                  pop_state()
+                  push_state("THROWSFIELD")
+              
+            } else if (parser_state== "STRUCTNAME"){
+              if (token == "{") {
+                pop_state()
+                push_state("FIELDTYPE")
+                filed_num=0;
+              } else {
+                struct_name=token
+                AST[t_file SUBSEP struct_execption SUBSEP struct_name SUBSEP "NAME"]=struct_name
+              }
+              
+            } else if (parser_state== "FIELDTYPE"){
+              if(save_def_val == 1){
+                save_def_val=0;
+                AST[t_file SUBSEP struct_execption SUBSEP struct_name SUBSEP "FIELDS" SUBSEP filed_num SUBSEP "DEFVAL"]=builded_const
+                builded_const="";
+              }
+              if ( token ~ /^[0-9+-]+$/ ){
+                  field_id=token
+                  
+                } else if ( token == ":"){ # just skip it
+                  
+                } else if ( token == "optional"){
+                  fieldReq=token
+                } else if ( token == "required"){
+                  fieldReq=token
+                  
+                } else if ( token == "="){
+                  save_def_val=1;
+                  push_state("CONST_VALUE_BUILD")
+                  
+                } else if ( token == "}"){
+                  pop_state()
+                  
+                } else if ( token == "map"){
+                  print "map is unsupported"
+                  definition_type_name="dummy";
+                  pop_state()
+                  push_state("FIELDNAME")
+                  push_state("MAP_END");
+                  
+                } else if ( token == "list"){
+                  pop_state()
+                  push_state("FIELDNAME")
+                  push_state("LIST_BEGIN");
+                  
+                } else if ( token == "set"){
+                  pop_state()
+                  push_state("FIELDNAME")
+                  push_state("SET_BEGIN");
+                  
+                } else {
+                  definition_type_name=token;
+                  pop_state()
+                  push_state("FIELDNAME")
+                 } 
+                  
+              
+            } else if (parser_state== "FIELDNAME"){
+              filed_num++
+              AST[t_file SUBSEP struct_execption SUBSEP struct_name SUBSEP "FIELDS" SUBSEP filed_num SUBSEP "ID"]=field_id
+              field_id=""
+              if(fieldReq!="optional") {fieldReq="required"}
+              AST[t_file SUBSEP struct_execption SUBSEP struct_name SUBSEP "FIELDS" SUBSEP filed_num SUBSEP "REQ"]=fieldReq
+              fieldReq=""
+              AST[t_file SUBSEP struct_execption SUBSEP struct_name SUBSEP "FIELDS" SUBSEP filed_num SUBSEP "TYPE"]=definition_type_name
+              definition_type_name=""
+              AST[t_file SUBSEP struct_execption SUBSEP struct_name SUBSEP "FIELDS" SUBSEP filed_num SUBSEP "NAME"]=token
+                  pop_state()
+                  push_state("FIELDTYPE")
+              
+            } else if (parser_state== "ENUMNAME"){
+              if(token == "{"){
+                pop_state();
+                push_state("ENUM_VALUE")
+              } else {
+                AST[t_file SUBSEP enum_senum SUBSEP token SUBSEP "NAME"]=token
+                enum_name=token
+                enum_id=0
+              }
+              
+            } else if (parser_state== "ENUM_VALUE"){
+              if ( token == "}"){
+                  pop_state();
+                  
+                } else if ( token == "="){
+                  push_state("ENUM_VALUE_VAL");
+                  
+                } else {
+                  enum_id++;
+                  AST[t_file SUBSEP enum_senum SUBSEP enum_name SUBSEP "VALUES" SUBSEP enum_id SUBSEP "NAME"]=token;
+                  
+              }
+              
+            } else if (parser_state== "ENUM_VALUE_VAL"){
+              AST[t_file SUBSEP enum_senum SUBSEP enum_name SUBSEP "VALUES" SUBSEP enum_id SUBSEP "VAL"]=token;
+              pop_state();
+              
+            } else if (parser_state== "CONSTDEF"){
+              if(token == "="){
+                pop_state();
+                push_state("CONST_VALUE")
+              } else {
+                AST[t_file SUBSEP "CONSTS" SUBSEP token SUBSEP "TYPE"]=definition_type_name
+                definition_type_name=""
+                const_name=token
+              }
+              
+            } else if (parser_state== "CONST_VALUE"){
+              if ( token == "{"){
+                  print "Map constatnt is not supported"
+                  pop_state();
+                  push_state("MAP_CONST_END")
+                  
+                } else if ( token == "["){
+                  pop_state();
+                  builded_const="{"
+                  push_state("LIST_CONST_END")
+                  
+                } else {
+                  AST[t_file SUBSEP "CONSTS" SUBSEP const_name SUBSEP "VALUE"]=token
+                  pop_state();
+              }
+              
+            } else if (parser_state== "CONST_VALUE_BUILD"){
+              if ( token == "{"){
+                  print "Map constatnt is not supported"
+                  pop_state();
+                  push_state("MAP_CONST_BUILD_END")
+                  
+                } else if ( token == "["){
+                  pop_state();
+                  push_state("LIST_CONST_BUILD_END")
+                  push_state("CONST_VALUE_BUILD")
+                  
+                } else {
+                  builded_const=token
+                  pop_state();
+              }
+              
+            } else if (parser_state== "MAP_CONST_END"){
+              if(token == "}"){
+                AST[t_file SUBSEP "CONSTS" SUBSEP const_name SUBSEP "VALUE"]="dummy_map_const"
+                pop_state();
+              }
+              
+            } else if (parser_state== "LIST_CONST_END"){
+              if(token == "]"){
+                AST[t_file SUBSEP "CONSTS" SUBSEP const_name SUBSEP "VALUE"]=builded_const"}";
+                pop_state();
+              } else {
+                lb=length(builded_const);
+                if(substr(builded_const,lb,1)=="{"){
+                  comm=""
+                } else {
+                  comm=", "
+                }
+                if ( token == "{"){
+                    print "Map constatnt is not supported"
+                    push_state("MAP_CONST_BUILD_END")
+                    
+                  } else if ( token == "["){
+                    builded_const=comm"{"
+                    push_state("LIST_CONST_BUILD_END")
+                    
+                  } else {
+                    
+                    AST[t_file SUBSEP "CONSTS" SUBSEP const_name SUBSEP "VALUE"]=token
+                    pop_state();
+                }
+              }
+              
+            } else if (parser_state== "LIST_CONST_BUILD_END"){
+              if(token == "}"){
+                builded_const=builded_const"}";
+                pop_state();
+              } else {
+                lb=length(builded_const);
+                if(substr(builded_const,lb,1)=="{"){
+                  comm=""
+                } else {
+                  comm=", "
+                }
+                if ( token == "{"){
+                    print "Map constatnt is not supported"
+                    push_state("MAP_CONST_BUILD_END")
+                    
+                  } else if ( token == "["){
+                    builded_const=comm"{"
+                    push_state("LIST_CONST_BUILD_END")
+                    
+                  } else {
+                    
+                    builded_const=comm token
+                    pop_state();
+                }
+              }
+              
+            } else if (parser_state== "MAP_CONST_BUILD_END"){
+              if(token == "}"){
+                lb=length(builded_const);
+                if(substr(builded_const,lb,1)=="{"){
+                  comm=""
+                } else {
+                  comm=", "
+                }
+                builded_const=comm"dummy_map_const"
+                pop_state();
+              }
+              
+            } else if (parser_state== "INCLUDE"){
+              match(token,/\.thrift/)
+              AST[t_file SUBSEP "INCLUDES" SUBSEP substr(token,1,RSTART-1)]=substr(token,1,RSTART-1)
+              if( ! (token in processed_files )){
+                ARGV[ARGC]=token;
+                ARGC++;
+                processed_files[token]=token
+                AST["FILES" SUBSEP basename(substr(token,1,RSTART-1))]=basename(substr(token,1,RSTART-1));
+              }
+              pop_state();
+              
+            } else if (parser_state== "NAMESPACE"){
+              if(token ~ /[*]|cpp/){
+                push_state("NAMESPACE_ID");
+              } else {
+                push_state("SKIP_1")
+              }
+              
+            } else if (parser_state== "NAMESPACE_ID"){
+              AST[t_file SUBSEP "NAMESPACE"]=token
+
+              start_state();
+              
+            } else if (parser_state== "DEFINITIONTYPE"){
+              if ( token == "map"){
+                  print "map is unsupported"
+                  definition_type_name="dummy";
+                  pop_state()
+                  push_state("MAP_END");
+                  
+                } else if ( token == "list"){
+                  pop_state()
+                  push_state("LIST_BEGIN");
+                  
+                } else if ( token == "set"){
+                  pop_state()
+                  push_state("SET_BEGIN");
+                  
+                } else {
+                  definition_type_name=token;
+                  pop_state()
+              }
+              
+            } else if (parser_state== "LIST_BEGIN"){
+              if(token == "<"){
+                pop_state();
+                push_state("LIST_END")
+                push_state("DEFINITIONTYPE")
+              }
+
+              
+            } else if (parser_state== "SET_BEGIN"){
+              if(token == "<"){
+                pop_state();
+                push_state("SET_END")
+                push_state("DEFINITIONTYPE")
+              }
+
+              
+            } else if (parser_state== "LIST_END"){
+              pop_state();
+              if(token == ">"){
+                AST[t_file SUBSEP "LIST_TYPES" SUBSEP definition_type_name "_list"]=definition_type_name
+                definition_type_name = definition_type_name "_list"
+              } else {
+                printf "invalid token: ", token
+                definition_type_name="dummy";
+              }
+              
+            } else if (parser_state== "SET_END"){
+              pop_state();
+              if(token == ">"){
+                AST[t_file SUBSEP "SET_TYPES" SUBSEP definition_type_name "_set"]=definition_type_name
+                definition_type_name = definition_type_name "_set"
+              } else {
+                printf "invalid token: ", token
+                definition_type_name="dummy";
+              }
+              
+            } else if (parser_state== "MAP_END"){
+              if(token == ">"){
+                pop_state();
+              }
+              
+            } else if (parser_state== "TYPEDEF"){
+              AST[t_file SUBSEP "TYPEDEF" SUBSEP token]=definition_type_name
+              definition_type_name=""
+              pop_state()
+              
+            } else if (parser_state ~ /SKIP_[0-9]+/){
+              num_to_skip=substr(parser_state,6);
+              if(num_to_skip == 1){
+                start_state();
+              } else {
+                pop_state()
+                num_to_skip--
+                push_state("SKIP_"num_to_skip)
+              }
+              
+            } else{
+      # do nothing
+             
+          }
+       }
+#       printf("new state %s \n",parser_state )
+      }
+      $0 = substr($0, RSTART+RLENGTH )  # Remove processed text from the raw data
+#               printf("$0 after = <%s>\n",$0)
+    } else {
+      next;
+    }
+  }
+}
+
+END {
+
+#   walk_array(AST, "AST")
+
+  delete files;
+  get_array_length(AST,files)
+  for(f in files){
+    if(f == "FILES"){
+      continue
+    }
+    
+    file_name= f "_TypesAndPorts.ttcn"
+    print "module " f "_TypesAndPorts {" >  file_name
+
+
+    
+    delete module_data
+    get_subarray(AST,f,module_data);
+    print "" >> file_name
+
+    delete include_data
+    get_subarray(module_data,"INCLUDES",include_data)
+    for(i in include_data){
+      print "  import from " i "_TypesAndPorts all" >> file_name
+    }
+
+    print "  import from Thrift_Common all" >> file_name
+    print "" >> file_name
+    print "  type integer address" >> file_name
+    print "" >> file_name
+    print "// Typedefs" >> file_name
+    
+    delete typedef_data
+    get_subarray(module_data,"TYPEDEF",typedef_data)
+    for(t in typedef_data){
+      print "  type " prefix_type(typedef_data[t],f) " " res_word(t) >> file_name
+    }
+    
+    print "" >> file_name
+    print "// List/Set types" >> file_name
+    
+    delete list_types
+    get_subarray(module_data,"LIST_TYPES",list_types)
+    for(l in list_types){
+      print "  type record of " prefix_type(list_types[l],f) " " l  >> file_name
+    }
+    delete list_types
+    get_subarray(module_data,"SET_TYPES",list_types)
+    for(l in list_types){
+      print "  type set of " prefix_type(list_types[l],f) " " l  >> file_name
+    }
+
+    print "" >> file_name
+    print "// Constants" >> file_name
+    
+    delete const_data
+    get_subarray(module_data,"CONSTS",const_data)
+    delete const_lists
+    get_array_length(const_data,const_lists)
+
+    for(c in const_lists){
+      print "  const " prefix_type(const_data[c SUBSEP "TYPE"],f) " " res_word(c) " := "  const_data[c SUBSEP "VALUE"]>> file_name
+    }
+    
+    print "" >> file_name
+    print "// Enumerations" >> file_name
+    
+    delete enum_data
+    get_subarray(module_data,"ENUMS",enum_data)
+    delete enum_list
+    get_array_length(enum_data,enum_list)
+    for(e in enum_list){
+      print "  type enumerated " res_word(e) " {" >> file_name
+      
+      delete enum_val_list
+      get_subarray(enum_data,e SUBSEP "VALUES",enum_val_list)
+      ev_num=get_array_length(enum_val_list)
+      for ( i=1; i<=ev_num; i++){
+        if(i==ev_num){
+          comm = ""
+        } else {
+          comm =","
+        }
+              if (e SUBSEP "VALUES" SUBSEP i SUBSEP "VAL" in enum_data){
+                print "    " res_word(enum_data[e SUBSEP "VALUES" SUBSEP i SUBSEP "NAME"]) " (" enum_data[e SUBSEP "VALUES" SUBSEP i SUBSEP "VAL"] ")" comm >> file_name
+        } else {
+                print "    " res_word(enum_data[e SUBSEP "VALUES" SUBSEP i SUBSEP "NAME"]) comm >> file_name
+        }
+      }
+      print "  }" >> file_name
+      print "" >> file_name
+      
+    }
+    
+    print "" >> file_name
+    print "// Structs" >> file_name
+    
+    delete struct_data
+    get_subarray(module_data,"STRUCTS",struct_data)
+    delete struct_list
+    get_array_length(struct_data,struct_list)
+    
+    for(s in struct_list){
+      print "  type record " res_word(s) " {" >> file_name
+
+      delete struct_fields
+      get_subarray(struct_data,s SUBSEP "FIELDS",struct_fields)
+      f_num=get_array_length(struct_fields)
+      for ( i=1; i<=f_num; i++){
+        if(i==f_num){
+          comm = ""
+        } else {
+          comm =","
+        }
+        if( struct_fields[i SUBSEP "REQ"] == "optional"){
+          opt=" optional"
+        } else {
+          opt=""
+        }
+        print "    " prefix_type(struct_fields[i SUBSEP "TYPE"],f) " " res_word(struct_fields[i SUBSEP "NAME"]) opt comm>> file_name
+      }
+      print "  }" >> file_name
+      print "" >> file_name
+    }
+    
+    print "" >> file_name
+    print "// Exception types" >> file_name
+    
+    delete struct_data
+    get_subarray(module_data,"EXCEPTIONS",struct_data)
+    delete struct_list
+    get_array_length(struct_data,struct_list)
+    
+    for(s in struct_list){
+      print "  type record " res_word(s) " {" >> file_name
+
+      delete struct_fields
+      get_subarray(struct_data,s SUBSEP "FIELDS",struct_fields)
+      f_num=get_array_length(struct_fields)
+      for ( i=1; i<=f_num; i++){
+        if(i==f_num){
+          comm = ""
+        } else {
+          comm =","
+        }
+        if( struct_fields[i SUBSEP "REQ"] == "optional"){
+          opt=" optional"
+        } else {
+          opt=""
+        }
+        print "    " prefix_type(struct_fields[i SUBSEP "TYPE"],f) " " res_word(struct_fields[i SUBSEP "NAME"]) opt comm>> file_name
+      }
+      print "  }" >> file_name
+      print "" >> file_name
+    }
+    
+    
+    print "" >> file_name
+    print "// Services" >> file_name
+    
+    delete services_data
+    delete services_list
+    get_subarray(module_data,"SERVICES",services_data)
+    get_array_length(services_data,services_list)
+    for(s in services_list){
+      delete serv_data
+      get_subarray(services_data,s,serv_data)
+      print "// Signatures for " s >> file_name
+      gen_service(serv_data,s,f)
+    }
+    
+    print "" >> file_name
+    print "// Port definition for Services" >> file_name
+    print "" >> file_name
+    
+    for(s in services_list){
+      delete serv_data
+      get_subarray(services_data,s,serv_data)
+      print "  type port " s "_PT procedure {"  >> file_name
+      print "    out Thrift_control"  >> file_name
+      gen_port_proc(serv_data,s,f)
+      print "  } with { extension \"address\" }" >> file_name
+      print "" >> file_name
+    }
+    
+    print "} with { encode \"XER\" }" >> file_name
+
+# generate converter functions
+    cc_file_name = f "_Converter.cc"
+    hh_file_name = f "_Converter.hh"
+    
+    if("NAMESPACE" in module_data){
+      cc_namespace=dot_to_colon(module_data["NAMESPACE"] "::")
+    } else {
+      cc_namespace=""
+    }
+    
+    print "#include \"" f "_TypesAndPorts.hh\"" > hh_file_name
+    print "#include \"" f "_types.h\"" > hh_file_name
+    print "#include \"Thrift_Common_Converter.hh\"" > hh_file_name
+    print "#include \"" f "_Converter.hh\"" > cc_file_name
+
+    for(i in include_data){
+      print "#include \"" i "_TypesAndPorts.hh\"" >> hh_file_name
+      print "#include \"" i "_Converter.hh\"" >> hh_file_name
+    }
+    print "" >> cc_file_name
+    print "" >> hh_file_name
+    print "// Enumerations" >> cc_file_name
+    print "// Enumerations" >> hh_file_name
+
+    for(e in enum_list){
+      print "void conv_ttcn_thrift(const " double_und(f) "__TypesAndPorts::" double_und(res_word(e))"& in," cc_namespace e "::type& out);" >> hh_file_name
+      print "void conv_thrift_ttcn(const "  cc_namespace e "::type& in,"double_und(f) "__TypesAndPorts::" double_und(res_word(e))"& out);" >> hh_file_name
+
+      print "void conv_ttcn_thrift(const " double_und(f) "__TypesAndPorts::" double_und(res_word(e))"& in," cc_namespace e "::type& out){" >> cc_file_name
+      print "  out=("cc_namespace e "::type)(int)in;" >> cc_file_name 
+      print "}" >> cc_file_name 
+      print "void conv_thrift_ttcn(const "  cc_namespace e "::type& in,"double_und(f) "__TypesAndPorts::" double_und(res_word(e))"& out){" >> cc_file_name
+      print "  out=(int)in;" >> cc_file_name
+      print "}" >> cc_file_name 
+    }
+    delete list_types
+    get_subarray(module_data,"LIST_TYPES",list_types)
+    for(l in list_types){
+      if(is_basetype(list_types[l],f)!=0){
+        lt=get_basetype(list_types[l])
+      } else {
+        lt=cc_namespace list_types[l]
+      }
+      print "void conv_ttcn_thrift(const " double_und(f) "__TypesAndPorts::" double_und(res_word(l))"& in, std::vector<" lt ">& out);" >> hh_file_name
+      print "void conv_thrift_ttcn(const std::vector<"  lt ">& in,"double_und(f) "__TypesAndPorts::" double_und(res_word(l))"& out);" >> hh_file_name
+      print "void conv_ttcn_thrift(const " double_und(f) "__TypesAndPorts::" double_und(res_word(l))"& in, std::vector<" lt ">& out){" >> cc_file_name
+      print "  out.empty();" >> cc_file_name
+      print "  size_t s=in.size_of();" >> cc_file_name
+      print "  if(s>0){" >> cc_file_name
+      print "    out.resize(s);" >> cc_file_name
+      print "    for(size_t i=s;i>0; i--){" >> cc_file_name
+      print "      conv_ttcn_thrift(in[i-1],out[i-1]);" >> cc_file_name
+      print "    }" >> cc_file_name
+      print "  }" >> cc_file_name
+
+      print "}" >> cc_file_name 
+      print "void conv_thrift_ttcn(const std::vector<"  lt ">& in,"double_und(f) "__TypesAndPorts::" double_und(res_word(l))"& out){" >> cc_file_name
+      print "  out=NULL_VALUE;" >> cc_file_name
+      print "  for(size_t i=in.size();i>0; i--){" >> cc_file_name
+      print "    conv_thrift_ttcn(in[i-1],out[i-1]);" >> cc_file_name
+      print "  }" >> cc_file_name
+      print "}" >> cc_file_name 
+    }
+    delete list_types
+    get_subarray(module_data,"SET_TYPES",list_types)
+    for(l in list_types){
+      if(is_basetype(list_types[l],f)!=0){
+        lt=get_basetype(list_types[l])
+      } else {
+        lt=cc_namespace list_types[l]
+      }
+      print "void conv_ttcn_thrift(const " double_und(f) "__TypesAndPorts::" double_und(res_word(l))"& in, std::set<" lt ">& out);" >> hh_file_name
+      print "void conv_thrift_ttcn(const std::set<"  lt ">& in,"double_und(f) "__TypesAndPorts::" double_und(res_word(l))"& out);" >> hh_file_name
+
+      print "void conv_ttcn_thrift(const " double_und(f) "__TypesAndPorts::" double_und(res_word(l))"& in, std::set<" lt ">& out){" >> cc_file_name
+      print "}" >> cc_file_name 
+      print "void conv_thrift_ttcn(const std::set<"  lt ">& in,"double_und(f) "__TypesAndPorts::" double_und(res_word(l))"& out){" >> cc_file_name
+      print "  out=NULL_VALUE;" >> cc_file_name
+      print "  std::set<" lt ">::iterator it=in.begin();" >> cc_file_name
+      print "  for(size_t i=in.size();i>0; i--){" >> cc_file_name
+      print "    conv_thrift_ttcn(*it,out[i-1]);" >> cc_file_name
+      print "    it++;" >> cc_file_name
+      print "  }" >> cc_file_name
+      print "}" >> cc_file_name 
+
+    }
+
+    delete struct_data
+    get_subarray(module_data,"STRUCTS",struct_data)
+    delete struct_list
+    get_array_length(struct_data,struct_list)
+    
+    for(s in struct_list){
+      print "void conv_ttcn_thrift(const " double_und(f) "__TypesAndPorts::" double_und(res_word(s))"& in, " cc_namespace s "& out);" >> hh_file_name
+      print "void conv_thrift_ttcn(const "  cc_namespace s "& in,"double_und(f) "__TypesAndPorts::" double_und(res_word(s))"& out);" >> hh_file_name
+
+      print "void conv_ttcn_thrift(const " double_und(f) "__TypesAndPorts::" double_und(res_word(s))"& in, " cc_namespace s "& out){" >> cc_file_name
+
+      delete struct_fields
+      get_subarray(struct_data,s SUBSEP "FIELDS",struct_fields)
+      f_num=get_array_length(struct_fields)
+      for ( i=1; i<=f_num; i++){
+        if( struct_fields[i SUBSEP "REQ"] == "optional"){
+          print "  if( in."double_und(res_word(struct_fields[i SUBSEP "NAME"]))"().ispresent()){" >> cc_file_name  
+          print "    conv_ttcn_thrift( in." double_und(res_word(struct_fields[i SUBSEP "NAME"])) "()(),out." struct_fields[i SUBSEP "NAME"] ");" >> cc_file_name
+          print "    out.__isset." struct_fields[i SUBSEP "NAME"]"=true;" >> cc_file_name
+          print "  } else {" >> cc_file_name 
+          print "    out.__isset." struct_fields[i SUBSEP "NAME"]"=false;" >> cc_file_name
+          print "  }" >> cc_file_name 
+        } else {
+          print "  conv_ttcn_thrift( in." double_und(res_word(struct_fields[i SUBSEP "NAME"])) "(),out." struct_fields[i SUBSEP "NAME"] ");" >> cc_file_name
+        }
+      }
+      print "}" >> cc_file_name 
+      print "void conv_thrift_ttcn(const "  cc_namespace s "& in,"double_und(f) "__TypesAndPorts::" double_und(res_word(s))"& out){" >> cc_file_name
+      for ( i=1; i<=f_num; i++){
+        if( struct_fields[i SUBSEP "REQ"] == "optional"){
+          print "  if( in.__isset."struct_fields[i SUBSEP "NAME"]"){" >> cc_file_name  
+          print "    conv_thrift_ttcn( in." struct_fields[i SUBSEP "NAME"]   ",out." double_und(res_word(struct_fields[i SUBSEP "NAME"]))"()());" >> cc_file_name
+          print "  } else {" >> cc_file_name 
+          print "    out." double_und(res_word(struct_fields[i SUBSEP "NAME"]))"()=OMIT_VALUE;" >> cc_file_name
+          print "  }" >> cc_file_name 
+        } else {
+          print "  conv_thrift_ttcn( in." struct_fields[i SUBSEP "NAME"]   ",out." double_und(res_word(struct_fields[i SUBSEP "NAME"]))"());" >> cc_file_name
+        }
+      }
+      print "}" >> cc_file_name 
+      
+    }
+    delete struct_data
+    get_subarray(module_data,"EXCEPTIONS",struct_data)
+    delete struct_list
+    get_array_length(struct_data,struct_list)
+    
+    for(s in struct_list){
+      print "void conv_ttcn_thrift(const " double_und(f) "__TypesAndPorts::" double_und(res_word(s))"& in, " cc_namespace s "& out);" >> hh_file_name
+      print "void conv_thrift_ttcn(const "  cc_namespace s "& in,"double_und(f) "__TypesAndPorts::" double_und(res_word(s))"& out);" >> hh_file_name
+
+      print "void conv_ttcn_thrift(const " double_und(f) "__TypesAndPorts::" double_und(res_word(s))"& in, " cc_namespace s "& out){" >> cc_file_name
+      delete struct_fields
+      get_subarray(struct_data,s SUBSEP "FIELDS",struct_fields)
+      f_num=get_array_length(struct_fields)
+      for ( i=1; i<=f_num; i++){
+        if( struct_fields[i SUBSEP "REQ"] == "optional"){
+          print "  if( in."double_und(res_word(struct_fields[i SUBSEP "NAME"]))"().ispresent()){" >> cc_file_name  
+          print "    conv_ttcn_thrift( in." double_und(res_word(struct_fields[i SUBSEP "NAME"])) "()(),out." struct_fields[i SUBSEP "NAME"] ");" >> cc_file_name
+          print "    out.__isset." struct_fields[i SUBSEP "NAME"]"=true;" >> cc_file_name
+          print "  } else {" >> cc_file_name 
+          print "    out.__isset." struct_fields[i SUBSEP "NAME"]"=false;" >> cc_file_name
+          print "  }" >> cc_file_name 
+        } else {
+          print "  conv_ttcn_thrift( in." double_und(res_word(struct_fields[i SUBSEP "NAME"])) "(),out." struct_fields[i SUBSEP "NAME"] ");" >> cc_file_name
+        }
+      }
+      print "}" >> cc_file_name 
+      print "void conv_thrift_ttcn(const "  cc_namespace s "& in,"double_und(f) "__TypesAndPorts::" double_und(res_word(s))"& out){" >> cc_file_name
+      for ( i=1; i<=f_num; i++){
+        if( struct_fields[i SUBSEP "REQ"] == "optional"){
+          print "  if( in.__isset."struct_fields[i SUBSEP "NAME"]"){" >> cc_file_name  
+          print "    conv_thrift_ttcn( in." struct_fields[i SUBSEP "NAME"]   ",out." double_und(res_word(struct_fields[i SUBSEP "NAME"]))"()());" >> cc_file_name
+          print "  } else {" >> cc_file_name 
+          print "    out." double_und(res_word(struct_fields[i SUBSEP "NAME"]))"()=OMIT_VALUE;" >> cc_file_name
+          print "  }" >> cc_file_name 
+        } else {
+          print "  conv_thrift_ttcn( in." struct_fields[i SUBSEP "NAME"]   ",out." double_und(res_word(struct_fields[i SUBSEP "NAME"]))"());" >> cc_file_name
+        }
+      }
+      print "}" >> cc_file_name 
+      
+     
+
+    }
+    ## test port files
+
+    for(s in services_list){
+      delete serv_data
+      get_subarray(services_data,s,serv_data)
+      cc_file_name=s"_PT.cc"
+      hh_file_name=s"_PT.hh"
+      
+      ## _PT.hh
+
+      print "#ifndef "s"__PT_HH" > hh_file_name
+      print "#define "s"__PT_HH" >> hh_file_name
+
+      print "#include <arpa/inet.h>" >> hh_file_name
+      print "#include <pthread.h>" >> hh_file_name
+      print "#include \""f"_TypesAndPorts.hh\"" >> hh_file_name
+      print "#include \""f"_Converter.hh\"" >> hh_file_name
+      print "#include \""f"_types.h\"" >> hh_file_name
+      print "#include \""s".h\"" >> hh_file_name
+      print "" >> hh_file_name
+      print "#include <thrift/protocol/TBinaryProtocol.h>" >> hh_file_name
+      print "#include <thrift/transport/TServerSocket.h>" >> hh_file_name
+      print "#include <thrift/transport/TBufferTransports.h>" >> hh_file_name
+      print "#include <thrift/transport/TSocket.h>" >> hh_file_name
+      print "#include " myserver_include >> hh_file_name
+      print "" >> hh_file_name
+      print "namespace "double_und(f)"__TypesAndPorts {" >> hh_file_name
+      print "" >> hh_file_name
+      print "class "s"Handler : virtual public ::" cc_namespace s "If {" >> hh_file_name
+      print " public:" >> hh_file_name
+      print "  "s"Handler(const char *);" >> hh_file_name
+      print "  ~"s"Handler();" >> hh_file_name
+      print "  const char *uds_name;" >> hh_file_name
+      print "" >> hh_file_name
+      print "  int connect();" >> hh_file_name
+      print "  void* get_data();" >> hh_file_name
+
+      gen_service_hh(serv_data,s,f)
+
+      print "};" >> hh_file_name
+
+      print "" >> hh_file_name
+      print "class "double_und(s)"__PT : public "double_und(s)"__PT_BASE {" >> hh_file_name
+      print "public:" >> hh_file_name
+      print "  "double_und(s)"__PT(const char *par_port_name = NULL);" >> hh_file_name
+      print "  ~"double_und(s)"__PT();" >> hh_file_name
+      print "" >> hh_file_name
+      print "  void set_parameter(const char *parameter_name," >> hh_file_name
+      print "    const char *parameter_value);" >> hh_file_name
+      print "" >> hh_file_name
+      print "  void Handle_Fd_Event_Error(int fd);" >> hh_file_name
+      print "  void Handle_Fd_Event_Writable(int fd);" >> hh_file_name
+      print "  void Handle_Fd_Event_Readable(int fd);" >> hh_file_name
+      print "" >> hh_file_name
+      print "  char *uds_name;" >> hh_file_name
+      print "  int server_socket;" >> hh_file_name
+      print "  " >> hh_file_name
+      print "  ::std::set<int> clients;" >> hh_file_name
+      print "  ::std::map<int,void*> client_data;" >> hh_file_name
+      print "  " >> hh_file_name
+      print "  int port_mode; // 0-not set, 1-client, 2-server" >> hh_file_name
+      print "" >> hh_file_name
+      print "  boost::shared_ptr<"s"Handler> service_handler;" >> hh_file_name
+      print "  boost::shared_ptr< ::apache::thrift::TProcessor> server_processor;" >> hh_file_name
+      print "  boost::shared_ptr< ::apache::thrift::transport::TServerTransport> server_Transport;" >> hh_file_name
+      print "  boost::shared_ptr< ::apache::thrift::transport::TTransportFactory> server_transportFactory;" >> hh_file_name
+      print "  boost::shared_ptr< ::apache::thrift::protocol::TProtocolFactory> server_protocolFactory;" >> hh_file_name
+      print "  boost::shared_ptr< ::apache::thrift::transport::TSocket> client_socket;" >> hh_file_name
+      print "  boost::shared_ptr< ::apache::thrift::transport::TTransport> client_transport;" >> hh_file_name
+      print "  boost::shared_ptr< ::apache::thrift::protocol::TProtocol> client_protocol;" >> hh_file_name
+      print "" >> hh_file_name
+      print "  ::apache::thrift::server::" myserver_name " *server_handler;" >> hh_file_name
+      print "  "cc_namespace s"Client *client_handler;" >> hh_file_name
+      print "" >> hh_file_name
+      print "  void clean_up();" >> hh_file_name
+      print "  pthread_t server_thread;" >> hh_file_name
+      print "protected:" >> hh_file_name
+      print "  void user_map(const char *system_port);" >> hh_file_name
+      print "  void user_unmap(const char *system_port);" >> hh_file_name
+      print "" >> hh_file_name
+      print "  void user_start();" >> hh_file_name
+      print "  void user_stop();" >> hh_file_name
+      print "" >> hh_file_name
+      print "  void outgoing_call(const Thrift__Common::Thrift__control_call& call_par," >> hh_file_name
+      print "    const INTEGER *destination_address);" >> hh_file_name
+      print "" >> hh_file_name
+      gen_outgoing_hh(serv_data,s,f)
+      print "};" >> hh_file_name
+      print "" >> hh_file_name
+      print "}" >> hh_file_name
+      print "#endif" >> hh_file_name
+
+      ## _PT.cc
+      print "#include <stdio.h>" > cc_file_name
+      print "#include <sys/socket.h>" >> cc_file_name
+      print "#include <sys/un.h>" >> cc_file_name
+      print "#include <unistd.h>" >> cc_file_name
+      print "#include <string.h>" >> cc_file_name
+      print "#include <errno.h>" >> cc_file_name
+      print "" >> cc_file_name
+      print "#include \"" s "_PT.hh\"" >> cc_file_name
+      print "" >> cc_file_name
+      print "using namespace ::apache::thrift;" >> cc_file_name
+      print "using namespace ::apache::thrift::protocol;" >> cc_file_name
+      print "using namespace ::apache::thrift::transport;" >> cc_file_name
+      print "using namespace ::apache::thrift::server;" >> cc_file_name
+      print "using boost::shared_ptr;" >> cc_file_name
+      print "using namespace Thrift__Common;" >> cc_file_name
+      print "namespace "double_und(f)"__TypesAndPorts {" >> cc_file_name
+      print s "Handler::"s"Handler(const char *uds){" >> cc_file_name
+      print "  uds_name=uds;" >> cc_file_name
+      print "}" >> cc_file_name
+      print s "Handler::~"s"Handler(){}" >> cc_file_name 
+      print "" >> cc_file_name
+      print "int "s"Handler::connect(){" >> cc_file_name
+      print "        struct sockaddr_un serv_addr;" >> cc_file_name
+      print "" >> cc_file_name
+      print "        memset(&serv_addr, 0, sizeof(struct sockaddr_un));" >> cc_file_name
+      print "        serv_addr.sun_family = AF_UNIX;" >> cc_file_name
+      print "        strcpy(serv_addr.sun_path, uds_name);" >> cc_file_name
+      print "        int len=strlen(serv_addr.sun_path) + sizeof(serv_addr.sun_family);" >> cc_file_name
+      print "#ifdef LINUX" >> cc_file_name
+      print "          serv_addr.sun_path[0]='\\0';" >> cc_file_name
+      print "#endif" >> cc_file_name
+      print "        int client_socket = socket(PF_UNIX, SOCK_STREAM, 0);" >> cc_file_name
+      print "        ::connect(client_socket,(const sockaddr*)&serv_addr,len);" >> cc_file_name
+      print "        " >> cc_file_name
+      print "        return client_socket;  " >> cc_file_name
+      print "}" >> cc_file_name
+      gen_service_cc(serv_data,s,f,0)
+
+      print "" >> cc_file_name
+
+      print "void "s"__PT::clean_up(){" >> cc_file_name
+      print "  if(port_mode==1){" >> cc_file_name
+      print "    client_transport->close();" >> cc_file_name
+      print "    delete client_handler;" >> cc_file_name
+      print "    client_protocol.reset();" >> cc_file_name
+      print "    client_transport.reset();" >> cc_file_name
+      print "    client_socket.reset();" >> cc_file_name
+      print "    port_mode=0;" >> cc_file_name
+      print "  } else if(port_mode ==2) {" >> cc_file_name
+      print "    server_handler->stop();" >> cc_file_name
+      print "    void *a;" >> cc_file_name 
+      print "    pthread_join(server_thread,&a);" >> cc_file_name
+      print "    delete server_handler;" >> cc_file_name
+      print "    server_protocolFactory.reset();" >> cc_file_name
+      print "    server_transportFactory.reset();" >> cc_file_name
+      print "    server_Transport.reset();" >> cc_file_name
+      print "    server_processor.reset();" >> cc_file_name
+      print "    service_handler.reset();" >> cc_file_name
+      print "    Handler_Remove_Fd_Read(server_socket);" >> cc_file_name
+      print "    close(server_socket);" >> cc_file_name
+      print "    server_socket=-1;" >> cc_file_name
+      print "  }" >> cc_file_name
+      print "  if(uds_name){" >> cc_file_name
+      print "#ifndef LINUX" >> cc_file_name
+      print "    unlink(uds_name);" >> cc_file_name
+      print "#endif" >> cc_file_name
+      print "    Free(uds_name);" >> cc_file_name
+      print "    uds_name=NULL;" >> cc_file_name
+      print "  }" >> cc_file_name
+      print "  port_mode=0;" >> cc_file_name
+      print "}" >> cc_file_name
+      print "" >> cc_file_name
+      print ""double_und(s)"__PT::"double_und(s)"__PT(const char *par_port_name)" >> cc_file_name
+      print "  : "double_und(s)"__PT_BASE(par_port_name)" >> cc_file_name
+      print "{" >> cc_file_name
+      print "  server_socket=-1;" >> cc_file_name
+      print "  port_mode=0;" >> cc_file_name
+      print "  client_handler=NULL;" >> cc_file_name
+      print "  uds_name=NULL;" >> cc_file_name
+      print "}" >> cc_file_name
+      print "" >> cc_file_name
+      print ""double_und(s)"__PT::~"double_und(s)"__PT()" >> cc_file_name
+      print "{" >> cc_file_name
+      print " clean_up(); " >> cc_file_name
+      print "}" >> cc_file_name
+      print "" >> cc_file_name
+      print "void "double_und(s)"__PT::set_parameter(const char * /*parameter_name*/," >> cc_file_name
+      print "  const char * /*parameter_value*/)" >> cc_file_name
+      print "{" >> cc_file_name
+      print "" >> cc_file_name
+      print "}" >> cc_file_name
+
+      print "" >> cc_file_name
+      print "void "double_und(s)"__PT::Handle_Fd_Event_Error(int /*fd*/)" >> cc_file_name
+      print "{" >> cc_file_name
+      print "" >> cc_file_name
+      print "}" >> cc_file_name
+      print "" >> cc_file_name
+      print "void "double_und(s)"__PT::Handle_Fd_Event_Writable(int /*fd*/)" >> cc_file_name
+      print "{" >> cc_file_name
+
+      print "}" >> cc_file_name
+      print "" >> cc_file_name
+      print "void "double_und(s)"__PT::Handle_Fd_Event_Readable(int fd)" >> cc_file_name
+      print "{" >> cc_file_name
+      print "" >> cc_file_name
+      print "  if(fd==server_socket){" >> cc_file_name
+      print "    struct sockaddr_un client_addr;" >> cc_file_name
+      print "    memset(&client_addr, 0, sizeof(struct sockaddr_un));" >> cc_file_name
+      print "    socklen_t client_addr_len;" >> cc_file_name
+      print "    int new_socket=accept(fd,(struct sockaddr *) &client_addr,&client_addr_len);" >> cc_file_name
+      print "    Handler_Add_Fd_Read(new_socket);" >> cc_file_name
+      print "    clients.insert(new_socket);" >> cc_file_name
+      print "    " >> cc_file_name
+      print "  } else {" >> cc_file_name
+      print "    void *read_data;" >> cc_file_name
+      print "    int read_len=read(fd,&read_data,sizeof(read_data));" >> cc_file_name
+      print "" >> cc_file_name
+      print "    if(read_len>0){" >> cc_file_name
+      print "      int func_num=((struct internal_comm_struct*)read_data)->code;" >> cc_file_name
+      print "      client_data.insert(std::pair<int,void*>(fd,read_data));" >> cc_file_name
+      print "      INTEGER addr=fd;" >> cc_file_name
+      print "      void **_push_data=((struct internal_comm_struct*)read_data)->data;" >> cc_file_name
+      print "      switch(func_num){" >> cc_file_name
+
+      gen_service_event_call_cc(serv_data,s,f,0)
+
+      print "        default:" >> cc_file_name
+      print "          break;" >> cc_file_name
+      print "      }" >> cc_file_name
+      print "      return;" >> cc_file_name
+      print "    } else {" >> cc_file_name
+      print "      Handler_Remove_Fd_Read(fd);" >> cc_file_name
+      print "      clients.erase(fd);" >> cc_file_name
+      print "      close(fd);" >> cc_file_name
+      print "    }" >> cc_file_name
+      print "  }" >> cc_file_name
+
+
+      print "}" >> cc_file_name
+      print "" >> cc_file_name
+
+      print "void "double_und(s)"__PT::user_map(const char * /*system_port*/)" >> cc_file_name
+      print "{" >> cc_file_name
+      print "" >> cc_file_name
+      print "}" >> cc_file_name
+
+      print "void "double_und(s)"__PT::user_unmap(const char * /*system_port*/)" >> cc_file_name
+      print "{" >> cc_file_name
+      print " clean_up(); " >> cc_file_name
+
+      print "}" >> cc_file_name
+
+      print "void "double_und(s)"__PT::user_start()" >> cc_file_name
+      print "{" >> cc_file_name
+
+      print "}" >> cc_file_name
+
+      print "void "double_und(s)"__PT::user_stop()" >> cc_file_name
+      print "{" >> cc_file_name
+
+      print "}" >> cc_file_name
+
+      print "static void *server_runner_main( void * ptr){" >> cc_file_name
+      print "  (("double_und(s)"__PT*)ptr)->server_handler->serve();" >> cc_file_name
+      print "  return NULL;" >> cc_file_name
+      print "}" >> cc_file_name
+      print "" >> cc_file_name
+
+
+      print "void "double_und(s)"__PT::outgoing_call(const Thrift__Common::Thrift__control_call& call_par," >> cc_file_name
+      print "  const INTEGER * /*destination_address*/)" >> cc_file_name
+      print "{" >> cc_file_name
+      print "  Thrift__Common::Thrift__control_reply reply;" >> cc_file_name
+      print "  if(port_mode && call_par.operation()!=Thrift__Common::Thrift__port__operation::OP__CLOSE){" >> cc_file_name
+      print "    reply.return_value().result__code()=Thrift__Common::Thrift__control__code::CTRL__RES__ERR;" >> cc_file_name
+      print "    reply.return_value().result__desc()().error__code()=1;" >> cc_file_name
+      print "    reply.return_value().result__desc()().error__text()=\"The port is aleady connected\";" >> cc_file_name
+      print "    incoming_reply(reply,NULL);" >> cc_file_name
+      print "    return;" >> cc_file_name
+      print "  }" >> cc_file_name
+  
+      print "  switch(call_par.operation()){" >> cc_file_name
+      print "    case Thrift__Common::Thrift__port__operation::OP__CLOSE:" >> cc_file_name
+      print "      clean_up(); " >> cc_file_name
+      print "      reply.return_value().result__code()=Thrift__Common::Thrift__control__code::CRTL__RES__OK;" >> cc_file_name
+      print "      reply.return_value().result__desc()=OMIT_VALUE;" >> cc_file_name
+      print "      break;" >> cc_file_name
+      print "    case Thrift__Common::Thrift__port__operation::OP__OPEN:" >> cc_file_name
+      print "      if(call_par.port__mode() == Thrift__Common::Thrift__port__mode::MODE__CLIENT){" >> cc_file_name
+      print "        if(call_par.conn__data().transport()().get_selection()==Thrift__Common::Thrift__transport__data::ALT_socket){" >> cc_file_name
+      print "          client_socket.reset(new ::apache::thrift::transport::TSocket(" >> cc_file_name
+      print "                                   call_par.conn__data().transport()().socket().host__name().ispresent()?(const char*)call_par.conn__data().transport()().socket().host__name()():\"localhost\"," >> cc_file_name
+      print "                                   (int)call_par.conn__data().transport()().socket().port__num()" >> cc_file_name
+      print "                                                             ));" >> cc_file_name
+      print "         client_transport.reset(new ::apache::thrift::transport::TBufferedTransport(client_socket)) ;" >> cc_file_name
+      print "        } else if(call_par.conn__data().transport()().get_selection()==Thrift__Common::Thrift__transport__data::ALT_framed){" >> cc_file_name
+      print "          client_socket.reset(new ::apache::thrift::transport::TSocket(" >> cc_file_name
+      print "                                   call_par.conn__data().transport()().framed().host__name().ispresent()?(const char*)call_par.conn__data().transport()().framed().host__name()():\"localhost\"," >> cc_file_name
+      print "                                   (int)call_par.conn__data().transport()().framed().port__num()" >> cc_file_name
+      print "                                                             ));" >> cc_file_name
+      print "         client_transport.reset(new ::apache::thrift::transport::TFramedTransport(client_socket)) ;" >> cc_file_name
+      print "        }" >> cc_file_name
+      print "        if(call_par.conn__data().protocol()().get_selection()==Thrift__Common::Thrift__protocol__data::ALT_binary){" >> cc_file_name
+      print "          client_protocol.reset(new ::apache::thrift::protocol::TBinaryProtocol(client_transport));" >> cc_file_name
+      print "        }" >> cc_file_name
+      print "        client_handler=new "cc_namespace s"Client(client_protocol);" >> cc_file_name
+      print "        " >> cc_file_name
+      print "        try{" >> cc_file_name
+      print "          client_transport->open();" >> cc_file_name
+      print "        } catch (...) {" >> cc_file_name
+      print "          delete client_handler;" >> cc_file_name
+      print "          client_protocol.reset();" >> cc_file_name
+      print "          client_transport.reset();" >> cc_file_name
+      print "          client_socket.reset();" >> cc_file_name
+      print "          reply.return_value().result__code()=Thrift__Common::Thrift__control__code::CTRL__RES__ERR;" >> cc_file_name
+      print "          reply.return_value().result__desc()().error__code()=1;" >> cc_file_name
+      print "          reply.return_value().result__desc()().error__text()=\"There is an error reported by the Thrift\";" >> cc_file_name
+      print "          incoming_reply(reply,NULL);" >> cc_file_name
+      print "          return;" >> cc_file_name
+      print "        }" >> cc_file_name
+      print "        " >> cc_file_name
+      print "        reply.return_value().result__code()=Thrift__Common::Thrift__control__code::CRTL__RES__OK;" >> cc_file_name
+      print "        reply.return_value().result__desc()=OMIT_VALUE;" >> cc_file_name
+      print "        port_mode=1;" >> cc_file_name
+      print "      } else {" >> cc_file_name
+      print "        if(!uds_name){" >> cc_file_name
+      print "#ifdef LINUX" >> cc_file_name
+      print "          uds_name=mprintf(\"#thriftPTXXXXXX\");" >> cc_file_name
+      print "#else" >> cc_file_name
+      print "          uds_name=mprintf(\"/tmp/thriftPTXXXXXX\");" >> cc_file_name
+      print "#endif" >> cc_file_name
+      print "          mktemp(uds_name);" >> cc_file_name
+      print "        }" >> cc_file_name
+      print "        struct sockaddr_un serv_addr;" >> cc_file_name
+      print "" >> cc_file_name
+      print "        memset(&serv_addr, 0, sizeof(struct sockaddr_un));" >> cc_file_name
+      print "        serv_addr.sun_family = AF_UNIX;" >> cc_file_name
+      print "        strcpy(serv_addr.sun_path, uds_name);" >> cc_file_name
+      print "        int len=strlen(serv_addr.sun_path) + sizeof(serv_addr.sun_family);" >> cc_file_name
+      print "#ifdef LINUX" >> cc_file_name
+      print "          serv_addr.sun_path[0]='\\0';" >> cc_file_name
+      print "#else" >> cc_file_name
+      print "          unlink(uds_name);" >> cc_file_name
+      print "#endif" >> cc_file_name
+      print "        server_socket = socket(PF_UNIX, SOCK_STREAM, 0);" >> cc_file_name
+      print "        if(bind(server_socket, (struct sockaddr *)&serv_addr, len) == -1){" >> cc_file_name
+      print "          reply.return_value().result__code()=Thrift__Common::Thrift__control__code::CTRL__RES__ERR;" >> cc_file_name
+      print "          reply.return_value().result__desc()().error__code()=errno;" >> cc_file_name
+      print "          reply.return_value().result__desc()().error__text()=strerror(errno);" >> cc_file_name
+      print "          incoming_reply(reply,NULL);" >> cc_file_name
+      print "          close(server_socket);" >> cc_file_name
+      print "          server_socket=-1;" >> cc_file_name
+      print "          Free(uds_name);" >> cc_file_name
+      print "          uds_name=NULL;" >> cc_file_name
+      print "          return;" >> cc_file_name
+      print "        }" >> cc_file_name
+      print "        if(listen(server_socket, 10) == -1){" >> cc_file_name
+      print "          reply.return_value().result__code()=Thrift__Common::Thrift__control__code::CTRL__RES__ERR;" >> cc_file_name
+      print "          reply.return_value().result__desc()().error__code()=errno;" >> cc_file_name
+      print "          reply.return_value().result__desc()().error__text()=strerror(errno);" >> cc_file_name
+      print "          incoming_reply(reply,NULL);" >> cc_file_name
+      print "          close(server_socket);" >> cc_file_name
+      print "          server_socket=-1;" >> cc_file_name
+      print "          Free(uds_name);" >> cc_file_name
+      print "          uds_name=NULL;" >> cc_file_name
+      print "          return;" >> cc_file_name
+      print "        }" >> cc_file_name
+      print "        Handler_Add_Fd_Read(server_socket);" >> cc_file_name
+      print "" >> cc_file_name
+      print "        if(call_par.conn__data().transport()().get_selection()==Thrift__Common::Thrift__transport__data::ALT_socket){" >> cc_file_name
+      print "          server_Transport.reset(new TServerSocket((int)call_par.conn__data().transport()().socket().port__num()));" >> cc_file_name
+      print "          server_transportFactory.reset(new TBufferedTransportFactory());" >> cc_file_name
+      print "        } else if(call_par.conn__data().transport()().get_selection()==Thrift__Common::Thrift__transport__data::ALT_framed){" >> cc_file_name
+      print "          server_Transport.reset(new TServerSocket((int)call_par.conn__data().transport()().framed().port__num()));" >> cc_file_name
+      print "          server_transportFactory.reset(new TFramedTransportFactory());" >> cc_file_name
+      print "        }" >> cc_file_name
+      print "        if(call_par.conn__data().protocol()().get_selection()==Thrift__Common::Thrift__protocol__data::ALT_binary){" >> cc_file_name
+      print "          server_protocolFactory.reset(new TBinaryProtocolFactory());" >> cc_file_name
+      print "        }" >> cc_file_name
+      print "" >> cc_file_name
+      print "        service_handler.reset(new "s"Handler(uds_name));" >> cc_file_name
+      print "        server_processor.reset(new " cc_namespace s"Processor(service_handler));" >> cc_file_name
+      print "        " >> cc_file_name
+      print "        reply.return_value().result__code()=Thrift__Common::Thrift__control__code::CRTL__RES__OK;" >> cc_file_name
+      print "        reply.return_value().result__desc()=OMIT_VALUE;" >> cc_file_name
+      print "        server_handler=new "myserver_name"(server_processor,server_Transport,server_transportFactory,server_protocolFactory);" >> cc_file_name
+      print "" >> cc_file_name
+      print "        port_mode=2;" >> cc_file_name
+      print "        pthread_create(&server_thread,NULL,server_runner_main,this);" >> cc_file_name
+      print "      }" >> cc_file_name
+      print "" >> cc_file_name
+      print "      break;" >> cc_file_name
+      print "    default:" >> cc_file_name
+      print "      break;" >> cc_file_name
+      print "  }" >> cc_file_name
+      print "  incoming_reply(reply,NULL);" >> cc_file_name
+      print "" >> cc_file_name
+      print "}" >> cc_file_name
+      print "" >> cc_file_name
+
+      gen_service_outgoing_cc(serv_data,s,f,0)
+
+      print "} // namespace" >> cc_file_name
+    }
+
+  } ## for(f in files)
+  
+  
+}
diff --git a/src/Thrift_Common.ttcn b/src/Thrift_Common.ttcn
new file mode 100644
index 0000000..04eef1b
--- /dev/null
+++ b/src/Thrift_Common.ttcn
@@ -0,0 +1,59 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+///////////////////////////////////////////////////////////////////////////////
+
+module Thrift_Common{
+
+  type boolean bool
+  type integer byte
+  type integer i16
+  type integer i32
+  type integer i64
+  type charstring string
+  type octetstring binary
+
+  type enumerated Thrift_port_operation { OP_OPEN(0),OP_CLOSE(1) }
+  type enumerated Thrift_port_mode { MODE_CLIENT(0),MODE_SERVER(1) }
+  type record Thrift_conn_data {
+    Thrift_transport_data  transport optional,
+    Thrift_protocol_data   protocol optional
+  }
+  
+  type union Thrift_transport_data{
+    Thrift_socket_transport  socket,
+    Thrift_socket_transport  framed
+  }
+  
+  type union Thrift_protocol_data{
+    Thrift_binary_protocol binary
+  }
+  
+  type record Thrift_socket_transport {
+    charstring   host_name optional,
+    integer      port_num
+  }
+  
+  type record Thrift_binary_protocol {
+  }
+  
+  type enumerated Thrift_control_code{ CRTL_RES_OK(0), CTRL_RES_FAIL(1), CTRL_RES_ERR(2)}
+  type record Thrift_control_result {
+    Thrift_control_code result_code,
+    Thrift_port_error   result_desc optional
+  }
+  
+  signature Thrift_control(in Thrift_port_operation operation,
+                           in Thrift_port_mode port_mode,
+                           in Thrift_conn_data conn_data) return Thrift_control_result
+                           
+
+  type record Thrift_port_error{
+    integer error_code,
+    charstring error_text
+  }
+
+}
diff --git a/src/Thrift_Common_Converter.cc b/src/Thrift_Common_Converter.cc
new file mode 100644
index 0000000..6ea5855
--- /dev/null
+++ b/src/Thrift_Common_Converter.cc
@@ -0,0 +1,59 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+//////////////////////////////////////////////////////////////////////////////
+
+
+#include "Thrift_Common.hh"
+#include "Thrift_Common_Converter.hh"
+
+void conv_ttcn_thrift(const Thrift__Common::bool_& in,bool& out){
+  out=in;
+}
+void conv_ttcn_thrift(const Thrift__Common::byte& in,int8_t& out){
+  out=(int)in;
+}
+void conv_ttcn_thrift(const Thrift__Common::i16& in,int16_t& out){
+  out=(int)in;
+}
+void conv_ttcn_thrift(const Thrift__Common::i32& in,int32_t& out){
+  out=(int)in;
+}
+void conv_ttcn_thrift(const Thrift__Common::i64& in,int64_t& out){
+  out=in.get_long_long_val();
+}
+void conv_ttcn_thrift(const Thrift__Common::string& in,std::string& out){
+  out=std::string((const char*)in,in.lengthof());
+}
+void conv_ttcn_thrift(const Thrift__Common::binary& in,std::string& out){
+  out=std::string((const char*)(const unsigned char*)in,in.lengthof());
+}
+
+void conv_thrift_ttcn(const bool& in,Thrift__Common::bool_& out){
+  out=in;
+}
+
+void conv_thrift_ttcn(const int8_t& in,Thrift__Common::byte& out){
+  out=in;
+}
+
+void conv_thrift_ttcn(const int16_t& in,Thrift__Common::i16& out){
+  out=in;
+}
+
+void conv_thrift_ttcn(const int32_t& in,Thrift__Common::i32& out){
+  out=in;
+}
+
+void conv_thrift_ttcn(const int64_t& in,Thrift__Common::i64& out){
+  out.set_long_long_val(in);
+}
+void conv_thrift_ttcn(const std::string& in,Thrift__Common::string& out){
+  out=Thrift__Common::string(in.size(),in.data());
+}
+void conv_thrift_ttcn(const std::string& in,Thrift__Common::binary& out){
+  out=Thrift__Common::binary(in.size(),(const unsigned char*)in.data());
+}
diff --git a/src/Thrift_Common_Converter.hh b/src/Thrift_Common_Converter.hh
new file mode 100644
index 0000000..f9dab8e
--- /dev/null
+++ b/src/Thrift_Common_Converter.hh
@@ -0,0 +1,38 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+//////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef Thrift_Common_Converter_H
+#define Thrift_Common_Converter_H
+
+#include <thrift/Thrift.h>
+#include "Thrift_Common.hh"
+
+
+struct internal_comm_struct{
+  int code;
+  void** data;
+};
+
+
+void conv_ttcn_thrift(const Thrift__Common::bool_& in,bool& out);
+void conv_ttcn_thrift(const Thrift__Common::byte& in,int8_t& out);
+void conv_ttcn_thrift(const Thrift__Common::i16& in,int16_t& out);
+void conv_ttcn_thrift(const Thrift__Common::i32& in,int32_t& out);
+void conv_ttcn_thrift(const Thrift__Common::i64& in,int64_t& out);
+void conv_ttcn_thrift(const Thrift__Common::string& in,std::string& out);
+void conv_ttcn_thrift(const Thrift__Common::binary& in,std::string& out);
+void conv_thrift_ttcn(const bool& in,Thrift__Common::bool_& out);
+void conv_thrift_ttcn(const int8_t& in,Thrift__Common::byte& out);
+void conv_thrift_ttcn(const int16_t& in,Thrift__Common::i16& out);
+void conv_thrift_ttcn(const int32_t& in,Thrift__Common::i32& out);
+void conv_thrift_ttcn(const int64_t& in,Thrift__Common::i64& out);
+void conv_thrift_ttcn(const std::string& in,Thrift__Common::string& out);
+void conv_thrift_ttcn(const std::string& in,Thrift__Common::binary& out);
+
+#endif
diff --git a/test/sapc.thrift b/test/sapc.thrift
new file mode 100644
index 0000000..9f6bde4
--- /dev/null
+++ b/test/sapc.thrift
@@ -0,0 +1,409 @@
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#  Data Structures
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+typedef i32                ScfId
+typedef i32                TenantId
+typedef i32                ServChainId
+typedef i32                PortId
+typedef i32                NexthopId
+typedef i32                Priority
+typedef i32                SubFilterId
+typedef i32                ApplFilterId
+typedef i16                SubProfileId
+typedef i16                ApplProfileId
+typedef i16                VlanId
+
+typedef byte         IpProtocol
+
+typedef string      TenantName
+
+typedef i64                MacAddress
+
+enum Afi {
+     AFI_IPV4,
+     AFI_IPV6,
+}
+
+struct IpAddress {
+     1: required     Afi                  afi,
+     2: optional          i32                  ipv4Address,
+     3: optional          binary               ipv6Address,
+}
+
+struct IpSubnet {
+     1: required     Afi                  afi,
+     2: optional          i32                  ipv4Prefix,
+     3: optional          binary               ipv6Prefix,
+     4: required          byte            prefixLength,
+}
+
+enum DpnState {
+     DPN_STATE_UNKNOWN =           0, 
+     DPN_STATE_UNCONFIGURED =      1,
+     DPN_STATE_PRECONFIGURED =     2,
+     DPN_STATE_CONNECTED =         3,
+     DPN_STATE_READY =             4,
+     DPN_STATE_DISCONNECTED =      5,
+}
+
+enum PortState {
+     PORT_STATE_UNKNOWN =          0,
+     PORT_STATE_UNCONFIGURED =     1,
+     PORT_STATE_PRECONFIGURED =    2,
+     PORT_STATE_UP =               3,
+     PORT_STATE_DOWN =             4,
+     PORT_STATE_SHUT =             5,
+}
+
+enum LogicalPortUse {
+     PORT_USE_UNKNOWN =            0,
+     PORT_USE_FREE =                    1,
+     PORT_USE_SEIZED =             2,
+     PORT_USE_BUSY =                    3,
+}
+
+struct LogicalPortInfo {
+     1: required     LogicalPortUse  portUse,
+     2: optional     VlanId               vlanId,
+     3: optional     string               displayName,
+}
+
+struct PortInfo {
+     1: optional          i64                  dpId,
+     2: required          string               portName,
+     3: required          PortState       portState,
+     4: optional          i32                  portNo,
+     5: optional          list<LogicalPortInfo>     logicalPorts,
+}
+
+struct DpnInfo {
+     1: required          i64                  dpId,       
+     2: optional          string               dpnName,
+     3: optional          list<PortInfo> ports,
+     4: required          DpnState        dpnState,
+}
+
+struct DomainInfo {
+     1: optional          string               domainName,
+     2: required          list<DpnInfo>  dpns,
+}
+
+
+struct TenantInfo {
+     1: required     TenantName           tenantName,
+     2: optional     IpAddress            tenantIpAddress,
+     3: optional         i16                         tcpPortNo,
+     4: optional          i16                        cookie,
+} 
+
+enum SubEventType {
+     CREATE = 0,
+     UPDATE = 1,
+     DELETE = 2,
+}
+
+enum SubObjectType {
+     DPN = 0,
+     PORT = 1,
+}
+
+struct SubItem {
+     1: required     SubEventType               subEventType,
+     2: required     SubObjectType              subObjectType,
+}
+
+struct LogicalPort {
+     1: required i64                 dpId,
+     2: required string              portName,
+     3: optional VlanId              vlanId,
+     4: optional string              displayName,
+}
+
+struct ServiceChain {
+     1: optional string              displayName,
+}
+
+
+enum Direction {
+     UP = 1,
+     DOWN = 2,
+ 
+}
+
+
+struct SubFilterInfo {
+     1: optional string                   displayName,
+     2: optional IpSubnet            srcIpPrefix,
+     3: optional Priority           priority, 
+     4: optional SubProfileId       subProfileId,
+}
+
+struct ApplFilterInfo {
+     1: optional string                   displayName
+     2: optional IpSubnet            dstIpPrefix,
+     3: optional IpProtocol              ipProtocol,
+     4: optional i32                     destPortNo,
+     5: optional Priority           priority,
+     6: optional ApplProfileId      applProfileId,
+}
+
+
+typedef list<NexthopId>              NextHops
+
+struct IndirectNexthop {
+     1: optional string              displayName,
+     2: optional NextHops           nextHops,
+}
+
+struct DirectNexthop {
+     1: optional string                   displayName,
+     2: optional PortId                   egressPort,
+     3: optional IpAddress           ipAddress,
+     4: optional MacAddress               macAddress,
+}
+
+enum Result{
+     UNSUCCESSFUL = 0,
+     SUCCESSFUL = 1,
+}
+
+struct ScfResult {
+     1: required          Result               result,
+     2: optional          TenantId        tenantId,     /* Response to register_tenant() */                     
+     3: optional          i16                  genId,             /* Response to register_tenant(), create_scf_instance(), seize_logical_port(), add_logical_port, create_service_chain(), start_recovery(), recovery_completed() */
+     4: optional          i32                  revisionId,        /* Response to register_tenant(), create_scf_instance(), seize_logical_port(), add_logical_port, create_service_chain(), start_recovery(), recovery_completed() */
+     5: optional          PortInfo        portInfo,     /* Response to seize_port(), get_port() */
+     6: optional          DpnInfo              dpnInfo,      /* Response to get_dpn() */
+}
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#  Service Definition
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+service TenantService {
+
+     # Tenant handling
+ 
+     ScfResult  register_tenant                   (1:  TenantInfo         tenantInfo),  
+ 
+     ScfResult  deregister_tenant                 (1:  TenantId           tenantId),  
+ 
+     ScfResult  start_recovery                    (1:  TenantInfo         tenantInfo),
+ 
+     ScfResult  recovery_completed                (1:  TenantInfo         tenantInfo),
+                 
+     ScfResult  subscribe_nw_events               (1:  TenantId           tenantId,
+                                                              2:  SubItem            subItem),
+                                                            
+     ScfResult  unsubscribe_nw_events        (1:  TenantId            tenantId,
+                                                           2:  SubItem              subItem),             
+ 
+     # Logical Port handling
+                                                      
+     ScfResult  seize_logical_port               (1:  TenantId           tenantId,
+                                                              2:  PortId             portId,
+                                                              3:  LogicalPort        logicalPort),
+                                                              
+     ScfResult  update_logical_port              (1:  TenantId           tenantId,
+                                                              2:  PortId             portId,
+                                                              3:  LogicalPort        logicalPort),
+                                                              
+     ScfResult  release_logical_port         (1:  TenantId            tenantId,
+                                                              2:  PortId             portId),
+}
+
+
+service NetworkInfoService {
+
+     # Domain information retrieval
+ 
+     DomainInfo      get_domain                        (),
+ 
+     ScfResult get_dpn                                (1:  i64                      dpId), 
+ 
+     ScfResult  get_port                          (1:  i64                      dpId, 
+                                                              2:  string             portName),
+ 
+}
+
+
+service ServiceChainProvisioning {
+
+     #SCF Instance handling
+ 
+     ScfResult  create_scf_instance            (1:  TenantId              tenantId,
+                                                              2:  ScfId              scfId,
+                                                              3:  string             displayName), 
+                                                              
+     ScfResult  delete_scf_instance            (1:  TenantId              tenantId,
+                                                              2:  ScfId              scfId),
+                                                              
+     ScfResult  add_logical_port                  (1:  TenantId           tenantId,
+                                                              2:  ScfId              scfId,
+                                                              3:  PortId             portId,
+                                                              4:  Direction          direction) 
+
+     ScfResult  remove_logical_port               (1:  TenantId           tenantId,
+                                                              2:  ScfId              scfId,
+                                                              3:  PortId             portId)                                                               
+                                                 
+ 
+
+     # Service Chain handling
+     ScfResult  create_service_chain         (1:  TenantId            tenantId,
+                                                              2:  ScfId              scfId,
+                                                              3:  ServChainId        servChainId,
+                                                              4:  ServiceChain       serviceChain),
+                                                             
+     ScfResult  update_service_chain         (1:  TenantId            tenantId,     
+                                                              2:  ScfId              scfId,
+                                                              3:  ServChainId        servChainId,
+                                                              4:  ServiceChain       serviceChain),
+                                                              
+     ScfResult  delete_service_chain         (1:  TenantId            tenantId,
+                                                              2:  ScfId              scfId,
+                                                              3:  ServChainId        servChainId),
+                                                 
+ 
+     # SCF nexthop handling
+
+     ScfResult  create_repl_nexthop               (1:  TenantId           tenantId,
+                                                              2:  ScfId              scfId,
+                                                              3:  NexthopId          nexthopId
+                                                              4:  IndirectNexthop     replNexthop),
+                                                              
+     ScfResult  update_repl_nexthop               (1:  TenantId           tenantId,
+                                                              2:  ScfId              scfId,
+                                                              3:  NexthopId          nexthopId
+                                                              4:  IndirectNexthop     replNexthop),
+                                                              
+     ScfResult  create_lb_nexthop                 (1:  TenantId           tenantId,   
+                                                              2:  ScfId              scfId,
+                                                              3:  NexthopId          nexthopId,
+                                                              4:  IndirectNexthop  lbNexthop),
+                                                             
+     ScfResult  update_lb_nexthop                 (1:  TenantId           tenantId,
+                                                              2:  ScfId              scfId,
+                                                              3:  NexthopId          nexthopId,
+                                                              4:  IndirectNexthop  lbNexthops),
+                                                              
+     ScfResult  create_direct_nexthop        (1:  TenantId            tenantId,
+                                                              2:  ScfId              scfId,
+                                                              3:  NexthopId          nexthopId,
+                                                              4:  DirectNexthop     directNexthop),
+                                                              
+     ScfResult  update_direct_nexthop        (1:  TenantId            tenantId,
+                                                              2:  ScfId              scfId,
+                                                              3:  NexthopId          nexthopId,
+                                                              4:  DirectNexthop     directNexthop),
+                                                              
+     ScfResult  delete_nexthop                    (1:  TenantId           tenantId,
+                                                              2:  ScfId              scfId,
+                                                              3:  NexthopId          nexthopId),
+ 
+     # SC Hop handling
+     ScfResult  create_sc_hop                     (1:  TenantId           tenantId,
+                                                              2:  ScfId              scfId,
+                                                              3:  ServChainId        servChainId,
+                                                              4:  PortId             ingressPort,
+                                                              5:  NexthopId          nexthopId),
+                                                              
+     ScfResult  update_sc_hop                     (1:  TenantId           tenantId,
+                                                              2:  ScfId              scfId,
+                                                              3:  ServChainId        servChainId,
+                                                              4:  PortId             ingressPort,
+                                                              5:  NexthopId          nexthopId),
+                                                              
+     ScfResult  delete_sc_hop                     (1:  TenantId           tenantId,
+                                                              2:  ScfId              scfId,
+                                                              3:  ServChainId        servChainId,
+                                                              4:  PortId             ingressPort), 
+}
+
+
+service FlowMapping {
+     # Profile handling
+     ScfResult  create_sub_profile              (1:  TenantId              tenantId,
+                                                             2:  ScfId                     scfId,
+                                                             3:  SubProfileId        subProfileId,
+                                                             4:  string              displayName),
+                                                            
+     ScfResult  delete_sub_profile              (1:  TenantId            tenantId,
+                                                             2:  ScfId                     scfId,
+                                                             3:  SubProfileId        subProfileId),
+                                                            
+     ScfResult  create_app_profile              (1:  TenantId            tenantId,
+                                                             2:  ScfId                     scfId,
+                                                             3:  ApplProfileId       applProfileId,
+                                                             4:  string              displayName),
+                                                            
+     ScfResult  delete_app_profile              (1:  TenantId            tenantId,
+                                                             2:  ScfId                     scfId,
+                                                             3:  ApplProfileId       applProfileId),
+ 
+   # SCF Service Chain mapping
+ 
+     ScfResult  create_profile_map              (1:  TenantId            tenantId,
+                                                             2:  ScfId                     scfId,
+                                                             3:  SubProfileId       subProfileId,  /* Change to struct? */
+                                                             4:  ApplProfileId      applProfileId,
+                                                             5:  ServChainId         servChainId),
+                                                 
+     ScfResult  update_profile_map              (1:  TenantId            tenantId,
+                                                             2:  ScfId                     scfId,
+                                                             3:  SubProfileId       subProfileId,
+                                                             4:  ApplProfileId      applProfileId,
+                                                             5:  ServChainId         servChainId),
+                                                 
+     ScfResult  delete_profile_map          (1:  TenantId             tenantId,
+                                                             2:  ScfId                     scfId,
+                                                             3:  SubProfileId       subProfileId,
+                                                             4:  ApplProfileId      applProfileId),  
+
+     # Filters
+     ScfResult  create_exc_filter                (1:  TenantId            tenantId,
+                                                             2:  ScfId                   scfId,
+                                                             3:  IpAddress           srcIp,
+                                                             4:  IpAddress          destIp,
+                                                             5:  IpProtocol          ipProtocol,
+                                                             6:  PortId              srcPort,
+                                                             7:  PortId              destPort,
+                                                             8:  ServChainId        servChainId),
+                                                            
+     ScfResult  delete_exc_filter           (1:  TenantId             tenantId,
+                                                             2:  ScfId                     scfId,
+                                                             3:  IpAddress          srcIp,
+                                                             4:  IpAddress          destIp,
+                                                             5:  IpProtocol          ipProtocol,
+                                                             6:  PortId              srcPort,
+                                                             7:  PortId              destPort),
+                                                            
+     ScfResult  create_sub_filter           (1:  TenantId             tenantId   
+                                                             2:  ScfId                     scfId,
+                                                             3:  SubFilterId        subFilterId,
+                                                             4:  SubFilterInfo       subFilterInfo),
+                                                            
+     ScfResult  update_sub_filter           (1:  TenantId             tenantId
+                                                             2:  ScfId                     scfId,
+                                                             3:  SubFilterId        subFilterId,
+                                                             4:  SubFilterInfo       subFilterInfo),
+                                                            
+     ScfResult  delete_sub_filter               (1:  TenantId            tenantId,
+                                                             2:  ScfId                     scfId,
+                                                             3:  SubFilterId        subFilterId ),
+                                                            
+    ScfResult   create_app_filter           (1:  TenantId             tenantId,   
+                                                             2:  ScfId                     scfId,
+                                                             3:  ApplFilterId       applFilterId,
+                                                             4:  ApplFilterInfo     applFilterInfo ),
+                                                            
+     ScfResult  update_app_filter           (1:  TenantId             tenantId,   
+                                                             2:  ScfId                     scfId,
+                                                             3:  ApplFilterId       applFilterId,
+                                                             4:  ApplFilterInfo     applFilterInfo ),
+                                                            
+     ScfResult delete_app_filter                (1:  TenantId            tenantId,
+                                                             2:  ScfId                     scfId,
+                                                             3:  ApplFilterId       applFilterId ),                                               
+                                                 
+}