diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index cc3efcd..baee877 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -1768,10 +1768,10 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 				bool in_creation_method_with_chainup = (current_method is CreationMethod && current_class != null && current_class.base_class != null);
 
 				if (in_constructor || (in_instance_method && (!in_creation_method_with_chainup || current_method.body != b)) || in_instance_property) {
-					var ref_call = new CCodeFunctionCall (get_dup_func_expression (get_data_type_for_symbol (current_type_symbol), b.source_reference));
-					ref_call.add_argument (get_result_cexpression ("self"));
+					//var ref_call = new CCodeFunctionCall (get_dup_func_expression (get_data_type_for_symbol (current_type_symbol), b.source_reference));
+					//ref_call.add_argument (get_result_cexpression ("self"));
 
-					ccode.add_assignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "self"), ref_call);
+					ccode.add_assignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "self"), get_result_cexpression ("self"));
 				}
 
 				if (current_method != null) {
@@ -1858,8 +1858,8 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 			} else {
 				if (in_constructor || (current_method != null && current_method.binding == MemberBinding.INSTANCE) ||
 				           (current_property_accessor != null && current_property_accessor.prop.binding == MemberBinding.INSTANCE)) {
-					var this_value = new GLibValue (get_data_type_for_symbol (current_type_symbol), new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), "self"), true);
-					ccode.add_expression (destroy_value (this_value));
+					//var this_value = new GLibValue (get_data_type_for_symbol (current_type_symbol), new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), "self"), false);
+					//ccode.add_expression (destroy_value (this_value));
 				}
 			}
 
diff --git a/codegen/valagsignalmodule.vala b/codegen/valagsignalmodule.vala
index 6e06f72..12c82f7 100644
--- a/codegen/valagsignalmodule.vala
+++ b/codegen/valagsignalmodule.vala
@@ -558,7 +558,9 @@ public class Vala.GSignalModule : GObjectModule {
 				else
 					connect_func = get_dynamic_signal_connect_after_wrapper_name ((DynamicSignal) sig);
 			} else {
-				if (m.closure) {
+				if (m.closure && in_gobject_instance (m)) {
+					connect_func = "g_signal_connect_closure";
+				} else if (m.closure) {
 					connect_func = "g_signal_connect_data";
 				} else if (in_gobject_instance (m)) {
 					connect_func = "g_signal_connect_object";
@@ -656,55 +658,85 @@ public class Vala.GSignalModule : GObjectModule {
 			ccall.add_argument (new CCodeConstant ("NULL"));
 		}
 
-		// third resp. sixth argument: handler
-		ccall.add_argument (new CCodeCastExpression (get_cvalue (handler), "GCallback"));
+		if (m.closure && in_gobject_instance (m)) {
+			// g_signal_connect_closure
+			var closure_var = get_temp_variable (new CType ("GClosure*"), false, null, false);
+			var closure_ref = get_variable_cexpression (closure_var.name);
+			emit_temp_var (closure_var);
 
-		if (m.closure) {
-			// g_signal_connect_data
+			var closure_call = new CCodeFunctionCall (new CCodeIdentifier ("g_cclosure_new"));
 
-			// fourth argument: user_data
+			// callback func
+			closure_call.add_argument (new CCodeCastExpression (get_cvalue (handler), "GCallback"));
+
+			// user_data
 			CCodeExpression handler_destroy_notify;
-			ccall.add_argument (get_delegate_target_cexpression (handler, out handler_destroy_notify));
+			closure_call.add_argument (get_delegate_target_cexpression (handler, out handler_destroy_notify));
 
-			// fifth argument: destroy_notify
-			ccall.add_argument (new CCodeCastExpression (handler_destroy_notify, "GClosureNotify"));
+			// destroy_data
+			closure_call.add_argument (new CCodeCastExpression (handler_destroy_notify, "GClosureNotify"));
 
-			// sixth argument: connect_flags
-			if (!after)
-				ccall.add_argument (new CCodeConstant ("0"));
-			else
-				ccall.add_argument (new CCodeConstant ("G_CONNECT_AFTER"));
-		} else if (m.binding == MemberBinding.INSTANCE) {
-			// g_signal_connect_object or g_signal_handlers_disconnect_matched
-			// or dynamic_signal_connect or dynamic_signal_disconnect
-
-			// fourth resp. seventh argument: object/user_data
-			if (handler is MemberAccess) {
-				var right_ma = (MemberAccess) handler;
-				if (right_ma.inner != null) {
-					ccall.add_argument (get_cvalue (right_ma.inner));
-				} else {
-					ccall.add_argument (get_result_cexpression ("self"));
-				}
-			} else if (handler is LambdaExpression) {
-				ccall.add_argument (get_result_cexpression ("self"));
-			}
-			if (!disconnect && !(sig is DynamicSignal)
-			    && in_gobject_instance (m)) {
-				// g_signal_connect_object
+			ccode.add_assignment (closure_ref, closure_call);
+
+			var watch_call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_watch_closure"));
+			watch_call.add_argument (new CCodeCastExpression (get_result_cexpression ("self"), "GObject *"));
+			watch_call.add_argument (closure_ref);
+
+			ccode.add_expression (watch_call);
+
+			ccall.add_argument (closure_ref);
+			ccall.add_argument (new CCodeConstant (after ? "TRUE" : "FALSE"));
+		} else {
+			// third resp. sixth argument: handler
+			ccall.add_argument (new CCodeCastExpression (get_cvalue (handler), "GCallback"));
+
+			if (m.closure) {
+				// g_signal_connect_data
 
-				// fifth argument: connect_flags
+				// fourth argument: user_data
+				CCodeExpression handler_destroy_notify;
+				ccall.add_argument (get_delegate_target_cexpression (handler, out handler_destroy_notify));
+
+				// fifth argument: destroy_notify
+				ccall.add_argument (new CCodeCastExpression (handler_destroy_notify, "GClosureNotify"));
+
+				// sixth argument: connect_flags
 				if (!after)
 					ccall.add_argument (new CCodeConstant ("0"));
 				else
 					ccall.add_argument (new CCodeConstant ("G_CONNECT_AFTER"));
-			}
-		} else {
-			// g_signal_connect or g_signal_connect_after or g_signal_handlers_disconnect_matched
-			// or dynamic_signal_connect or dynamic_signal_disconnect
+			} else if (m.binding == MemberBinding.INSTANCE) {
+				// g_signal_connect_object or g_signal_handlers_disconnect_matched
+				// or dynamic_signal_connect or dynamic_signal_disconnect
+
+				// fourth resp. seventh argument: object/user_data
+				if (handler is MemberAccess) {
+					var right_ma = (MemberAccess) handler;
+					if (right_ma.inner != null) {
+						ccall.add_argument (get_cvalue (right_ma.inner));
+					} else {
+						ccall.add_argument (get_result_cexpression ("self"));
+					}
+				} else if (handler is LambdaExpression) {
+					ccall.add_argument (get_result_cexpression ("self"));
+				}
+				if (!disconnect && !(sig is DynamicSignal)
+						&& in_gobject_instance (m)) {
+					// g_signal_connect_object
+
+					// fifth argument: connect_flags
+					if (!after)
+						ccall.add_argument (new CCodeConstant ("0"));
+					else
+						ccall.add_argument (new CCodeConstant ("G_CONNECT_AFTER"));
+				}
+			} else {
+				// g_signal_connect or g_signal_connect_after or g_signal_handlers_disconnect_matched
+				// or dynamic_signal_connect or dynamic_signal_disconnect
 
-			// fourth resp. seventh argument: user_data
-			ccall.add_argument (new CCodeConstant ("NULL"));
+				// fourth resp. seventh argument: user_data
+				ccall.add_argument (new CCodeConstant ("NULL"));
+			}
 		}
 
 		if (disconnect || expr.parent_node is ExpressionStatement) {
