diff --git a/codegen/valagsignalmodule.vala b/codegen/valagsignalmodule.vala
index fe7c864..a739d10 100644
--- a/codegen/valagsignalmodule.vala
+++ b/codegen/valagsignalmodule.vala
@@ -171,6 +171,34 @@ internal class Vala.GSignalModule : GObjectModule {
 		}
 
 		generate_marshaller (sig.get_parameters (), sig.return_type);
+
+		if(sig.has_emitter) {
+			var emitter = new CCodeFunction ("%s_%s".printf(
+			       cl.get_lower_case_cname(null), sig.get_cname ()));
+			int n_params = 0;
+			emitter.add_parameter (
+			        new CCodeFormalParameter ("*self", cl.get_cname ()));
+			foreach (FormalParameter p in sig.get_parameters ()) {
+				emitter.add_parameter (new CCodeFormalParameter (p.name, get_value_type_name_from_parameter (p)));
+				n_params++;
+				if (p.parameter_type.is_array ()) {
+					emitter.add_parameter (new CCodeFormalParameter ("%s_length".printf (p.name), "gint"));
+					n_params++;
+				}
+			}
+			var vblock = new CCodeBlock();
+
+			emitter.line = function.line;
+			bool visible = !sig.is_internal_symbol ();
+			if (visible) {
+				header_declarations.add_type_member_declaration (emitter.copy ());
+			} else {
+				emitter.modifiers |= CCodeModifiers.STATIC;
+				source_declarations.add_type_member_declaration (emitter.copy ());
+			}
+			emitter.block = vblock;
+			source_type_member_definition.append (emitter);
+		}
 	}
 
 	public override void generate_marshaller (Gee.List<FormalParameter> params, DataType return_type, bool dbus = false) {
@@ -358,13 +386,14 @@ internal class Vala.GSignalModule : GObjectModule {
 		var cl = sig.parent_symbol as Class;
 		csignew.add_argument (new CCodeConstant ("\"%s\"".printf (sig.get_cname ())));
 		csignew.add_argument (new CCodeIdentifier (type.get_type_id ()));
-		csignew.add_argument (new CCodeConstant ("G_SIGNAL_RUN_LAST"));
-		if (sig.default_handler == null) {
+		csignew.add_argument (new CCodeConstant (get_signal_stage_cname(sig.stage)));
+		if(sig.default_handler == null) {
 			csignew.add_argument (new CCodeConstant ("0"));
 		} else {
 			var struct_offset = new CCodeFunctionCall (new CCodeIdentifier ("G_STRUCT_OFFSET"));
-			struct_offset.add_argument (new CCodeIdentifier ("%sClass".printf (cl.get_cname ())));
-			struct_offset.add_argument (new CCodeIdentifier (sig.default_handler.vfunc_name));
+			struct_offset.add_argument (new CCodeIdentifier("%sClass".printf (cl.get_cname ())));
+			struct_offset.add_argument (new
+			CCodeIdentifier(sig.default_handler.vfunc_name));
 			csignew.add_argument (struct_offset);
 		}
 		csignew.add_argument (new CCodeConstant ("NULL"));
@@ -798,5 +827,20 @@ internal class Vala.GSignalModule : GObjectModule {
 
 		expr.ccodenode = ccall;
 	}
+	private static string get_signal_stage_cname (SignalStage stage) {
+		switch(stage) {
+			case SignalStage.RUN_FIRST:
+				return "G_SIGNAL_RUN_FIRST";
+			case SignalStage.RUN_LAST:
+				return "G_SIGNAL_RUN_LAST";
+			case SignalStage.RUN_CLEANUP:
+				return "G_SIGNAL_RUN_CLEANUP";
+			default:
+				/*'cause only three possible stages are supported
+				 * by GLib. N_RECURSE, DETAILED ACTION, NO_HOOKS 
+				 * are not invocation stages.*/
+				assert_not_reached();
+		}
+	}
 }
 
diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala
index 3ce7399..5183f04 100644
--- a/vala/valamemberaccess.vala
+++ b/vala/valamemberaccess.vala
@@ -400,6 +400,16 @@ public class Vala.MemberAccess : Expression {
 		}
 
 		var member = symbol_reference;
+		if(member is Method) {
+			var m = member as Method;
+			/*If the member is actually a overriden
+			 * default signal handler, we don't want to
+			 * access this member. Rather we want to access
+			 * the signal.*/
+			if(m.signal_reference != null) {
+				member = m.signal_reference;
+			}
+		}
 		var access = SymbolAccessibility.PUBLIC;
 		bool instance = false;
 		bool klass = false;
diff --git a/vala/valamethod.vala b/vala/valamethod.vala
index 79e9d5c..ec4e941 100644
--- a/vala/valamethod.vala
+++ b/vala/valamethod.vala
@@ -149,6 +149,21 @@ public class Vala.Method : Member {
 		}
 	}
 
+	/**
+	 * If the function is an anonymous virtual function created
+	 * for the default Signal handler, this member points to the
+	 * owner signal
+	 * */
+	public weak Signal? signal_reference {
+		get {
+			find_base_methods ();
+			return _signal_reference;
+		}
+		set {
+			_signal_reference = value;
+		}
+	}
+
 	public bool entry_point { get; private set; }
 
 	/**
@@ -200,8 +215,6 @@ public class Vala.Method : Member {
 	 */
 	public bool has_construct_function { get; set; default = true; }
 
-	public weak Signal signal_reference { get; set; }
-
 	public bool coroutine { get; set; }
 
 	private Gee.List<FormalParameter> parameters = new ArrayList<FormalParameter> ();
@@ -214,6 +227,7 @@ public class Vala.Method : Member {
 	private Block _body;
 
 	private weak Method _base_method;
+	private weak Signal _signal_reference;
 	private Method _base_interface_method;
 	private bool base_methods_valid;
 
@@ -602,6 +616,8 @@ public class Vala.Method : Member {
 				}
 
 				_base_method = base_method;
+				signal_reference = sig;
+
 				return;
 			}
 		}
diff --git a/vala/valasignal.vala b/vala/valasignal.vala
index 3a69f59..e0ca86c 100644
--- a/vala/valasignal.vala
+++ b/vala/valasignal.vala
@@ -58,12 +58,22 @@ public class Vala.Signal : Member, Lockable {
 	 */
 	public bool is_virtual { get; set; }
 
+	/**
+	 * The defatul signal handler's invocation stage.
+	 * Refer to GObject documentation on GSignalFlags
+	 **/
+	public SignalStage stage {
+		get;
+		private set;
+		default = SignalStage.RUN_LAST;
+	}
+
 	private Gee.List<FormalParameter> parameters = new ArrayList<FormalParameter> ();
 	/**
 	 * Refers to the default signal handler, which is an anonymous
 	 * function in the scope.
 	 * */
-	public Method default_handler { get; private set; }
+	public Method default_handler {get; private set;}
 
 	private string cname;
 	
@@ -203,11 +213,44 @@ public class Vala.Signal : Member, Lockable {
 	/**
 	 * Process all associated attributes.
 	 */
+	private void process_signal_attribute(Attribute a) {
+		if(a.has_argument("has_emitter")) {
+			has_emitter = a.get_bool ("has_emitter");
+		}
+		if(a.has_argument("stage")) {
+			var stage_name = a.get_string("stage");
+			switch(stage_name) {
+				case "RUN_FIRST":
+				case "FIRST":
+					stage = SignalStage.RUN_FIRST;
+				break;
+				case "RUN_LAST":
+				case "LAST":
+					stage = SignalStage.RUN_LAST;
+				break;
+				case "RUN_CLEANUP":
+				case "CLEANUP":
+					stage = SignalStage.RUN_CLEANUP;
+				break;
+				default:
+					Report.warning (source_reference,
+					"unknown stage %s".printf(stage_name));
+				break;
+			}
+		}
+	}
+
 	public void process_attributes () {
 		foreach (Attribute a in attributes) {
+			/* Backward compatitable weith HasEmitter,
+			 * should be replace with Signal (has_emitter = true/false)
+			 * */
 			if (a.name == "HasEmitter") {
 				has_emitter = true;
 			}
+			if (a.name == "Signal") {
+				process_signal_attribute(a);
+			}
 		}
 	}
 	
@@ -264,3 +306,8 @@ public class Vala.Signal : Member, Lockable {
 	}
 }
 
+public enum Vala.SignalStage {
+	RUN_FIRST,
+	RUN_LAST,
+	RUN_CLEANUP,
+}
