diff --git a/compiler2/ttcn3/Statement.cc b/compiler2/ttcn3/Statement.cc
index 1ddf88d11610365e4b2e32d5d8b76727e0a1f4e7..37c8ef4f8a127e06af2be71bd6059f6365b5a2ec 100644
--- a/compiler2/ttcn3/Statement.cc
+++ b/compiler2/ttcn3/Statement.cc
@@ -4775,9 +4775,9 @@ error:
         comp_op.donereturn.redirect->chk(return_type);
       }
     } else if (comp_op.donereturn.redirect) {
-      comp_op.donereturn.redirect->error("Redirect cannot be used for the "
-	"return value without a matching template");
-      comp_op.donereturn.redirect->chk_erroneous();
+      // if there is no matching template, then the value redirect stores the
+      // PTC's verdict instead of the return value
+      comp_op.donereturn.redirect->chk_verdict_only();
     }
     if (comp_op.index_redirect != NULL && ref_type != NULL) {
       ArrayDimensions dummy;
@@ -8161,41 +8161,41 @@ error:
   {
     if (comp_op.compref) {
       if (comp_op.donereturn.donematch) {
-	// value returning done
-  // figure out what type the done() function belongs to
-  Type *t = comp_op.donereturn.donematch
-    ->get_expr_governor(Type::EXPECTED_TEMPLATE);
-  if (!t) FATAL_ERROR("Statement::generate_code_expr_done()");
-  while (t->is_ref() && !t->has_done_attribute())
-    t = t->get_type_refd();
-  if (!t->has_done_attribute())
-    FATAL_ERROR("Statement::generate_code_expr_done()");
-  // determine whether the done() function is in the same module
-  Common::Module *t_mod = t->get_my_scope()->get_scope_mod_gen();
-  if (t_mod != my_sb->get_scope_mod_gen()) {
-    expr->expr = mputprintf(expr->expr, "%s::",
-      t_mod->get_modid().get_name().c_str());
-  }
-	expr->expr = mputstr(expr->expr, "done(");
-	comp_op.compref->generate_code_expr(expr);
-	expr->expr = mputstr(expr->expr, ", ");
-  bool has_decoded_redirect = comp_op.donereturn.redirect != NULL &&
-    comp_op.donereturn.redirect->has_decoded_modifier();
-	comp_op.donereturn.donematch->generate_code(expr, TR_NONE, has_decoded_redirect);
-	expr->expr = mputstr(expr->expr, ", ");
-	if (comp_op.donereturn.redirect) {
-	  // value redirect is present
-	  comp_op.donereturn.redirect->generate_code(expr, comp_op.donereturn.donematch);
-	} else {
-	  // value redirect is omitted
-	  expr->expr = mputstr(expr->expr, "NULL");
-	}
-  expr->expr = mputstr(expr->expr, ", ");
+        // value returning done
+        // figure out what type the done() function belongs to
+        Type *t = comp_op.donereturn.donematch
+          ->get_expr_governor(Type::EXPECTED_TEMPLATE);
+        if (!t) FATAL_ERROR("Statement::generate_code_expr_done()");
+        while (t->is_ref() && !t->has_done_attribute())
+          t = t->get_type_refd();
+        if (!t->has_done_attribute())
+          FATAL_ERROR("Statement::generate_code_expr_done()");
+        // determine whether the done() function is in the same module
+        Common::Module *t_mod = t->get_my_scope()->get_scope_mod_gen();
+        if (t_mod != my_sb->get_scope_mod_gen()) {
+          expr->expr = mputprintf(expr->expr, "%s::",
+            t_mod->get_modid().get_name().c_str());
+        }
+        expr->expr = mputstr(expr->expr, "done(");
+        comp_op.compref->generate_code_expr(expr);
+        expr->expr = mputstr(expr->expr, ", ");
+        bool has_decoded_redirect = comp_op.donereturn.redirect != NULL &&
+          comp_op.donereturn.redirect->has_decoded_modifier();
+        comp_op.donereturn.donematch->generate_code(expr, TR_NONE, has_decoded_redirect);
+        expr->expr = mputstr(expr->expr, ", ");
+      } else {
+        // simple done
+        comp_op.compref->generate_code_expr_mandatory(expr);
+        expr->expr = mputstr(expr->expr, ".done(");        
+      }
+      if (comp_op.donereturn.redirect != NULL) {
+        // value redirect is present
+        comp_op.donereturn.redirect->generate_code(expr, comp_op.donereturn.donematch);
       } else {
-	// simple done
-	comp_op.compref->generate_code_expr_mandatory(expr);
-	expr->expr = mputstr(expr->expr, ".done(");
+        // value redirect is omitted
+        expr->expr = mputstr(expr->expr, "NULL");
       }
+      expr->expr = mputstr(expr->expr, ", ");
       if (comp_op.index_redirect != NULL) {
         generate_code_index_redirect(expr, comp_op.index_redirect, my_sb);
       }
@@ -10262,13 +10262,14 @@ error:
   bool ValueRedirect::chk_RT1_restrictions() const
   {
     if (v.size() > 1) {
-      error("Redirecting multiple values is not supported in the Load Test "
-        "Runtime.");
+      error(verdict_only ? "Only one redirect is allowed in this case." :
+        "Redirecting multiple values is not supported in the Load Test Runtime.");
       return false;
     }
     if (v[0]->get_subrefs() != NULL) {
-      error("Redirecting parts of a value is not supported in the Load Test "
-        "Runtime.");
+      error(verdict_only ? "Cannot apply field names or array indexes to a "
+        "variable of type `verdicttype'." :
+        "Redirecting parts of a value is not supported in the Load Test Runtime.");
       return false;
     }
     return true;
@@ -10290,9 +10291,15 @@ error:
     }
   }
   
+  void ValueRedirect::chk_verdict_only()
+  {
+    verdict_only = true;
+    chk(Type::get_pooltype(Type::T_VERDICT));
+  }
+  
   void ValueRedirect::chk(Type* p_type)
   {
-    if (!use_runtime_2 && !chk_RT1_restrictions()) {
+    if ((verdict_only || !use_runtime_2) && !chk_RT1_restrictions()) {
       return;
     }
     bool invalid_type = p_type->get_typetype() == Type::T_ERROR;
@@ -10370,7 +10377,7 @@ error:
         exp_type = p_type;
       }
       if (exp_type != NULL && var_type != NULL) {
-        if (use_runtime_2) {
+        if (use_runtime_2 && !verdict_only) {
           // check for type compatibility in RT2
           TypeCompatInfo info(v[i]->get_var_ref()->get_my_scope()->get_scope_mod(),
             exp_type, var_type, true, false);
@@ -10407,7 +10414,7 @@ error:
   void ValueRedirect::generate_code(expression_struct* expr,
                                     TemplateInstance* matched_ti)
   {
-    if (use_runtime_2) {
+    if (use_runtime_2 && !verdict_only) {
       // a value redirect class is generated for this redirect in the expression's
       // preamble and instantiated in the expression
       Scope* scope = v[0]->get_var_ref()->get_my_scope();
@@ -10980,7 +10987,7 @@ error:
       Free(inst_params_str);
       expr->expr = mputprintf(expr->expr, "&%s", instance_id.c_str());
     }
-    else { // RT1
+    else { // RT1 or verdict only
       // in this case only the address of the one variable needs to be generated
       expr->expr = mputstr(expr->expr, "&(");
       v[0]->get_var_ref()->generate_code(expr);
diff --git a/compiler2/ttcn3/Statement.hh b/compiler2/ttcn3/Statement.hh
index 3bb62caad013df558cb13395bb75210d046905f4..d77479586988c4ea97414d568faf1f5d22a55654 100644
--- a/compiler2/ttcn3/Statement.hh
+++ b/compiler2/ttcn3/Statement.hh
@@ -1187,11 +1187,14 @@ namespace Ttcn {
     vector<SingleValueRedirect> v;
     /** pointer to the type of the redirected value, not owned */
     Type* value_type;
+    /** indicates whether the value redirect is restricted to only one value of
+      * type 'verdicttype' */
+    bool verdict_only;
     
     ValueRedirect(const ValueRedirect&);
     ValueRedirect& operator=(const ValueRedirect&);
   public:
-    ValueRedirect(): v(), value_type(NULL) { }
+    ValueRedirect(): v(), value_type(NULL), verdict_only(false) { }
     virtual ~ValueRedirect();
     virtual ValueRedirect* clone() const;
     virtual void set_my_scope(Scope* p_scope);
@@ -1209,6 +1212,10 @@ namespace Ttcn {
       * type of the redirected value. Called when the value's type cannot be
       * determined or is erroneous. */
     void chk_erroneous();
+    /** Performs the full semantic analysis on the value redirect.
+      * Only used by the 'done' statement, when it can only redirect a value of
+      * type 'verdicttype'. */
+    void chk_verdict_only();
     /** Performs the full semantic analysis on the value redirect.
       * @param p_type the type of the redirected value */
     void chk(Type* p_type);
diff --git a/core/Array.hh b/core/Array.hh
index 62fc25c9e84efc172757cbbac5896b71804aa63f..006d5d0815dc2c3ffbb4bb2a4a59e3ba5c614dcd 100644
--- a/core/Array.hh
+++ b/core/Array.hh
@@ -970,14 +970,14 @@ public:
   int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean);
   
   // alt-status priority: ALT_YES (return immediately) > ALT_REPEAT > ALT_MAYBE > ALT_NO
-  alt_status done(Index_Redirect* index_redirect) const
+  alt_status done(VERDICTTYPE* value_redirect, Index_Redirect* index_redirect) const
   {
     if (index_redirect != NULL) {
       index_redirect->incr_pos();
     }
     alt_status result = ALT_NO;
     for (unsigned int i = 0; i < array_size; ++i) {
-      alt_status ret_val = array_elements[i].done(index_redirect);
+      alt_status ret_val = array_elements[i].done(value_redirect, index_redirect);
       if (ret_val == ALT_YES) {
         if (index_redirect != NULL) {
           index_redirect->add_index((int)i + index_offset);
diff --git a/core/Communication.cc b/core/Communication.cc
index 34ed422203dfb49fb8b36de42c48f8a8e6a1ba81..f96b36ee2dfc3d2bc9279d18decf52174a1b9cd1 100644
--- a/core/Communication.cc
+++ b/core/Communication.cc
@@ -1512,12 +1512,14 @@ void TTCN_Communication::process_done_ack(int msg_end)
 {
   // decoding the mandatory attributes
   boolean answer = incoming_buf.pull_int().get_val();
+  verdicttype ptc_verdict = static_cast<verdicttype>(
+    incoming_buf.pull_int().get_val());
   char *return_type = incoming_buf.pull_string();
   // the return value starts here
   int return_value_begin = incoming_buf.get_pos();
 
   try {
-    TTCN_Runtime::process_done_ack(answer, return_type,
+    TTCN_Runtime::process_done_ack(answer, ptc_verdict, return_type,
       msg_end - return_value_begin,
       incoming_buf.get_data() + return_value_begin);
   } catch (...) {
@@ -1567,12 +1569,14 @@ void TTCN_Communication::process_component_status_mtc(int msg_end)
   boolean is_any_killed = incoming_buf.pull_int().get_val();
   boolean is_all_killed = incoming_buf.pull_int().get_val();
   if (is_done) {
-    // the return type and value is valid
+    // the return type and value are valid
+    verdicttype ptc_verdict = static_cast<verdicttype>(
+      incoming_buf.pull_int().get_val());
     char *return_type = incoming_buf.pull_string();
     int return_value_begin = incoming_buf.get_pos();
     try {
-      TTCN_Runtime::set_component_done(component_reference, return_type,
-        msg_end - return_value_begin,
+      TTCN_Runtime::set_component_done(component_reference, ptc_verdict, 
+        return_type, msg_end - return_value_begin,
         incoming_buf.get_data() + return_value_begin);
     } catch (...) {
       // avoid memory leaks
@@ -1584,9 +1588,9 @@ void TTCN_Communication::process_component_status_mtc(int msg_end)
   }
   if (is_killed) TTCN_Runtime::set_component_killed(component_reference);
   if (is_any_done)
-    TTCN_Runtime::set_component_done(ANY_COMPREF, NULL, 0, NULL);
+    TTCN_Runtime::set_component_done(ANY_COMPREF, NONE, NULL, 0, NULL);
   if (is_all_done)
-    TTCN_Runtime::set_component_done(ALL_COMPREF, NULL, 0, NULL);
+    TTCN_Runtime::set_component_done(ALL_COMPREF, NONE, NULL, 0, NULL);
   if (is_any_killed) TTCN_Runtime::set_component_killed(ANY_COMPREF);
   if (is_all_killed) TTCN_Runtime::set_component_killed(ALL_COMPREF);
   incoming_buf.cut_message();
@@ -1604,11 +1608,13 @@ void TTCN_Communication::process_component_status_ptc(int msg_end)
   boolean is_killed = incoming_buf.pull_int().get_val();
   if (is_done) {
     // the return type and value is valid
+    verdicttype ptc_verdict = static_cast<verdicttype>(
+      incoming_buf.pull_int().get_val());
     char *return_type = incoming_buf.pull_string();
     int return_value_begin = incoming_buf.get_pos();
     try {
-      TTCN_Runtime::set_component_done(component_reference, return_type,
-        msg_end - return_value_begin,
+      TTCN_Runtime::set_component_done(component_reference, ptc_verdict,
+        return_type, msg_end - return_value_begin,
         incoming_buf.get_data() + return_value_begin);
     } catch (...) {
       // avoid memory leaks
diff --git a/core/Component.cc b/core/Component.cc
index 08cf62634b9347c9aaab8ce8fc8a1655de2e4784..8792c7c5f046b9ec7d421b8425f1e266fe8c9695 100644
--- a/core/Component.cc
+++ b/core/Component.cc
@@ -28,6 +28,7 @@
 #include "Param_Types.hh"
 #include "Runtime.hh"
 #include "Optional.hh"
+#include "Verdicttype.hh"
 
 #include "../common/dbgnew.hh"
 
@@ -93,11 +94,16 @@ void COMPONENT::log() const
   else TTCN_Logger::log_event_unbound();
 }
 
-alt_status COMPONENT::done(Index_Redirect*) const
+alt_status COMPONENT::done(VERDICTTYPE* value_redirect, Index_Redirect*) const
 {
   if (component_value == UNBOUND_COMPREF) TTCN_error("Performing done "
     "operation on an unbound component reference.");
-  return TTCN_Runtime::component_done(component_value);
+  verdicttype ptc_verdict = NONE;
+  alt_status status = TTCN_Runtime::component_done(component_value, &ptc_verdict);
+  if (value_redirect != NULL) {
+    *value_redirect = ptc_verdict;
+  }
+  return status;
 }
 
 alt_status COMPONENT::killed(Index_Redirect*) const
diff --git a/core/Component.hh b/core/Component.hh
index f4e9853b9857806ad08e4ababc62348194f9e55d..b0f53b536a2cf0d7a20c466a2a13c48ec658b2f1 100644
--- a/core/Component.hh
+++ b/core/Component.hh
@@ -27,6 +27,7 @@ class Module_Param;
 
 template<typename T>
 class OPTIONAL;
+class VERDICTTYPE;
 
 // value class for all component types
 
@@ -78,7 +79,7 @@ public:
   inline boolean is_present() const { return is_bound(); }
 #endif
 
-  alt_status done(Index_Redirect*) const;
+  alt_status done(VERDICTTYPE* value_redirect, Index_Redirect*) const;
   alt_status killed(Index_Redirect*) const;
 
   boolean running(Index_Redirect*) const;
diff --git a/core/Runtime.cc b/core/Runtime.cc
index 25d48bc8443c8f062b119d168a56d413293b36bc..71a31ee2d756c4508cf67c6d654417a94b32d828 100644
--- a/core/Runtime.cc
+++ b/core/Runtime.cc
@@ -105,6 +105,7 @@ int TTCN_Runtime::component_status_table_size = 0;
 component TTCN_Runtime::component_status_table_offset = FIRST_PTC_COMPREF;
 struct TTCN_Runtime::component_status_table_struct {
     alt_status done_status, killed_status;
+    verdicttype local_verdict;
     char *return_type;
     Text_Buf *return_value;
 } *TTCN_Runtime::component_status_table = NULL;
@@ -861,7 +862,8 @@ void TTCN_Runtime::function_finished(const char *function_name)
   send_function_finished(text_buf);
 }
 
-alt_status TTCN_Runtime::component_done(component component_reference)
+alt_status TTCN_Runtime::component_done(component component_reference,
+  verdicttype* ptc_verdict /* = NULL */)
 {
   if (in_controlpart()) TTCN_error("Done operation cannot be performed "
     "in the control part.");
@@ -880,7 +882,7 @@ alt_status TTCN_Runtime::component_done(component component_reference)
   case ALL_COMPREF:
     return all_component_done();
   default:
-    return ptc_done(component_reference);
+    return ptc_done(component_reference, ptc_verdict);
   }
 }
 
@@ -1110,7 +1112,8 @@ void TTCN_Runtime::kill_execution()
   throw TC_End();
 }
 
-alt_status TTCN_Runtime::ptc_done(component component_reference)
+alt_status TTCN_Runtime::ptc_done(component component_reference,
+  verdicttype* ptc_verdict)
 {
   if (is_single()) TTCN_error("Done operation on a component reference "
     "cannot be performed in single mode.");
@@ -1151,6 +1154,9 @@ alt_status TTCN_Runtime::ptc_done(component component_reference)
   success:
   TTCN_Logger::log_par_ptc(API::ParallelPTC_reason::ptc__done,
     NULL, NULL, component_reference);
+  if (ptc_verdict != NULL) {
+    *ptc_verdict = component_status_table[index].local_verdict;
+  }
   return ALT_YES;
 }
 
@@ -2509,7 +2515,7 @@ void TTCN_Runtime::process_alive(boolean result_value)
   running_alive_result = result_value;
 }
 
-void TTCN_Runtime::process_done_ack(boolean done_status,
+void TTCN_Runtime::process_done_ack(boolean done_status, verdicttype ptc_verdict,
   const char *return_type, int return_value_len, const void *return_value)
 {
   switch (executor_state) {
@@ -2524,7 +2530,7 @@ void TTCN_Runtime::process_done_ack(boolean done_status,
     TTCN_error("Internal error: Message DONE_ACK arrived in invalid "
       "state.");
   }
-  if (done_status) set_component_done(create_done_killed_compref,
+  if (done_status) set_component_done(create_done_killed_compref, ptc_verdict,
     return_type, return_value_len, return_value);
   create_done_killed_compref = NULL_COMPREF;
 }
@@ -2646,7 +2652,7 @@ void TTCN_Runtime::process_kill_process(component component_reference)
 }
 
 void TTCN_Runtime::set_component_done(component component_reference,
-  const char *return_type, int return_value_len,
+  verdicttype ptc_verdict, const char *return_type, int return_value_len,
   const void *return_value)
 {
   switch (component_reference) {
@@ -2669,6 +2675,7 @@ void TTCN_Runtime::set_component_done(component component_reference,
   default: {
     int index = get_component_status_table_index(component_reference);
     component_status_table[index].done_status = ALT_YES;
+    component_status_table[index].local_verdict = ptc_verdict;
     Free(component_status_table[index].return_type);
     delete component_status_table[index].return_value;
     if (return_type != NULL && return_type[0] != '\0') {
@@ -2749,6 +2756,7 @@ int TTCN_Runtime::get_component_status_table_index(
 	      Malloc(sizeof(*component_status_table));
     component_status_table[0].done_status = ALT_UNCHECKED;
     component_status_table[0].killed_status = ALT_UNCHECKED;
+    component_status_table[0].local_verdict = NONE;
     component_status_table[0].return_type = NULL;
     component_status_table[0].return_value = NULL;
     component_status_table_size = 1;
@@ -2770,6 +2778,7 @@ int TTCN_Runtime::get_component_status_table_index(
         i <= component_index; i++) {
         component_status_table[i].done_status = ALT_UNCHECKED;
         component_status_table[i].killed_status = ALT_UNCHECKED;
+        component_status_table[i].local_verdict = NONE;
         component_status_table[i].return_type = NULL;
         component_status_table[i].return_value = NULL;
       }
@@ -2792,6 +2801,7 @@ int TTCN_Runtime::get_component_status_table_index(
     for (int i = 0; i < offset_diff; i++) {
       component_status_table[i].done_status = ALT_UNCHECKED;
       component_status_table[i].killed_status = ALT_UNCHECKED;
+      component_status_table[i].local_verdict = NONE;
       component_status_table[i].return_type = NULL;
       component_status_table[i].return_value = NULL;
     }
diff --git a/core/Runtime.hh b/core/Runtime.hh
index 7f6c9d9cbc25a177553495d21083ba3620761aef..2a90e372c3629f1f1b286e5b53d915465662e668 100644
--- a/core/Runtime.hh
+++ b/core/Runtime.hh
@@ -212,7 +212,8 @@ public:
   static void send_function_finished(Text_Buf& text_buf);
   static void function_finished(const char *function_name);
 
-  static alt_status component_done(component component_reference);
+  static alt_status component_done(component component_reference,
+    verdicttype* ptc_verdict = NULL);
   static alt_status component_done(component component_reference,
     const char *return_type, Text_Buf*& text_buf);
   static alt_status component_killed(component component_reference);
@@ -226,7 +227,8 @@ public:
   __attribute__ ((__noreturn__));
 
 private:
-  static alt_status ptc_done(component component_reference);
+  static alt_status ptc_done(component component_reference,
+    verdicttype* ptc_verdict);
   static alt_status any_component_done();
   static alt_status all_component_done();
   static alt_status ptc_killed(component component_reference);
@@ -309,7 +311,7 @@ public:
   static void process_create_ack(component new_component);
   static void process_running(boolean result_value);
   static void process_alive(boolean result_value);
-  static void process_done_ack(boolean done_status,
+  static void process_done_ack(boolean done_status, verdicttype ptc_verdict,
     const char *return_type, int return_value_len,
     const void *return_value);
   static void process_killed_ack(boolean killed_status);
@@ -318,7 +320,7 @@ public:
   static void process_kill_process(component component_reference);
 
   static void set_component_done(component component_reference,
-    const char *return_type, int return_value_len,
+    verdicttype ptc_verdict, const char *return_type, int return_value_len,
     const void *return_value);
   static void set_component_killed(component component_reference);
   static void cancel_component_done(component component_reference);
diff --git a/mctr2/mctr/MainController.cc b/mctr2/mctr/MainController.cc
index acad299fba793a2c15ca5ce4973b32f270936766..f7149203ca76eb20c4b32264f48c1d303a4f8835 100644
--- a/mctr2/mctr/MainController.cc
+++ b/mctr2/mctr/MainController.cc
@@ -1573,12 +1573,13 @@ void MainController::component_stopped(component_struct *tc)
       // the return value was requested
       send_component_status_mtc(tc->comp_ref, TRUE, FALSE,
         any_component_done_requested, all_done_result, FALSE, FALSE,
-        tc->return_type, tc->return_value_len, tc->return_value);
+        tc->local_verdict, tc->return_type, tc->return_value_len,
+        tc->return_value);
     } else {
       // the return value was not requested
       send_component_status_mtc(NULL_COMPREF, FALSE, FALSE,
         any_component_done_requested, all_done_result, FALSE, FALSE,
-        NULL, 0, NULL);
+        NONE, NULL, 0, NULL);
     }
     if (any_component_done_requested) {
       any_component_done_requested = FALSE;
@@ -1672,12 +1673,12 @@ void MainController::component_terminated(component_struct *tc)
     if (send_done_to_mtc) {
       // the return value was requested
       send_component_status_mtc(tc->comp_ref, TRUE, TRUE, TRUE,
-        all_done_result, TRUE, all_killed_result, tc->return_type,
-        tc->return_value_len, tc->return_value);
+        all_done_result, TRUE, all_killed_result, tc->local_verdict,
+        tc->return_type, tc->return_value_len, tc->return_value);
     } else {
       // the return value was not requested
       send_component_status_mtc(tc->comp_ref, FALSE, TRUE, TRUE,
-        all_done_result, TRUE, all_killed_result, NULL, 0, NULL);
+        all_done_result, TRUE, all_killed_result, NONE, NULL, 0, NULL);
     }
     any_component_done_requested = FALSE;
     any_component_done_sent = TRUE;
@@ -3307,11 +3308,13 @@ void MainController::send_alive(component_struct *tc, boolean answer)
 }
 
 void MainController::send_done_ack(component_struct *tc, boolean answer,
-  const char *return_type, int return_value_len, const void *return_value)
+  verdicttype local_verdict, const char *return_type, int return_value_len,
+  const void *return_value)
 {
   Text_Buf text_buf;
   text_buf.push_int(MSG_DONE_ACK);
   text_buf.push_int(answer ? 1 : 0);
+  text_buf.push_int(local_verdict);
   text_buf.push_string(return_type);
   text_buf.push_raw(return_value_len, return_value);
   send_message(tc->tc_fd, text_buf);
@@ -3498,7 +3501,8 @@ void MainController::send_cancel_done_mtc(component component_reference,
 void MainController::send_component_status_mtc(component component_reference,
   boolean is_done, boolean is_killed, boolean is_any_done,
   boolean is_all_done, boolean is_any_killed, boolean is_all_killed,
-  const char *return_type, int return_value_len, const void *return_value)
+  verdicttype local_verdict, const char *return_type, int return_value_len,
+  const void *return_value)
 {
   Text_Buf text_buf;
   text_buf.push_int(MSG_COMPONENT_STATUS);
@@ -3509,6 +3513,7 @@ void MainController::send_component_status_mtc(component component_reference,
   text_buf.push_int(is_all_done ? 1 : 0);
   text_buf.push_int(is_any_killed ? 1 : 0);
   text_buf.push_int(is_all_killed ? 1 : 0);
+  text_buf.push_int(local_verdict);
   text_buf.push_string(return_type);
   text_buf.push_raw(return_value_len, return_value);
   send_message(mtc->tc_fd, text_buf);
@@ -4755,7 +4760,7 @@ void MainController::process_done_req(component_struct *tc)
   case ANY_COMPREF:
     if (tc == mtc) {
       boolean answer = is_any_component_done();
-      send_done_ack(mtc, answer, NULL, 0, NULL);
+      send_done_ack(mtc, answer, NONE, NULL, 0, NULL);
       if (answer) any_component_done_sent = TRUE;
       else any_component_done_requested = TRUE;
     } else send_error_str(tc->tc_fd, "Operation 'any component.done' can "
@@ -4764,7 +4769,7 @@ void MainController::process_done_req(component_struct *tc)
   case ALL_COMPREF:
     if (tc == mtc) {
       boolean answer = !is_any_component_running();
-      send_done_ack(mtc, answer, NULL, 0, NULL);
+      send_done_ack(mtc, answer, NONE, NULL, 0, NULL);
       if (!answer) all_component_done_requested = TRUE;
     } else send_error_str(tc->tc_fd, "Operation 'all component.done' can "
       "only be performed on the MTC.");
@@ -4787,8 +4792,8 @@ void MainController::process_done_req(component_struct *tc)
   case TC_EXITING:
   case TC_EXITED:
   case PTC_KILLING:
-    send_done_ack(tc, TRUE, comp->return_type, comp->return_value_len,
-      comp->return_value);
+    send_done_ack(tc, TRUE, comp->local_verdict, comp->return_type,
+      comp->return_value_len, comp->return_value);
     break;
   case TC_IDLE:
   case TC_CREATE:
@@ -4803,7 +4808,7 @@ void MainController::process_done_req(component_struct *tc)
   case PTC_FUNCTION:
   case PTC_STARTING:
   case PTC_STOPPING_KILLING:
-    send_done_ack(tc, FALSE, NULL, 0, NULL);
+    send_done_ack(tc, FALSE, NONE, NULL, 0, NULL);
     add_requestor(&comp->done_requestors, tc);
     break;
   case PTC_STALE:
diff --git a/mctr2/mctr/MainController.h b/mctr2/mctr/MainController.h
index abfcb5a8073654d5f6e736fe8707a919bcb7e2d6..eb9e3ce326e1e9bb79775d67c1a6474b955981ca 100644
--- a/mctr2/mctr/MainController.h
+++ b/mctr2/mctr/MainController.h
@@ -506,7 +506,7 @@ private:
   static void send_running(component_struct *tc, boolean answer);
   static void send_alive(component_struct *tc, boolean answer);
   static void send_done_ack(component_struct *tc, boolean answer,
-    const char *return_type, int return_value_len,
+    verdicttype local_verdict, const char *return_type, int return_value_len,
     const void *return_value);
   static void send_killed_ack(component_struct *tc, boolean answer);
   static void send_connect_listen(component_struct *tc,
@@ -537,7 +537,7 @@ private:
   static void send_component_status_mtc(component component_reference,
     boolean is_done, boolean is_killed, boolean is_any_done,
     boolean is_all_done, boolean is_any_killed, boolean is_all_killed,
-    const char *return_type, int return_value_len,
+    verdicttype local_verdict, const char *return_type, int return_value_len,
     const void *return_value);
   static void send_execute_control(const char *module_name);
   static void send_execute_testcase(const char *module_name,
diff --git a/regression_test/Makefile b/regression_test/Makefile
index 98d16c3278da1eaf159f8ae3506973cad7acf76f..f8e32a5e76560aa1c193c963047ecb0d093d16f9 100644
--- a/regression_test/Makefile
+++ b/regression_test/Makefile
@@ -48,7 +48,7 @@ XML ipv6 implicitOmit testcase_defparam transparent HQ16404 cfgFile \
 all_from lazyEval tryCatch text2ttcn json ttcn2json profiler templateOmit \
 customEncoding makefilegen uidChars checkstate hostid templateIstemplatekind \
 selectUnion templateExclusiveRange any_from templatePatternRef indexWithRecofArray \
-connectMapOperTest fuzzy portTranslation ischosen OER functionSubref
+connectMapOperTest fuzzy portTranslation ischosen OER functionSubref done
 
 ifdef DYN
 DIRS += loggerplugin junitlogger 
diff --git a/regression_test/done/.gitignore b/regression_test/done/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..b38bc8a53e9f6882798faf8f4500800989aaa1e1
--- /dev/null
+++ b/regression_test/done/.gitignore
@@ -0,0 +1,6 @@
+DoneTest
+DoneTest.exe
+DoneTest*.cc
+DoneTest*.hh
+compile
+DoneTest*.log
diff --git a/regression_test/done/DoneTest.ttcn b/regression_test/done/DoneTest.ttcn
new file mode 100644
index 0000000000000000000000000000000000000000..c05886688fa2a1f9421f3de261f0deb3c37b740c
--- /dev/null
+++ b/regression_test/done/DoneTest.ttcn
@@ -0,0 +1,138 @@
+/******************************************************************************
+ * Copyright (c) 2000-2017 Ericsson Telecom AB
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Botond, Baranyi – initial implementation
+ *
+ ******************************************************************************/
+
+module DoneTest {
+
+/***************** Types *****************/
+type record Rec {
+  integer num,
+  charstring str
+}
+with {
+  extension "done";
+}
+
+type component CT {}
+
+/*********** Behavior functions ***********/
+function f_behavior_retval() runs on CT return Rec {
+  return { num := 10, str := "ab" };
+}
+
+function f_behavior_none() runs on CT {
+}
+
+function f_behavior_pass() runs on CT {
+  setverdict(pass);
+}
+
+/*************** Test cases ***************/
+
+// Testing 'done' statement on single component with no value redirect
+testcase tc_done_single() runs on CT {
+  var CT comp := CT.create;
+  comp.start(f_behavior_retval());
+  comp.done;
+  if (comp.running) {
+    setverdict(fail);
+  }
+  setverdict(pass);
+}
+
+// Testing 'done' statement on all components
+testcase tc_done_all() runs on CT {
+  var CT comps[3];
+  comps[0] := CT.create;
+  comps[1] := CT.create;
+  comps[2] := CT.create;
+  comps[0].start(f_behavior_retval());
+  comps[1].start(f_behavior_none());
+  comps[2].start(f_behavior_pass());
+  all component.done;
+  if (comps[0].running or comps[1].running or comps[2].running) {
+    setverdict(fail);
+  }
+  setverdict(pass);
+}
+
+// Testing 'done' statement on any components
+testcase tc_done_any() runs on CT {
+  var CT comps[3];
+  comps[0] := CT.create;
+  comps[1] := CT.create;
+  comps[2] := CT.create;
+  comps[0].start(f_behavior_retval());
+  comps[1].start(f_behavior_none());
+  comps[2].start(f_behavior_pass());
+  any component.done;
+  if (comps[0].running and comps[1].running and comps[2].running) {
+    setverdict(fail);
+  }
+  setverdict(pass);
+}
+
+// Testing 'done' statement on single component with value redirect
+// (in this case the value redirect stores the behavior function's return value,
+// because there is a matching template in the 'done' statement)
+testcase tc_done_retval_redirect() runs on CT {
+  var CT comp := CT.create;
+  comp.start(f_behavior_retval());
+  var Rec x;
+  comp.done(Rec: ?) -> value x;
+  if (comp.running or x != { num := 10, str := "ab" }) {
+    setverdict(fail);
+  }
+  setverdict(pass);
+}
+
+// Testing 'done' statement on single component with value redirect
+// (in this case the value redirect stores the local verdict on the component,
+// because there is no matching template in the 'done' statement)
+testcase tc_done_verdict_redirect() runs on CT {
+  var CT comp := CT.create;
+  comp.start(f_behavior_pass());
+  var verdicttype x;
+  comp.done -> value x;
+  if (comp.running or x != pass) {
+    setverdict(fail);
+  }
+  setverdict(pass);
+}
+
+// Testing 'done' statement on any component from a component array, and with value redirect
+// (in this case the value redirect stores the local verdict on the component,
+// because there is no matching template in the 'done' statement)
+testcase tc_any_from_done_verdict_redirect() runs on CT {
+  var CT comps[2];
+  comps[0] := CT.create;
+  comps[1] := CT.create;
+  comps[0].start(f_behavior_retval());
+  comps[1].start(f_behavior_none());
+  var verdicttype x;
+  any from comps.done -> value x; // the local verdict on both components is 'none'
+  if ((comps[0].running and comps[1].running) or x != none) {
+    setverdict(fail);
+  }
+  setverdict(pass);
+}
+
+/************** Control part **************/
+control {
+  execute(tc_done_single());
+  execute(tc_done_all());
+  execute(tc_done_any());
+  execute(tc_done_retval_redirect());
+  execute(tc_done_verdict_redirect());
+  execute(tc_any_from_done_verdict_redirect());
+}
+
+}
diff --git a/regression_test/done/Makefile b/regression_test/done/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..352c128930e3912032f11aeb62d9e9eed12b7b9b
--- /dev/null
+++ b/regression_test/done/Makefile
@@ -0,0 +1,56 @@
+##############################################################################
+# Copyright (c) 2000-2017 Ericsson Telecom AB
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#   Baranyi, Botond
+#
+##############################################################################
+TOPDIR := ..
+include $(TOPDIR)/Makefile.regression
+
+.SUFFIXES: .ttcn .hh
+.PHONY: all clean dep run
+
+TTCN3_LIB = ttcn3$(RT2_SUFFIX)-parallel$(DYNAMIC_SUFFIX)
+
+TTCN3_MODULES = DoneTest.ttcn
+
+GENERATED_SOURCES = $(TTCN3_MODULES:.ttcn=.cc)
+GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh)
+ifdef CODE_SPLIT
+GENERATED_SOURCES := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), .cc _seq.cc _set.cc  _seqof.cc _setof.cc _union.cc))
+else ifdef SPLIT_TO_SLICES
+POSTFIXES := $(foreach file, $(SPLIT_TO_SLICES), $(addsuffix $(file), _part_))
+POSTFIXES := $(foreach file, $(POSTFIXES), $(addprefix $(file), .cc))
+GENERATED_SOURCES2 := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), $(POSTFIXES)))
+GENERATED_SOURCES += $(GENERATED_SOURCES2)
+endif
+
+OBJECTS = $(GENERATED_SOURCES:.cc=.o)
+
+TARGET = DoneTest$(EXESUFFIX)
+
+all: $(TARGET)
+
+$(TARGET): $(GENERATED_SOURCES) $(USER_SOURCES)
+	$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@ $^ -L$(TTCN3_DIR)/lib -l$(TTCN3_LIB) -L$(OPENSSL_DIR)/lib -lcrypto $($(PLATFORM)_LIBS)
+
+.ttcn.cc .ttcn.hh:
+	$(TTCN3_COMPILER) $<
+
+clean distclean:
+	-rm -f $(TARGET) $(OBJECTS) $(GENERATED_HEADERS) \
+	$(GENERATED_SOURCES) *.log Makefile.bak
+
+dep: $(GENERATED_SOURCES)
+	makedepend $(CPPFLAGS) $(GENERATED_SOURCES)
+
+run: $(TARGET) config.cfg
+	$(TTCN3_DIR)/bin/ttcn3_start $^
+
+.NOTPARALLEL:
+
diff --git a/regression_test/done/config.cfg b/regression_test/done/config.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..3e444cd0615aaf0a4b5f110d596edc5e24d1a7b6
--- /dev/null
+++ b/regression_test/done/config.cfg
@@ -0,0 +1,19 @@
+###############################################################################
+# Copyright (c) 2000-2017 Ericsson Telecom AB
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#   Baranyi, Botond
+#
+###############################################################################
+[LOGGING]
+Logfile := "DoneTest_%r.log"
+FileMask := LOG_ALL
+ConsoleMask := TTCN_WARNING | TTCN_ERROR | TTCN_TESTCASE | TTCN_STATISTICS
+
+[EXECUTE]
+DoneTest
+