[vala] Move common code from GObjectModule to GTypeModule



commit 1f523e45f52792d1dd88c7fe4754b50cdebbc1bf
Author: Jürg Billeter <j bitron ch>
Date:   Wed Apr 8 22:18:03 2009 +0200

    Move common code from GObjectModule to GTypeModule
---
 gobject/valagobjectmodule.vala | 1726 +++-------------------------------------
 gobject/valagtypemodule.vala   | 1548 +++++++++++++++++++++++++++++++++++
 2 files changed, 1646 insertions(+), 1628 deletions(-)

diff --git a/gobject/valagobjectmodule.vala b/gobject/valagobjectmodule.vala
index 38511ca..b48ffa5 100644
--- a/gobject/valagobjectmodule.vala
+++ b/gobject/valagobjectmodule.vala
@@ -32,1491 +32,134 @@ internal class Vala.GObjectModule : GTypeModule {
 		base (codegen, next);
 	}
 
-	public override void generate_parameter (FormalParameter param, CCodeDeclarationSpace decl_space, Map<int,CCodeFormalParameter> cparam_map, Map<int,CCodeExpression>? carg_map) {
-		if (!(param.parameter_type is ObjectType)) {
-			base.generate_parameter (param, decl_space, cparam_map, carg_map);
-			return;
-		}
-
-		generate_type_declaration (param.parameter_type, decl_space);
-
-		string ctypename = param.parameter_type.get_cname ();
-
-		if (param.direction != ParameterDirection.IN) {
-			ctypename += "*";
-		}
-
-		param.ccodenode = new CCodeFormalParameter (param.name, ctypename);
-
-		cparam_map.set (get_param_pos (param.cparameter_position), (CCodeFormalParameter) param.ccodenode);
-		if (carg_map != null) {
-			carg_map.set (get_param_pos (param.cparameter_position), new CCodeIdentifier (param.name));
-		}
-	}
+	public override void visit_class (Class cl) {
+		base.visit_class (cl);
 
-	public override void generate_class_declaration (Class cl, CCodeDeclarationSpace decl_space) {
-		if (decl_space.add_symbol_declaration (cl, cl.get_cname ())) {
+		if (!cl.is_subtype_of (gobject_type)) {
 			return;
 		}
 
-		if (cl.base_class != null) {
-			// base class declaration
-			// necessary for ref and unref function declarations
-			generate_class_declaration (cl.base_class, decl_space);
+		if (class_has_readable_properties (cl) || cl.get_type_parameters ().size > 0) {
+			add_get_property_function (cl);
 		}
-
-		bool is_gtypeinstance = !cl.is_compact;
-		bool is_fundamental = is_gtypeinstance && cl.base_class == null;
-
-		if (is_gtypeinstance) {
-			decl_space.add_type_declaration (new CCodeNewline ());
-			var macro = "(%s_get_type ())".printf (cl.get_lower_case_cname (null));
-			decl_space.add_type_declaration (new CCodeMacroReplacement (cl.get_type_id (), macro));
-
-			macro = "(G_TYPE_CHECK_INSTANCE_CAST ((obj), %s, %s))".printf (cl.get_type_id (), cl.get_cname ());
-			decl_space.add_type_declaration (new CCodeMacroReplacement ("%s(obj)".printf (cl.get_upper_case_cname (null)), macro));
-
-			macro = "(G_TYPE_CHECK_CLASS_CAST ((klass), %s, %sClass))".printf (cl.get_type_id (), cl.get_cname ());
-			decl_space.add_type_declaration (new CCodeMacroReplacement ("%s_CLASS(klass)".printf (cl.get_upper_case_cname (null)), macro));
-
-			macro = "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), %s))".printf (cl.get_type_id ());
-			decl_space.add_type_declaration (new CCodeMacroReplacement ("%s(obj)".printf (get_type_check_function (cl)), macro));
-
-			macro = "(G_TYPE_CHECK_CLASS_TYPE ((klass), %s))".printf (cl.get_type_id ());
-			decl_space.add_type_declaration (new CCodeMacroReplacement ("%s_CLASS(klass)".printf (get_type_check_function (cl)), macro));
-
-			macro = "(G_TYPE_INSTANCE_GET_CLASS ((obj), %s, %sClass))".printf (cl.get_type_id (), cl.get_cname ());
-			decl_space.add_type_declaration (new CCodeMacroReplacement ("%s_GET_CLASS(obj)".printf (cl.get_upper_case_cname (null)), macro));
-			decl_space.add_type_declaration (new CCodeNewline ());
-		}
-
-		decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (cl.get_cname ()), new CCodeVariableDeclarator (cl.get_cname ())));
-
-		if (is_fundamental) {
-			var ref_fun = new CCodeFunction (cl.get_lower_case_cprefix () + "ref", "gpointer");
-			var unref_fun = new CCodeFunction (cl.get_lower_case_cprefix () + "unref", "void");
-			if (cl.access == SymbolAccessibility.PRIVATE) {
-				ref_fun.modifiers = CCodeModifiers.STATIC;
-				unref_fun.modifiers = CCodeModifiers.STATIC;
-			}
-
-			ref_fun.add_parameter (new CCodeFormalParameter ("instance", "gpointer"));
-			unref_fun.add_parameter (new CCodeFormalParameter ("instance", "gpointer"));
-
-			decl_space.add_type_member_declaration (ref_fun.copy ());
-			decl_space.add_type_member_declaration (unref_fun.copy ());
-
-			// GParamSpec and GValue functions
-			var function_name = cl.get_lower_case_cname ("param_spec_");
-
-			var function = new CCodeFunction (function_name, "GParamSpec*");
-			function.add_parameter (new CCodeFormalParameter ("name", "const gchar*"));
-			function.add_parameter (new CCodeFormalParameter ("nick", "const gchar*"));
-			function.add_parameter (new CCodeFormalParameter ("blurb", "const gchar*"));
-			function.add_parameter (new CCodeFormalParameter ("object_type", "GType"));
-			function.add_parameter (new CCodeFormalParameter ("flags", "GParamFlags"));
-
-			cl.set_param_spec_function (function_name);
-
-			if (cl.access == SymbolAccessibility.PRIVATE) {
-				function.modifiers = CCodeModifiers.STATIC;
-			}
-
-			decl_space.add_type_member_declaration (function);
-
-			function = new CCodeFunction (cl.get_set_value_function (), "void");
-			function.add_parameter (new CCodeFormalParameter ("value", "GValue*"));
-			function.add_parameter (new CCodeFormalParameter ("v_object", "gpointer"));
-
-			if (cl.access == SymbolAccessibility.PRIVATE) {
-				function.modifiers = CCodeModifiers.STATIC;
-			}
-
-			decl_space.add_type_member_declaration (function);
-
-			function = new CCodeFunction (cl.get_get_value_function (), "gpointer");
-			function.add_parameter (new CCodeFormalParameter ("value", "const GValue*"));
-
-			if (cl.access == SymbolAccessibility.PRIVATE) {
-				function.modifiers = CCodeModifiers.STATIC;
-			}
-
-			decl_space.add_type_member_declaration (function);
-		}
-
-		if (is_gtypeinstance) {
-			decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%sClass".printf (cl.get_cname ()), new CCodeVariableDeclarator ("%sClass".printf (cl.get_cname ()))));
-
-			var type_fun = new ClassRegisterFunction (cl, context);
-			type_fun.init_from_type (in_plugin);
-			decl_space.add_type_member_declaration (type_fun.get_declaration ());
+		if (class_has_writable_properties (cl) || cl.get_type_parameters ().size > 0) {
+			add_set_property_function (cl);
 		}
 	}
 
-	public override void generate_class_struct_declaration (Class cl, CCodeDeclarationSpace decl_space) {
-		if (decl_space.add_symbol_declaration (cl, "struct _" + cl.get_cname ())) {
+	public override void generate_class_init (Class cl, CCodeBlock init_block) {
+		if (!cl.is_subtype_of (gobject_type)) {
 			return;
 		}
 
-		if (cl.base_class != null) {
-			// base class declaration
-			generate_class_struct_declaration (cl.base_class, decl_space);
-		}
-		foreach (DataType base_type in cl.get_base_types ()) {
-			var iface = base_type.data_type as Interface;
-			if (iface != null) {
-				generate_interface_declaration (iface, decl_space);
-			}
-		}
-
-		generate_class_declaration (cl, decl_space);
-
-		bool is_gtypeinstance = !cl.is_compact;
-		bool is_fundamental = is_gtypeinstance && cl.base_class == null;
-
-		var instance_struct = new CCodeStruct ("_%s".printf (cl.get_cname ()));
-		var type_struct = new CCodeStruct ("_%sClass".printf (cl.get_cname ()));
-
-		if (cl.base_class != null) {
-			instance_struct.add_field (cl.base_class.get_cname (), "parent_instance");
-		} else if (is_fundamental) {
-			instance_struct.add_field ("GTypeInstance", "parent_instance");
-			instance_struct.add_field ("volatile int", "ref_count");
-		}
-
-		if (cl.is_compact && cl.base_class == null && cl.get_fields ().size == 0) {
-			// add dummy member, C doesn't allow empty structs
-			instance_struct.add_field ("int", "dummy");
-		}
-
-		if (is_gtypeinstance) {
-			decl_space.add_type_declaration (new CCodeTypeDefinition ("struct %sPrivate".printf (instance_struct.name), new CCodeVariableDeclarator ("%sPrivate".printf (cl.get_cname ()))));
-
-			instance_struct.add_field ("%sPrivate *".printf (cl.get_cname ()), "priv");
-			if (is_fundamental) {
-				type_struct.add_field ("GTypeClass", "parent_class");
-			} else {
-				type_struct.add_field ("%sClass".printf (cl.base_class.get_cname ()), "parent_class");
-			}
-
-			if (is_fundamental) {
-				type_struct.add_field ("void", "(*finalize) (%s *self)".printf (cl.get_cname ()));
-			}
-		}
-
-		foreach (Method m in cl.get_methods ()) {
-			generate_virtual_method_declaration (m, decl_space, type_struct);
-		}
-
-		foreach (Property prop in cl.get_properties ()) {
-			if (!prop.is_abstract && !prop.is_virtual) {
-				continue;
-			}
-			generate_type_declaration (prop.property_type, decl_space);
-
-			var t = (ObjectTypeSymbol) prop.parent_symbol;
-
-			bool returns_real_struct = prop.property_type.is_real_struct_type ();
-
-			var this_type = new ObjectType (t);
-			var cselfparam = new CCodeFormalParameter ("self", this_type.get_cname ());
-			CCodeFormalParameter cvalueparam;
-			if (returns_real_struct) {
-				cvalueparam = new CCodeFormalParameter ("value", prop.property_type.get_cname () + "*");
-			} else {
-				cvalueparam = new CCodeFormalParameter ("value", prop.property_type.get_cname ());
-			}
-
-			if (prop.get_accessor != null) {
-				var vdeclarator = new CCodeFunctionDeclarator ("get_%s".printf (prop.name));
-				vdeclarator.add_parameter (cselfparam);
-				string creturn_type;
-				if (returns_real_struct) {
-					vdeclarator.add_parameter (cvalueparam);
-					creturn_type = "void";
-				} else {
-					creturn_type = prop.property_type.get_cname ();
-				}
-				var vdecl = new CCodeDeclaration (creturn_type);
-				vdecl.add_declarator (vdeclarator);
-				type_struct.add_declaration (vdecl);
-			}
-			if (prop.set_accessor != null) {
-				var vdeclarator = new CCodeFunctionDeclarator ("set_%s".printf (prop.name));
-				vdeclarator.add_parameter (cselfparam);
-				vdeclarator.add_parameter (cvalueparam);
-				var vdecl = new CCodeDeclaration ("void");
-				vdecl.add_declarator (vdeclarator);
-				type_struct.add_declaration (vdecl);
-			}
-		}
-
-		foreach (Field f in cl.get_fields ()) {
-			string field_ctype = f.field_type.get_cname ();
-			if (f.is_volatile) {
-				field_ctype = "volatile " + field_ctype;
-			}
-
-			if (f.binding == MemberBinding.INSTANCE && f.access != SymbolAccessibility.PRIVATE)  {
-				generate_type_declaration (f.field_type, decl_space);
-
-				instance_struct.add_field (field_ctype, f.get_cname ());
-				if (f.field_type is ArrayType && !f.no_array_length) {
-					// create fields to store array dimensions
-					var array_type = (ArrayType) f.field_type;
-					var len_type = int_type.copy ();
-
-					for (int dim = 1; dim <= array_type.rank; dim++) {
-						instance_struct.add_field (len_type.get_cname (), head.get_array_length_cname (f.name, dim));
-					}
-
-					if (array_type.rank == 1 && f.is_internal_symbol ()) {
-						instance_struct.add_field (len_type.get_cname (), head.get_array_size_cname (f.name));
-					}
-				} else if (f.field_type is DelegateType) {
-					var delegate_type = (DelegateType) f.field_type;
-					if (delegate_type.delegate_symbol.has_target) {
-						// create field to store delegate target
-						instance_struct.add_field ("gpointer", get_delegate_target_cname (f.name));
-					}
-				}
-			} else if (f.binding == MemberBinding.CLASS && f.access != SymbolAccessibility.PRIVATE)  {
-				type_struct.add_field (field_ctype, f.get_cname ());
-			}
-		}
-
-		if (cl.source_reference.comment != null) {
-			decl_space.add_type_definition (new CCodeComment (cl.source_reference.comment));
-		}
-		decl_space.add_type_definition (instance_struct);
-
-		if (is_gtypeinstance) {
-			decl_space.add_type_definition (type_struct);
-		}
-	}
-
-	public virtual void generate_virtual_method_declaration (Method m, CCodeDeclarationSpace decl_space, CCodeStruct type_struct) {
-		if (!m.is_abstract && !m.is_virtual) {
-			return;
-		}
-
-		// add vfunc field to the type struct
-		var vdeclarator = new CCodeFunctionDeclarator (m.vfunc_name);
-		var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
-
-		generate_cparameters (m, decl_space, cparam_map, new CCodeFunction ("fake"), vdeclarator);
-
-		var vdecl = new CCodeDeclaration (m.return_type.get_cname ());
-		vdecl.add_declarator (vdeclarator);
-		type_struct.add_declaration (vdecl);
-	}
-
-	void generate_class_private_declaration (Class cl, CCodeDeclarationSpace decl_space) {
-		if (decl_space.add_symbol_declaration (cl, cl.get_cname () + "Private")) {
-			return;
-		}
-
-		bool is_gtypeinstance = !cl.is_compact;
-
-		var instance_priv_struct = new CCodeStruct ("_%sPrivate".printf (cl.get_cname ()));
-		var type_priv_struct = new CCodeStruct ("_%sClassPrivate".printf (cl.get_cname ()));
-
-		if (is_gtypeinstance) {
-			/* create type, dup_func, and destroy_func fields for generic types */
-			foreach (TypeParameter type_param in cl.get_type_parameters ()) {
-				string func_name;
-
-				func_name = "%s_type".printf (type_param.name.down ());
-				instance_priv_struct.add_field ("GType", func_name);
-
-				func_name = "%s_dup_func".printf (type_param.name.down ());
-				instance_priv_struct.add_field ("GBoxedCopyFunc", func_name);
-
-				func_name = "%s_destroy_func".printf (type_param.name.down ());
-				instance_priv_struct.add_field ("GDestroyNotify", func_name);
-			}
-		}
-
-		foreach (Field f in cl.get_fields ()) {
-			string field_ctype = f.field_type.get_cname ();
-			if (f.is_volatile) {
-				field_ctype = "volatile " + field_ctype;
-			}
-
-			if (f.binding == MemberBinding.INSTANCE && f.access == SymbolAccessibility.PRIVATE)  {
-				generate_type_declaration (f.field_type, decl_space);
-
-				instance_priv_struct.add_field (field_ctype, f.get_cname ());
-				if (f.field_type is ArrayType && !f.no_array_length) {
-					// create fields to store array dimensions
-					var array_type = (ArrayType) f.field_type;
-					var len_type = int_type.copy ();
-
-					for (int dim = 1; dim <= array_type.rank; dim++) {
-						instance_priv_struct.add_field (len_type.get_cname (), head.get_array_length_cname (f.name, dim));
-					}
-
-					if (array_type.rank == 1 && f.is_internal_symbol ()) {
-						instance_priv_struct.add_field (len_type.get_cname (), head.get_array_size_cname (f.name));
-					}
-				} else if (f.field_type is DelegateType) {
-					var delegate_type = (DelegateType) f.field_type;
-					if (delegate_type.delegate_symbol.has_target) {
-						// create field to store delegate target
-						instance_priv_struct.add_field ("gpointer", get_delegate_target_cname (f.name));
-					}
-				}
-
-				if (f.get_lock_used ()) {
-					// add field for mutex
-					instance_priv_struct.add_field (mutex_type.get_cname (), get_symbol_lock_name (f));
-				}
-			} else if (f.binding == MemberBinding.CLASS && f.access == SymbolAccessibility.PRIVATE)  {
-				type_priv_struct.add_field (field_ctype, f.get_cname ());
-			}
-		}
-
-		if (is_gtypeinstance) {
-			if (cl.has_class_private_fields) {
-				decl_space.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (type_priv_struct.name), new CCodeVariableDeclarator ("%sClassPrivate".printf (cl.get_cname ()))));
-				var cdecl = new CCodeDeclaration ("GQuark");
-				cdecl.add_declarator (new CCodeVariableDeclarator ("_vala_%s_class_private_quark".printf (cl.get_lower_case_cname ()), new CCodeConstant ("0")));
-				cdecl.modifiers = CCodeModifiers.STATIC;
-				decl_space.add_type_declaration (cdecl);
-			}
-
-			/* only add the *Private struct if it is not empty, i.e. we actually have private data */
-			if (cl.has_private_fields || cl.get_type_parameters ().size > 0) {
-				decl_space.add_type_definition (instance_priv_struct);
-				var macro = "(G_TYPE_INSTANCE_GET_PRIVATE ((o), %s, %sPrivate))".printf (cl.get_type_id (), cl.get_cname ());
-				decl_space.add_type_member_declaration (new CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (cl.get_upper_case_cname (null)), macro));
-			}
-
-			if (cl.has_class_private_fields) {
-				decl_space.add_type_member_declaration (type_priv_struct);
-
-				var macro = "((%sClassPrivate *) g_type_get_qdata (type, _vala_%s_class_private_quark))".printf (cl.get_cname(), cl.get_lower_case_cname ());
-				decl_space.add_type_member_declaration (new CCodeMacroReplacement ("%s_GET_CLASS_PRIVATE(type)".printf (cl.get_upper_case_cname (null)), macro));
-			}
-			decl_space.add_type_member_declaration (prop_enum);
-		} else {
-			var function = new CCodeFunction (cl.get_lower_case_cprefix () + "free", "void");
-			if (cl.access == SymbolAccessibility.PRIVATE) {
-				function.modifiers = CCodeModifiers.STATIC;
-			}
-
-			function.add_parameter (new CCodeFormalParameter ("self", cl.get_cname () + "*"));
-
-			decl_space.add_type_member_declaration (function);
-		}
-	}
-
-	public override void visit_class (Class cl) {
-		var old_symbol = current_symbol;
-		var old_type_symbol = current_type_symbol;
-		var old_class = current_class;
-		var old_param_spec_struct = param_spec_struct;
-		var old_prop_enum = prop_enum;
-		var old_class_init_fragment = class_init_fragment;
-		var old_base_init_fragment = base_init_fragment;
-		var old_class_finalize_fragment = class_finalize_fragment;
-		var old_base_finalize_fragment = base_finalize_fragment;
-		var old_instance_init_fragment = instance_init_fragment;
-		var old_instance_finalize_fragment = instance_finalize_fragment;
-		current_symbol = cl;
-		current_type_symbol = cl;
-		current_class = cl;
-
-		bool is_gtypeinstance = !cl.is_compact;
-		bool is_gobject = cl.is_subtype_of (gobject_type);
-		bool is_fundamental = is_gtypeinstance && cl.base_class == null;
-
-		if (cl.get_cname().len () < 3) {
-			cl.error = true;
-			Report.error (cl.source_reference, "Class name `%s' is too short".printf (cl.get_cname ()));
-			return;
-		}
-
-		prop_enum = new CCodeEnum ();
-		prop_enum.add_value (new CCodeEnumValue ("%s_DUMMY_PROPERTY".printf (cl.get_upper_case_cname (null))));
-		class_init_fragment = new CCodeFragment ();
-		base_init_fragment = new CCodeFragment ();
-		class_finalize_fragment = new CCodeFragment ();
-		base_finalize_fragment = new CCodeFragment ();
-		instance_init_fragment = new CCodeFragment ();
-		instance_finalize_fragment = new CCodeFragment ();
-
-
-		generate_class_struct_declaration (cl, source_declarations);
-		generate_class_private_declaration (cl, source_declarations);
-
-		if (!cl.is_internal_symbol ()) {
-			generate_class_struct_declaration (cl, header_declarations);
-		}
-		generate_class_struct_declaration (cl, internal_header_declarations);
-
-		cl.accept_children (codegen);
-
-		if (is_gtypeinstance) {
-			if (is_fundamental) {
-				param_spec_struct = new CCodeStruct ( "_%sParamSpec%s".printf(cl.parent_symbol.get_cprefix (), cl.name));
-				param_spec_struct.add_field ("GParamSpec", "parent_instance");
-				source_declarations.add_type_definition (param_spec_struct);
-
-				source_declarations.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (param_spec_struct.name), new CCodeVariableDeclarator ( "%sParamSpec%s".printf(cl.parent_symbol.get_cprefix (), cl.name))));
-
-
-				gvaluecollector_h_needed = true;
-
-				add_type_value_table_init_function (cl);
-				add_type_value_table_free_function (cl);
-				add_type_value_table_copy_function (cl);
-				add_type_value_table_peek_pointer_function (cl);
-				add_type_value_table_collect_value_function (cl);
-				add_type_value_table_lcopy_value_function (cl);
-				add_g_param_spec_type_function (cl);
-				add_g_value_get_function (cl);
-				add_g_value_set_function (cl);
-
-				var ref_count = new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "ref_count"), new CCodeConstant ("1"));
-				instance_init_fragment.append (new CCodeExpressionStatement (ref_count));
-			} else if (is_gobject) {
-				if (class_has_readable_properties (cl) || cl.get_type_parameters ().size > 0) {
-					add_get_property_function (cl);
-				}
-				if (class_has_writable_properties (cl) || cl.get_type_parameters ().size > 0) {
-					add_set_property_function (cl);
-				}
-			}
-
-
-			if (cl.class_constructor != null || cl.has_class_private_fields) {
-				add_base_init_function (cl);
-			}
-			add_class_init_function (cl);
-
-			if (cl.class_destructor != null || cl.has_class_private_fields) {
-				add_base_finalize_function (cl);
-			}
-
-			if (cl.static_destructor != null) {
-				add_class_finalize_function (cl);
-			}
-
-			foreach (DataType base_type in cl.get_base_types ()) {
-				if (base_type.data_type is Interface) {
-					add_interface_init_function (cl, (Interface) base_type.data_type);
-				}
-			}
-			
-			add_instance_init_function (cl);
-
-			if (!cl.is_compact && (cl.get_fields ().size > 0 || cl.destructor != null || cl.is_fundamental ())) {
-				add_finalize_function (cl);
-			}
-
-			var type_fun = new ClassRegisterFunction (cl, context);
-			type_fun.init_from_type (in_plugin);
-			source_type_member_definition.append (type_fun.get_definition ());
-			
-			if (in_plugin) {
-				// FIXME resolve potential dependency issues, i.e. base types have to be registered before derived types
-				var register_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_register_type".printf (cl.get_lower_case_cname (null))));
-				register_call.add_argument (new CCodeIdentifier (module_init_param_name));
-				module_init_fragment.append (new CCodeExpressionStatement (register_call));
-			}
-
-			if (is_fundamental) {
-				var ref_fun = new CCodeFunction (cl.get_lower_case_cprefix () + "ref", "gpointer");
-				var unref_fun = new CCodeFunction (cl.get_lower_case_cprefix () + "unref", "void");
-				if (cl.access == SymbolAccessibility.PRIVATE) {
-					ref_fun.modifiers = CCodeModifiers.STATIC;
-					unref_fun.modifiers = CCodeModifiers.STATIC;
-				}
-
-				ref_fun.add_parameter (new CCodeFormalParameter ("instance", "gpointer"));
-				unref_fun.add_parameter (new CCodeFormalParameter ("instance", "gpointer"));
-
-				var ref_block = new CCodeBlock ();
-				var unref_block = new CCodeBlock ();
-
-				var cdecl = new CCodeDeclaration (cl.get_cname () + "*");
-				cdecl.add_declarator (new CCodeVariableDeclarator ("self", new CCodeIdentifier ("instance")));
-				ref_block.add_statement (cdecl);
-				unref_block.add_statement (cdecl);
-
-				var ref_count = new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "ref_count");
-
-				var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_atomic_int_inc"));
-				ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ref_count));
-				ref_block.add_statement (new CCodeExpressionStatement (ccall));
-
-				ref_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("instance")));
-
-				var destroy_block = new CCodeBlock ();
-				var get_class = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS".printf (cl.get_upper_case_cname (null))));
-				get_class.add_argument (new CCodeIdentifier ("self"));
-
-				// finalize class
-				var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS".printf (cl.get_upper_case_cname (null))));
-				ccast.add_argument (new CCodeIdentifier ("self"));
-				ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (ccast, "finalize"));
-				ccall.add_argument (new CCodeIdentifier ("self"));
-				destroy_block.add_statement (new CCodeExpressionStatement (ccall));
-
-				// free type instance
-				var free = new CCodeFunctionCall (new CCodeIdentifier ("g_type_free_instance"));
-				free.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "GTypeInstance *"));
-				destroy_block.add_statement (new CCodeExpressionStatement (free));
-
-				ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_atomic_int_dec_and_test"));
-				ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ref_count));
-				unref_block.add_statement (new CCodeIfStatement (ccall, destroy_block));
-
-				ref_fun.block = ref_block;
-				unref_fun.block = unref_block;
-
-				source_type_member_definition.append (ref_fun);
-				source_type_member_definition.append (unref_fun);
-			}
-		} else {
-			add_instance_init_function (cl);
-
-			var function = new CCodeFunction (cl.get_lower_case_cprefix () + "free", "void");
-			if (cl.access == SymbolAccessibility.PRIVATE) {
-				function.modifiers = CCodeModifiers.STATIC;
-			}
-
-			function.add_parameter (new CCodeFormalParameter ("self", cl.get_cname () + "*"));
-
-			var cblock = new CCodeBlock ();
-
-			cblock.add_statement (instance_finalize_fragment);
-
-			if (cl.destructor != null) {
-				cblock.add_statement (cl.destructor.ccodenode);
-			}
-
-			var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_free"));
-			ccall.add_argument (new CCodeIdentifier (cl.get_cname ()));
-			ccall.add_argument (new CCodeIdentifier ("self"));
-			cblock.add_statement (new CCodeExpressionStatement (ccall));
-
-			function.block = cblock;
-
-			source_type_member_definition.append (function);
-		}
-
-		current_symbol = old_symbol;
-		current_type_symbol = old_type_symbol;
-		current_class = old_class;
-		param_spec_struct = old_param_spec_struct;
-		prop_enum = old_prop_enum;
-		class_init_fragment = old_class_init_fragment;
-		base_init_fragment = old_base_init_fragment;
-		class_finalize_fragment = old_class_finalize_fragment;
-		base_finalize_fragment = old_base_finalize_fragment;
-		instance_init_fragment = old_instance_init_fragment;
-		instance_finalize_fragment = old_instance_finalize_fragment;
-	}
-
-	private void add_type_value_table_init_function (Class cl) {
-		var function = new CCodeFunction ("%s_init".printf (cl.get_lower_case_cname ("value_")), "void");
-		function.add_parameter (new CCodeFormalParameter ("value", "GValue*"));
-		function.modifiers = CCodeModifiers.STATIC;
-
-		var init_block = new CCodeBlock ();
-		function.block = init_block;
-
-		init_block.add_statement(new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess(new CCodeMemberAccess.pointer (new CCodeIdentifier ("value"), "data[0]"),"v_pointer"),new CCodeConstant ("NULL"), CCodeAssignmentOperator.SIMPLE)));
-		source_type_member_definition.append (function);
-	}
-
-	private void add_type_value_table_free_function (Class cl) {
-		var function = new CCodeFunction ("%s_free_value".printf (cl.get_lower_case_cname ("value_")), "void");
-		function.add_parameter (new CCodeFormalParameter ("value", "GValue*"));
-		function.modifiers = CCodeModifiers.STATIC;
-
-		var init_block = new CCodeBlock ();
-		function.block = init_block;
-		
-		var vpointer = new CCodeMemberAccess(new CCodeMemberAccess.pointer (new CCodeIdentifier ("value"), "data[0]"),"v_pointer");
-		var ccall = new CCodeFunctionCall (new CCodeIdentifier (cl.get_lower_case_cprefix () + "unref"));
-		ccall.add_argument ( vpointer );
-
-		var ifbody = new CCodeBlock ();
-		ifbody.add_statement ( new CCodeExpressionStatement(ccall) );
-
-		init_block.add_statement(new CCodeIfStatement (vpointer, ifbody));
-		source_type_member_definition.append (function);
-	}
-
-	private void add_type_value_table_copy_function (Class cl) {
-		var function = new CCodeFunction ("%s_copy_value".printf (cl.get_lower_case_cname ("value_")), "void");
-		function.add_parameter (new CCodeFormalParameter ("src_value", "const GValue*"));
-		function.add_parameter (new CCodeFormalParameter ("dest_value", "GValue*"));
-		function.modifiers = CCodeModifiers.STATIC;
-
-		var init_block = new CCodeBlock ();
-		function.block = init_block;
-
-		var dest_vpointer = new CCodeMemberAccess (new CCodeMemberAccess.pointer (new CCodeIdentifier ("dest_value"), "data[0]"),"v_pointer");
-		var src_vpointer = new CCodeMemberAccess (new CCodeMemberAccess.pointer (new CCodeIdentifier ("src_value"), "data[0]"),"v_pointer");
-
-		var ref_ccall = new CCodeFunctionCall (new CCodeIdentifier (cl.get_lower_case_cprefix () + "ref"));
-		ref_ccall.add_argument ( src_vpointer );
-
-		var true_stmt = new CCodeBlock ();
-		true_stmt.add_statement(new CCodeExpressionStatement(new CCodeAssignment (dest_vpointer, ref_ccall, CCodeAssignmentOperator.SIMPLE)));
-
-		var false_stmt = new CCodeBlock ();
-		false_stmt.add_statement (new CCodeExpressionStatement( new CCodeAssignment (dest_vpointer, new CCodeConstant ("NULL"), CCodeAssignmentOperator.SIMPLE)));
-
-		var if_statement = new CCodeIfStatement (src_vpointer, true_stmt, false_stmt);
-		init_block.add_statement (if_statement);
-
-		source_type_member_definition.append (function);
-	}
-
-	private void add_type_value_table_peek_pointer_function (Class cl) {
-		var function = new CCodeFunction ("%s_peek_pointer".printf (cl.get_lower_case_cname ("value_")), "gpointer");
-		function.add_parameter (new CCodeFormalParameter ("value", "const GValue*"));
-		function.modifiers = CCodeModifiers.STATIC;
-
-		var init_block = new CCodeBlock ();
-		function.block = init_block;
-
-		var vpointer = new CCodeMemberAccess(new CCodeMemberAccess.pointer (new CCodeIdentifier ("value"), "data[0]"),"v_pointer");
-		var ret = new CCodeReturnStatement ( vpointer );
-		init_block.add_statement (ret);
-
-		source_type_member_definition.append (function);
-	}
-
-	private void add_type_value_table_lcopy_value_function ( Class cl ) {
-		var function = new CCodeFunction ("%s_lcopy_value".printf (cl.get_lower_case_cname ("value_")), "gchar*");
-		function.add_parameter (new CCodeFormalParameter ("value", "const GValue*"));
-		function.add_parameter (new CCodeFormalParameter ("n_collect_values", "guint"));
-		function.add_parameter (new CCodeFormalParameter ("collect_values", "GTypeCValue*"));
-		function.add_parameter (new CCodeFormalParameter ("collect_flags", "guint"));
-		function.modifiers = CCodeModifiers.STATIC;
-
-		var vpointer = new CCodeMemberAccess (new CCodeMemberAccess.pointer (new CCodeIdentifier ("value"), "data[0]"), "v_pointer");
-		var object_p_ptr = new CCodeIdentifier ("*object_p");
-		var null_ = new CCodeConstant ("NULL");
-
-		var init_block = new CCodeBlock ();
-
-		var ctypedecl = new CCodeDeclaration (cl.get_cname () + "**");
-		ctypedecl.add_declarator (new CCodeVariableDeclarator ("object_p", new CCodeMemberAccess (new CCodeIdentifier ("collect_values[0]"),"v_pointer")));
-		init_block.add_statement (ctypedecl);
-
-		var value_type_name_fct = new CCodeFunctionCall (new CCodeIdentifier ("G_VALUE_TYPE_NAME"));
-		value_type_name_fct.add_argument (new CCodeConstant ("value"));
-
-		var assert_condition = new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("object_p"));
-		function.block = init_block;
-		var assert_true = new CCodeBlock ();
-		var assert_printf = new CCodeFunctionCall (new CCodeIdentifier ("g_strdup_printf"));
-		assert_printf.add_argument (new CCodeConstant ("\"value location for `%s' passed as NULL\""));
-		assert_printf.add_argument (value_type_name_fct);
-		assert_true.add_statement (new CCodeReturnStatement (assert_printf));
-		var if_assert = new CCodeIfStatement (assert_condition, assert_true);
-		init_block.add_statement (if_assert);
-
-		var main_else_true = new CCodeBlock ();
-		var main_else_if_true = new CCodeBlock ();
-		var main_else_if_condition = new CCodeBinaryExpression (CCodeBinaryOperator.AND, new CCodeIdentifier ("collect_flags"), new CCodeIdentifier ("G_VALUE_NOCOPY_CONTENTS"));
-		var main_else_if = new CCodeIfStatement (main_else_if_condition, main_else_if_true, main_else_true);
-
-		var main_true = new CCodeBlock ();
-		var main_condition = new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, vpointer);
-		var if_main = new CCodeIfStatement (main_condition, main_true, main_else_if);
-		init_block.add_statement (if_main);
-
-		var ref_fct = new CCodeFunctionCall (new CCodeIdentifier (cl.get_ref_function()));
-		ref_fct.add_argument (vpointer);
-
-		main_true.add_statement (new CCodeExpressionStatement (new CCodeAssignment (object_p_ptr, null_, CCodeAssignmentOperator.SIMPLE)));
-		main_else_if_true.add_statement (new CCodeExpressionStatement (new CCodeAssignment (object_p_ptr, vpointer, CCodeAssignmentOperator.SIMPLE)));
-		main_else_true.add_statement (new CCodeExpressionStatement (new CCodeAssignment (object_p_ptr, ref_fct, CCodeAssignmentOperator.SIMPLE)));
-
-		init_block.add_statement (new CCodeReturnStatement (null_));
-		source_type_member_definition.append (function);
-	}
-
-	private void add_type_value_table_collect_value_function (Class cl) {
-		var function = new CCodeFunction ("%s_collect_value".printf (cl.get_lower_case_cname ("value_")), "gchar*");
-		function.add_parameter (new CCodeFormalParameter ("value", "GValue*"));
-		function.add_parameter (new CCodeFormalParameter ("n_collect_values", "guint"));
-		function.add_parameter (new CCodeFormalParameter ("collect_values", "GTypeCValue*"));
-		function.add_parameter (new CCodeFormalParameter ("collect_flags", "guint"));
-		function.modifiers = CCodeModifiers.STATIC;
-
-		var vpointer = new CCodeMemberAccess(new CCodeMemberAccess.pointer (new CCodeIdentifier ("value"), "data[0]"),"v_pointer");
-
-		var init_block = new CCodeBlock ();
-		function.block = init_block;
-
-		var collect_vpointer = new CCodeMemberAccess (new CCodeIdentifier ("collect_values[0]"), "v_pointer");
-
-		var true_stmt = new CCodeBlock ();
-		var false_stmt = new CCodeBlock ();
-		var if_statement = new CCodeIfStatement (collect_vpointer, true_stmt, false_stmt);
-		init_block.add_statement (if_statement);
-
-		var obj_identifier = new CCodeIdentifier ("object");
-
-		var ctypedecl = new CCodeDeclaration (cl.get_cname () + "*");
-		ctypedecl.add_declarator (new CCodeVariableDeclarator ("object", collect_vpointer));
-		true_stmt.add_statement (ctypedecl);
-
-		var l_expression = new CCodeMemberAccess (new CCodeMemberAccess.pointer (obj_identifier, "parent_instance"), "g_class");
-		var sub_condition = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, l_expression, new CCodeConstant ("NULL"));
-		var sub_true_stmt = new CCodeBlock ();
-		var sub_false_stmt = new CCodeBlock ();
-
-		var reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_value_type_compatible"));
-		var type_check = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_FROM_INSTANCE"));
-		type_check.add_argument (new CCodeIdentifier ("object"));
-		reg_call.add_argument (type_check);
-
-		var type_name_fct = new CCodeFunctionCall (new CCodeIdentifier ("g_type_name"));
-		type_name_fct.add_argument (type_check);
-
-		var stored_type = new CCodeFunctionCall (new CCodeIdentifier ("G_VALUE_TYPE"));
-		stored_type.add_argument (new CCodeIdentifier ("value"));
-		reg_call.add_argument (stored_type);
-
-		var value_type_name_fct = new CCodeFunctionCall (new CCodeIdentifier ("G_VALUE_TYPE_NAME"));
-		value_type_name_fct.add_argument (new CCodeConstant ("value"));
-
-		var true_return = new CCodeFunctionCall (new CCodeIdentifier ("g_strconcat"));
-		true_return.add_argument (new CCodeConstant ("\"invalid unclassed object pointer for value type `\""));
-		true_return.add_argument (value_type_name_fct);
-		true_return.add_argument (new CCodeConstant ("\"'\""));
-		true_return.add_argument (new CCodeConstant ("NULL"));
-		sub_true_stmt.add_statement (new CCodeReturnStatement (true_return));
-
-		var false_return = new CCodeFunctionCall (new CCodeIdentifier ("g_strconcat"));
-		false_return.add_argument (new CCodeConstant ("\"invalid object type `\""));
-		false_return.add_argument (type_name_fct);
-		false_return.add_argument (new CCodeConstant ("\"' for value type `\""));
-		false_return.add_argument (value_type_name_fct);
-		false_return.add_argument (new CCodeConstant ("\"'\""));
-		false_return.add_argument (new CCodeConstant ("NULL"));
-		sub_false_stmt.add_statement (new CCodeReturnStatement (false_return));
-
-		var sub_else_if_statement = new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, reg_call), sub_false_stmt );
-		sub_else_if_statement.else_if = true;
-		var sub_if_statement = new CCodeIfStatement (sub_condition, sub_true_stmt, sub_else_if_statement);
-		true_stmt.add_statement (sub_if_statement);
-
-		var ref_call = new CCodeFunctionCall (new CCodeIdentifier (cl.get_ref_function ()));
-		ref_call.add_argument (new CCodeIdentifier ("object"));
-
-		var true_assignment = new CCodeExpressionStatement (new CCodeAssignment (vpointer, ref_call, CCodeAssignmentOperator.SIMPLE));
-		true_stmt.add_statement (true_assignment);
-
-		var else_assigment = new CCodeExpressionStatement (new CCodeAssignment (vpointer, new CCodeConstant ("NULL"), CCodeAssignmentOperator.SIMPLE));
-		false_stmt.add_statement (else_assigment);
-
-		init_block.add_statement (new CCodeReturnStatement (new CCodeConstant ("NULL")));
-		source_type_member_definition.append (function);
-	}
-
-	private void add_g_param_spec_type_function (Class cl) {
-		var function_name = cl.get_lower_case_cname ("param_spec_");
-
-		var function = new CCodeFunction (function_name, "GParamSpec*");
-		function.add_parameter (new CCodeFormalParameter ("name", "const gchar*"));
-		function.add_parameter (new CCodeFormalParameter ("nick", "const gchar*"));
-		function.add_parameter (new CCodeFormalParameter ("blurb", "const gchar*"));
-		function.add_parameter (new CCodeFormalParameter ("object_type", "GType"));
-		function.add_parameter (new CCodeFormalParameter ("flags", "GParamFlags"));
-
-		cl.set_param_spec_function ( function_name );
-
-		if (cl.access == SymbolAccessibility.PRIVATE) {
-			function.modifiers = CCodeModifiers.STATIC;
-		}
-
-		var init_block = new CCodeBlock ();
-		function.block = init_block;
-
-		var ctypedecl = new CCodeDeclaration ("%sParamSpec%s*".printf (cl.parent_symbol.get_cprefix (), cl.name));
-		ctypedecl.add_declarator ( new CCodeVariableDeclarator ("spec"));
-		init_block.add_statement (ctypedecl);
-
-		var subccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_is_a"));
-		subccall.add_argument (new CCodeIdentifier ("object_type"));
-		subccall.add_argument (new CCodeIdentifier ( cl.get_type_id() ));
-
-		var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_return_val_if_fail"));
-		ccall.add_argument (subccall);
-		ccall.add_argument (new CCodeIdentifier ("NULL"));
-		init_block.add_statement (new CCodeExpressionStatement (ccall));
-
-		ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_param_spec_internal"));
-		ccall.add_argument (new CCodeIdentifier ( "G_TYPE_PARAM_OBJECT" ));
-		ccall.add_argument (new CCodeIdentifier ("name"));
-		ccall.add_argument (new CCodeIdentifier ("nick"));
-		ccall.add_argument (new CCodeIdentifier ("blurb"));
-		ccall.add_argument (new CCodeIdentifier ("flags"));
-
-		init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("spec"), ccall, CCodeAssignmentOperator.SIMPLE )));
-
-		ccall = new CCodeFunctionCall (new CCodeIdentifier ("G_PARAM_SPEC"));
-		ccall.add_argument (new CCodeIdentifier ("spec"));
-
-		init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "value_type"), new CCodeIdentifier ("object_type"), CCodeAssignmentOperator.SIMPLE )));
-		init_block.add_statement (new CCodeReturnStatement (ccall));
-		source_type_member_definition.append (function);
-	}
-
-	private void add_g_value_set_function (Class cl) {
-		var function = new CCodeFunction (cl.get_set_value_function (), "void");
-		function.add_parameter (new CCodeFormalParameter ("value", "GValue*"));
-		function.add_parameter (new CCodeFormalParameter ("v_object", "gpointer"));
-
-		if (cl.access == SymbolAccessibility.PRIVATE) {
-			function.modifiers = CCodeModifiers.STATIC;
-		}
-
-		var vpointer = new CCodeMemberAccess(new CCodeMemberAccess.pointer (new CCodeIdentifier ("value"), "data[0]"),"v_pointer");
-
-		var init_block = new CCodeBlock ();
-		function.block = init_block;
-
-		var ctypedecl = new CCodeDeclaration (cl.get_cname()+"*");
-		ctypedecl.add_declarator ( new CCodeVariableDeclarator ("old"));
-		init_block.add_statement (ctypedecl);
-
-		var ccall_typecheck = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_CHECK_VALUE_TYPE"));
-		ccall_typecheck.add_argument (new CCodeIdentifier ( "value" ));
-		ccall_typecheck.add_argument (new CCodeIdentifier ( cl.get_type_id() ));
-
-		var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_return_if_fail"));
-		ccall.add_argument (ccall_typecheck);
-		init_block.add_statement (new CCodeExpressionStatement (ccall));
-
-		init_block.add_statement(new CCodeExpressionStatement (new CCodeAssignment (new CCodeConstant ("old"), vpointer, CCodeAssignmentOperator.SIMPLE)));
-
-		var true_stmt = new CCodeBlock ();
-		var false_stmt = new CCodeBlock ();
-		var if_statement = new CCodeIfStatement (new CCodeIdentifier ("v_object"), true_stmt, false_stmt);
-		init_block.add_statement (if_statement);
-
-
-		ccall_typecheck = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_CHECK_INSTANCE_TYPE"));
-		ccall_typecheck.add_argument (new CCodeIdentifier ( "v_object" ));
-		ccall_typecheck.add_argument (new CCodeIdentifier ( cl.get_type_id() ));
-
-		ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_return_if_fail"));
-		ccall.add_argument (ccall_typecheck);
-		true_stmt.add_statement (new CCodeExpressionStatement (ccall));
-
-		var ccall_typefrominstance = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_FROM_INSTANCE"));
-		ccall_typefrominstance.add_argument (new CCodeIdentifier ( "v_object" ));
-
-		var ccall_gvaluetype = new CCodeFunctionCall (new CCodeIdentifier ("G_VALUE_TYPE"));
-		ccall_gvaluetype.add_argument (new CCodeIdentifier ( "value" ));
-
-		var ccall_typecompatible = new CCodeFunctionCall (new CCodeIdentifier ("g_value_type_compatible"));
-		ccall_typecompatible.add_argument (ccall_typefrominstance);
-		ccall_typecompatible.add_argument (ccall_gvaluetype);
-
-		ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_return_if_fail"));
-		ccall.add_argument (ccall_typecompatible);
-		true_stmt.add_statement (new CCodeExpressionStatement (ccall));
-
-		true_stmt.add_statement(new CCodeExpressionStatement (new CCodeAssignment (vpointer, new CCodeConstant ("v_object"), CCodeAssignmentOperator.SIMPLE)));
-
-		ccall = new CCodeFunctionCall (new CCodeIdentifier (cl.get_ref_function ()));
-		ccall.add_argument (vpointer);
-		true_stmt.add_statement (new CCodeExpressionStatement (ccall));
-
-		false_stmt.add_statement(new CCodeExpressionStatement (new CCodeAssignment (vpointer, new CCodeConstant ("NULL"), CCodeAssignmentOperator.SIMPLE)));
-
-		true_stmt = new CCodeBlock ();
-		if_statement = new CCodeIfStatement (new CCodeIdentifier ("old"), true_stmt);
-		init_block.add_statement (if_statement);
-		
-		ccall = new CCodeFunctionCall (new CCodeIdentifier (cl.get_unref_function ()));
-		ccall.add_argument (new CCodeIdentifier ("old"));
-		true_stmt.add_statement (new CCodeExpressionStatement (ccall));
-		source_type_member_definition.append (function);
-	}
-
-	private void add_g_value_get_function (Class cl) {
-		var function = new CCodeFunction (cl.get_get_value_function (), "gpointer");
-		function.add_parameter (new CCodeFormalParameter ("value", "const GValue*"));
-
-		if (cl.access == SymbolAccessibility.PRIVATE) {
-			function.modifiers = CCodeModifiers.STATIC;
-		}
-
-		var vpointer = new CCodeMemberAccess(new CCodeMemberAccess.pointer (new CCodeIdentifier ("value"), "data[0]"),"v_pointer");
-
-		var init_block = new CCodeBlock ();
-		function.block = init_block;
-
-		var ccall_typecheck = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_CHECK_VALUE_TYPE"));
-		ccall_typecheck.add_argument (new CCodeIdentifier ( "value" ));
-		ccall_typecheck.add_argument (new CCodeIdentifier ( cl.get_type_id() ));
-
-		var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_return_val_if_fail"));
-		ccall.add_argument (ccall_typecheck);
-		ccall.add_argument (new CCodeIdentifier ( "NULL" ));
-		init_block.add_statement (new CCodeExpressionStatement (ccall));
-
-		init_block.add_statement (new CCodeReturnStatement ( vpointer ));
-		source_type_member_definition.append (function);
-	}
-
-	private void add_base_init_function (Class cl) {
-		var base_init = new CCodeFunction ("%s_base_init".printf (cl.get_lower_case_cname (null)), "void");
-		base_init.add_parameter (new CCodeFormalParameter ("klass", "%sClass *".printf (cl.get_cname ())));
-		base_init.modifiers = CCodeModifiers.STATIC;
-
-		var init_block = new CCodeBlock ();
-		base_init.block = init_block;
-
-		if (cl.has_class_private_fields) {
-			var block = new CCodeBlock ();
-			var cdecl = new CCodeDeclaration ("%sClassPrivate *".printf (cl.get_cname ()));
-			cdecl.add_declarator (new CCodeVariableDeclarator ("priv"));
-			block.add_statement (cdecl);
-			cdecl = new CCodeDeclaration ("%sClassPrivate *".printf (cl.get_cname ()));
-			cdecl.add_declarator (new CCodeVariableDeclarator ("parent_priv", new CCodeConstant ("NULL")));
-			block.add_statement (cdecl);
-			cdecl = new CCodeDeclaration ("GType");
-			cdecl.add_declarator (new CCodeVariableDeclarator ("parent_type"));
-			block.add_statement (cdecl);
-
-			var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_parent"));
-			var ccall2 = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_FROM_CLASS"));
-			ccall2.add_argument (new CCodeIdentifier ("klass"));
-			ccall.add_argument (ccall2);
-			block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("parent_type"), ccall)));
-
-			var iftrue = new CCodeBlock ();
-			ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS_PRIVATE".printf (cl.get_upper_case_cname (null))));
-			ccall.add_argument (new CCodeIdentifier ("parent_type"));
-			iftrue.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("parent_priv"), ccall)));
-			block.add_statement (new CCodeIfStatement (new CCodeIdentifier ("parent_type"), iftrue));
-
-			ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_new0"));
-			ccall.add_argument (new CCodeIdentifier ("%sClassPrivate".printf(cl.get_cname())));
-
-			block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("priv"), ccall)));
-
-			source_declarations.add_include ("string.h");
-
-			iftrue = new CCodeBlock ();
-			ccall = new CCodeFunctionCall (new CCodeIdentifier ("memcpy"));
-			ccall.add_argument (new CCodeIdentifier ("priv"));
-			ccall.add_argument (new CCodeIdentifier ("parent_priv"));
-			ccall.add_argument (new CCodeIdentifier ("sizeof (%sClassPrivate)".printf(cl.get_cname())));
-			iftrue.add_statement (new CCodeExpressionStatement (ccall));
-
-			block.add_statement (new CCodeIfStatement (new CCodeIdentifier ("parent_priv"), iftrue));
-
-			ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_set_qdata"));
-			ccall2 = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_FROM_CLASS"));
-			ccall2.add_argument (new CCodeIdentifier ("klass"));
-			ccall.add_argument (ccall2);
-			ccall.add_argument (new CCodeIdentifier ("_vala_%s_class_private_quark".printf (cl.get_lower_case_cname ())));
-			ccall.add_argument (new CCodeIdentifier ("priv"));
-			block.add_statement (new CCodeExpressionStatement (ccall));
-
-			init_block.add_statement (block);
-
-			block = new CCodeBlock ();
-			cdecl = new CCodeDeclaration ("%sClassPrivate *".printf (cl.get_cname ()));
-			cdecl.add_declarator (new CCodeVariableDeclarator ("priv"));
-			block.add_statement (cdecl);
-
-			ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS_PRIVATE".printf (cl.get_upper_case_cname (null))));
-			ccall2 = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_FROM_CLASS"));
-			ccall2.add_argument (new CCodeIdentifier ("klass"));
-			ccall.add_argument (ccall2);
-			block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("priv"), ccall)));
-
-			ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_free"));
-			ccall.add_argument (new CCodeIdentifier ("%sClassPrivate".printf (cl.get_cname ())));
-			ccall.add_argument (new CCodeIdentifier ("priv"));
-			block.add_statement (new CCodeExpressionStatement (ccall));
-			base_finalize_fragment.append (block);
-		}
-
-		init_block.add_statement (base_init_fragment);
-
-		source_type_member_definition.append (base_init);
-	}
-
-	private void add_class_init_function (Class cl) {
-		var class_init = new CCodeFunction ("%s_class_init".printf (cl.get_lower_case_cname (null)), "void");
-		class_init.add_parameter (new CCodeFormalParameter ("klass", "%sClass *".printf (cl.get_cname ())));
-		class_init.modifiers = CCodeModifiers.STATIC;
-
-		var init_block = new CCodeBlock ();
-		class_init.block = init_block;
-		
-		CCodeFunctionCall ccall;
-		
-		/* save pointer to parent class */
-		var parent_decl = new CCodeDeclaration ("gpointer");
-		var parent_var_decl = new CCodeVariableDeclarator ("%s_parent_class".printf (cl.get_lower_case_cname (null)));
-		parent_var_decl.initializer = new CCodeConstant ("NULL");
-		parent_decl.add_declarator (parent_var_decl);
-		parent_decl.modifiers = CCodeModifiers.STATIC;
-		source_declarations.add_type_member_declaration (parent_decl);
-		ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek_parent"));
+		/* set property handlers */
+		var ccall = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
 		ccall.add_argument (new CCodeIdentifier ("klass"));
-		var parent_assignment = new CCodeAssignment (new CCodeIdentifier ("%s_parent_class".printf (cl.get_lower_case_cname (null))), ccall);
-		init_block.add_statement (new CCodeExpressionStatement (parent_assignment));
-		
-
-		if (!cl.is_compact && !cl.is_subtype_of (gobject_type) && (cl.get_fields ().size > 0 || cl.destructor != null || cl.is_fundamental ())) {
-			// set finalize function
-			var fundamental_class = cl;
-			while (fundamental_class.base_class != null) {
-				fundamental_class = fundamental_class.base_class;
-			}
-
-			ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (fundamental_class.get_upper_case_cname (null))));
-			ccall.add_argument (new CCodeIdentifier ("klass"));
-			var finalize_assignment = new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "finalize"), new CCodeIdentifier (cl.get_lower_case_cprefix () + "finalize"));
-			init_block.add_statement (new CCodeExpressionStatement (finalize_assignment));
-		}
-
-		/* add struct for private fields */
-		if (cl.has_private_fields || cl.get_type_parameters ().size > 0) {
-			ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_add_private"));
-			ccall.add_argument (new CCodeIdentifier ("klass"));
-			ccall.add_argument (new CCodeConstant ("sizeof (%sPrivate)".printf (cl.get_cname ())));
-			init_block.add_statement (new CCodeExpressionStatement (ccall));
+		if (class_has_readable_properties (cl) || cl.get_type_parameters ().size > 0) {
+			init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "get_property"), new CCodeIdentifier ("%s_get_property".printf (cl.get_lower_case_cname (null))))));
 		}
-
-		if (cl.is_subtype_of (gobject_type)) {
-			/* set property handlers */
-			ccall = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
-			ccall.add_argument (new CCodeIdentifier ("klass"));
-			if (class_has_readable_properties (cl) || cl.get_type_parameters ().size > 0) {
-				init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "get_property"), new CCodeIdentifier ("%s_get_property".printf (cl.get_lower_case_cname (null))))));
-			}
-			if (class_has_writable_properties (cl) || cl.get_type_parameters ().size > 0) {
-				init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "set_property"), new CCodeIdentifier ("%s_set_property".printf (cl.get_lower_case_cname (null))))));
-			}
-		
-			/* set constructor */
-			if (cl.constructor != null) {
-				var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
-				ccast.add_argument (new CCodeIdentifier ("klass"));
-				init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "constructor"), new CCodeIdentifier ("%s_constructor".printf (cl.get_lower_case_cname (null))))));
-			}
-
-			/* set finalize function */
-			if (cl.get_fields ().size > 0 || cl.destructor != null) {
-				var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
-				ccast.add_argument (new CCodeIdentifier ("klass"));
-				init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "finalize"), new CCodeIdentifier ("%s_finalize".printf (cl.get_lower_case_cname (null))))));
-			}
+		if (class_has_writable_properties (cl) || cl.get_type_parameters ().size > 0) {
+			init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "set_property"), new CCodeIdentifier ("%s_set_property".printf (cl.get_lower_case_cname (null))))));
 		}
-
-		/* connect overridden methods */
-		foreach (Method m in cl.get_methods ()) {
-			if (m.base_method == null) {
-				continue;
-			}
-			var base_type = m.base_method.parent_symbol;
-			
-			var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (((Class) base_type).get_upper_case_cname (null))));
+	
+		/* set constructor */
+		if (cl.constructor != null) {
+			var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
 			ccast.add_argument (new CCodeIdentifier ("klass"));
-			init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, m.base_method.vfunc_name), new CCodeIdentifier (m.get_real_cname ()))));
+			init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "constructor"), new CCodeIdentifier ("%s_constructor".printf (cl.get_lower_case_cname (null))))));
 		}
 
-		/* connect overridden properties */
-		foreach (Property prop in cl.get_properties ()) {
-			if (prop.base_property == null) {
-				continue;
-			}
-			var base_type = prop.base_property.parent_symbol;
-			
-			var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (((Class) base_type).get_upper_case_cname (null))));
+		/* set finalize function */
+		if (cl.get_fields ().size > 0 || cl.destructor != null) {
+			var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
 			ccast.add_argument (new CCodeIdentifier ("klass"));
-
-			if (prop.get_accessor != null) {
-				string cname = "%s_real_get_%s".printf (cl.get_lower_case_cname (null), prop.name);
-				init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "get_%s".printf (prop.name)), new CCodeIdentifier (cname))));
-			}
-			if (prop.set_accessor != null) {
-				string cname = "%s_real_set_%s".printf (cl.get_lower_case_cname (null), prop.name);
-				init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "set_%s".printf (prop.name)), new CCodeIdentifier (cname))));
-			}
-		}
-
-		/* initialize class fields */
-		var fields = cl.get_fields ();
-		foreach (Field field in fields) {
-			if (field.binding != MemberBinding.CLASS || field.initializer == null) {
-				continue;
-			}
-
-			CCodeExpression left;
-
-			if (field.access == SymbolAccessibility.PRIVATE) {
-				ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS_PRIVATE".printf (cl.get_upper_case_cname ())));
-				var ccall2 = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_FROM_CLASS"));
-				ccall2.add_argument (new CCodeIdentifier ("klass"));
-				ccall.add_argument (ccall2);
-				left = new CCodeMemberAccess (ccall, field.get_cname (), true);
-			} else {
-				left = new CCodeMemberAccess (new CCodeIdentifier ("klass"), field.get_cname (), true);
-			}
-			CCodeExpression right = (CCodeExpression) field.initializer.ccodenode;
-			CCodeAssignment assign = new CCodeAssignment (left, right);
-			init_block.add_statement (new CCodeExpressionStatement (assign));
+			init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "finalize"), new CCodeIdentifier ("%s_finalize".printf (cl.get_lower_case_cname (null))))));
 		}
 
-		if (cl.is_subtype_of (gobject_type)) {
-			/* create type, dup_func, and destroy_func properties for generic types */
-			foreach (TypeParameter type_param in cl.get_type_parameters ()) {
-				string func_name, enum_value;
-				CCodeConstant func_name_constant;
-				CCodeFunctionCall cinst, cspec;
-
-				func_name = "%s_type".printf (type_param.name.down ());
-				func_name_constant = new CCodeConstant ("\"%s-type\"".printf (type_param.name.down ()));
-				enum_value = "%s_%s".printf (cl.get_lower_case_cname (null), func_name).up ();
-				cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_install_property"));
-				cinst.add_argument (ccall);
-				cinst.add_argument (new CCodeConstant (enum_value));
-				cspec = new CCodeFunctionCall (new CCodeIdentifier ("g_param_spec_gtype"));
-				cspec.add_argument (func_name_constant);
-				cspec.add_argument (new CCodeConstant ("\"type\""));
-				cspec.add_argument (new CCodeConstant ("\"type\""));
-				cspec.add_argument (new CCodeIdentifier ("G_TYPE_NONE"));
-				cspec.add_argument (new CCodeConstant ("G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY"));
-				cinst.add_argument (cspec);
-				init_block.add_statement (new CCodeExpressionStatement (cinst));
-				prop_enum.add_value (new CCodeEnumValue (enum_value));
-
-
-				func_name = "%s_dup_func".printf (type_param.name.down ());
-				func_name_constant = new CCodeConstant ("\"%s-dup-func\"".printf (type_param.name.down ()));
-				enum_value = "%s_%s".printf (cl.get_lower_case_cname (null), func_name).up ();
-				cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_install_property"));
-				cinst.add_argument (ccall);
-				cinst.add_argument (new CCodeConstant (enum_value));
-				cspec = new CCodeFunctionCall (new CCodeIdentifier ("g_param_spec_pointer"));
-				cspec.add_argument (func_name_constant);
-				cspec.add_argument (new CCodeConstant ("\"dup func\""));
-				cspec.add_argument (new CCodeConstant ("\"dup func\""));
-				cspec.add_argument (new CCodeConstant ("G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY"));
-				cinst.add_argument (cspec);
-				init_block.add_statement (new CCodeExpressionStatement (cinst));
-				prop_enum.add_value (new CCodeEnumValue (enum_value));
-
-
-				func_name = "%s_destroy_func".printf (type_param.name.down ());
-				func_name_constant = new CCodeConstant ("\"%s-destroy-func\"".printf (type_param.name.down ()));
-				enum_value = "%s_%s".printf (cl.get_lower_case_cname (null), func_name).up ();
-				cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_install_property"));
-				cinst.add_argument (ccall);
-				cinst.add_argument (new CCodeConstant (enum_value));
-				cspec = new CCodeFunctionCall (new CCodeIdentifier ("g_param_spec_pointer"));
-				cspec.add_argument (func_name_constant);
-				cspec.add_argument (new CCodeConstant ("\"destroy func\""));
-				cspec.add_argument (new CCodeConstant ("\"destroy func\""));
-				cspec.add_argument (new CCodeConstant ("G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY"));
-				cinst.add_argument (cspec);
-				init_block.add_statement (new CCodeExpressionStatement (cinst));
-				prop_enum.add_value (new CCodeEnumValue (enum_value));
-			}
+		/* create type, dup_func, and destroy_func properties for generic types */
+		foreach (TypeParameter type_param in cl.get_type_parameters ()) {
+			string func_name, enum_value;
+			CCodeConstant func_name_constant;
+			CCodeFunctionCall cinst, cspec;
 
-			/* create properties */
-			var props = cl.get_properties ();
-			foreach (Property prop in props) {
-				if (prop.access == SymbolAccessibility.PRIVATE) {
-					// don't register private properties
-					continue;
-				}
-
-				var st = prop.property_type.data_type as Struct;
-				if (st != null && !st.has_type_id) {
-					continue;
-				}
-
-				if (prop.overrides || prop.base_interface_property != null) {
-					var cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_override_property"));
-					cinst.add_argument (ccall);
-					cinst.add_argument (new CCodeConstant (prop.get_upper_case_cname ()));
-					cinst.add_argument (prop.get_canonical_cconstant ());
-				
-					init_block.add_statement (new CCodeExpressionStatement (cinst));
-				} else {
-					var cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_install_property"));
-					cinst.add_argument (ccall);
-					cinst.add_argument (new CCodeConstant (prop.get_upper_case_cname ()));
-					cinst.add_argument (head.get_param_spec (prop));
-				
-					init_block.add_statement (new CCodeExpressionStatement (cinst));
-				}
-			}
-		}
+			func_name = "%s_type".printf (type_param.name.down ());
+			func_name_constant = new CCodeConstant ("\"%s-type\"".printf (type_param.name.down ()));
+			enum_value = "%s_%s".printf (cl.get_lower_case_cname (null), func_name).up ();
+			cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_install_property"));
+			cinst.add_argument (ccall);
+			cinst.add_argument (new CCodeConstant (enum_value));
+			cspec = new CCodeFunctionCall (new CCodeIdentifier ("g_param_spec_gtype"));
+			cspec.add_argument (func_name_constant);
+			cspec.add_argument (new CCodeConstant ("\"type\""));
+			cspec.add_argument (new CCodeConstant ("\"type\""));
+			cspec.add_argument (new CCodeIdentifier ("G_TYPE_NONE"));
+			cspec.add_argument (new CCodeConstant ("G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY"));
+			cinst.add_argument (cspec);
+			init_block.add_statement (new CCodeExpressionStatement (cinst));
+			prop_enum.add_value (new CCodeEnumValue (enum_value));
 
-		if (!cl.is_compact) {
-			/* create signals */
-			foreach (Signal sig in cl.get_signals ()) {
-				init_block.add_statement (new CCodeExpressionStatement (head.get_signal_creation (sig, cl)));
-			}
-		}
 
-		init_block.add_statement (head.register_dbus_info (cl));
-		init_block.add_statement (class_init_fragment);
+			func_name = "%s_dup_func".printf (type_param.name.down ());
+			func_name_constant = new CCodeConstant ("\"%s-dup-func\"".printf (type_param.name.down ()));
+			enum_value = "%s_%s".printf (cl.get_lower_case_cname (null), func_name).up ();
+			cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_install_property"));
+			cinst.add_argument (ccall);
+			cinst.add_argument (new CCodeConstant (enum_value));
+			cspec = new CCodeFunctionCall (new CCodeIdentifier ("g_param_spec_pointer"));
+			cspec.add_argument (func_name_constant);
+			cspec.add_argument (new CCodeConstant ("\"dup func\""));
+			cspec.add_argument (new CCodeConstant ("\"dup func\""));
+			cspec.add_argument (new CCodeConstant ("G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY"));
+			cinst.add_argument (cspec);
+			init_block.add_statement (new CCodeExpressionStatement (cinst));
+			prop_enum.add_value (new CCodeEnumValue (enum_value));
 
-		source_type_member_definition.append (class_init);
-	}
-	
-	private void add_interface_init_function (Class cl, Interface iface) {
-		var iface_init = new CCodeFunction ("%s_%s_interface_init".printf (cl.get_lower_case_cname (null), iface.get_lower_case_cname (null)), "void");
-		iface_init.add_parameter (new CCodeFormalParameter ("iface", "%s *".printf (iface.get_type_cname ())));
-		iface_init.modifiers = CCodeModifiers.STATIC;
-		
-		var init_block = new CCodeBlock ();
-		iface_init.block = init_block;
-		
-		CCodeFunctionCall ccall;
-		
-		/* save pointer to parent vtable */
-		string parent_iface_var = "%s_%s_parent_iface".printf (cl.get_lower_case_cname (null), iface.get_lower_case_cname (null));
-		var parent_decl = new CCodeDeclaration (iface.get_type_cname () + "*");
-		var parent_var_decl = new CCodeVariableDeclarator (parent_iface_var);
-		parent_var_decl.initializer = new CCodeConstant ("NULL");
-		parent_decl.add_declarator (parent_var_decl);
-		parent_decl.modifiers = CCodeModifiers.STATIC;
-		source_declarations.add_type_member_declaration (parent_decl);
-		ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_interface_peek_parent"));
-		ccall.add_argument (new CCodeIdentifier ("iface"));
-		var parent_assignment = new CCodeAssignment (new CCodeIdentifier (parent_iface_var), ccall);
-		init_block.add_statement (new CCodeExpressionStatement (parent_assignment));
-
-		foreach (Method m in cl.get_methods ()) {
-			if (m.base_interface_method == null) {
-				continue;
-			}
 
-			var base_type = m.base_interface_method.parent_symbol;
-			if (base_type != iface) {
+			func_name = "%s_destroy_func".printf (type_param.name.down ());
+			func_name_constant = new CCodeConstant ("\"%s-destroy-func\"".printf (type_param.name.down ()));
+			enum_value = "%s_%s".printf (cl.get_lower_case_cname (null), func_name).up ();
+			cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_install_property"));
+			cinst.add_argument (ccall);
+			cinst.add_argument (new CCodeConstant (enum_value));
+			cspec = new CCodeFunctionCall (new CCodeIdentifier ("g_param_spec_pointer"));
+			cspec.add_argument (func_name_constant);
+			cspec.add_argument (new CCodeConstant ("\"destroy func\""));
+			cspec.add_argument (new CCodeConstant ("\"destroy func\""));
+			cspec.add_argument (new CCodeConstant ("G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY"));
+			cinst.add_argument (cspec);
+			init_block.add_statement (new CCodeExpressionStatement (cinst));
+			prop_enum.add_value (new CCodeEnumValue (enum_value));
+		}
+
+		/* create properties */
+		var props = cl.get_properties ();
+		foreach (Property prop in props) {
+			if (prop.access == SymbolAccessibility.PRIVATE) {
+				// don't register private properties
 				continue;
 			}
-			
-			var ciface = new CCodeIdentifier ("iface");
-			string cname = m.get_real_cname ();
-			if (m.is_abstract || m.is_virtual) {
-				// FIXME results in C compiler warning
-				cname = m.get_cname ();
-			}
-			init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ciface, m.base_interface_method.vfunc_name), new CCodeIdentifier (cname))));
-		}
-
-		// connect inherited implementations
-		foreach (Method m in iface.get_methods ()) {
-			if (m.is_abstract) {
-				Method cl_method = null;
-				var base_class = cl;
-				while (base_class != null && cl_method == null) {
-					cl_method = base_class.scope.lookup (m.name) as Method;
-					base_class = base_class.base_class;
-				}
-				if (base_class != null && cl_method.parent_symbol != cl) {
-					// method inherited from base class
-
-					var base_method = cl_method;
-					if (cl_method.base_method != null) {
-						base_method = cl_method.base_method;
-					} else if (cl_method.base_interface_method != null) {
-						base_method = cl_method.base_interface_method;
-					}
-
-					var ciface = new CCodeIdentifier ("iface");
-					init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ciface, m.vfunc_name), new CCodeIdentifier (base_method.get_cname ()))));
-				}
-			}
-		}
 
-		foreach (Property prop in cl.get_properties ()) {
-			if (prop.base_interface_property == null) {
+			var st = prop.property_type.data_type as Struct;
+			if (st != null && !st.has_type_id) {
 				continue;
 			}
 
-			var base_type = prop.base_interface_property.parent_symbol;
-			if (base_type != iface) {
-				continue;
-			}
+			if (prop.overrides || prop.base_interface_property != null) {
+				var cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_override_property"));
+				cinst.add_argument (ccall);
+				cinst.add_argument (new CCodeConstant (prop.get_upper_case_cname ()));
+				cinst.add_argument (prop.get_canonical_cconstant ());
 			
-			var ciface = new CCodeIdentifier ("iface");
-
-			if (prop.get_accessor != null) {
-				string cname = "%s_real_get_%s".printf (cl.get_lower_case_cname (null), prop.name);
-				if (prop.is_abstract || prop.is_virtual) {
-					cname = "%s_get_%s".printf (cl.get_lower_case_cname (null), prop.name);
-				}
-				init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ciface, "get_%s".printf (prop.name)), new CCodeIdentifier (cname))));
-			}
-			if (prop.set_accessor != null) {
-				string cname = "%s_real_set_%s".printf (cl.get_lower_case_cname (null), prop.name);
-				if (prop.is_abstract || prop.is_virtual) {
-					cname = "%s_set_%s".printf (cl.get_lower_case_cname (null), prop.name);
-				}
-				init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ciface, "set_%s".printf (prop.name)), new CCodeIdentifier (cname))));
-			}
-		}
-
-		foreach (Property prop in iface.get_properties ()) {
-			if (!prop.is_abstract) {
-				continue;
-			}
-
-			Property cl_prop = null;
-			var base_class = cl;
-			while (base_class != null && cl_prop == null) {
-				cl_prop = base_class.scope.lookup (prop.name) as Property;
-				base_class = base_class.base_class;
-			}
-			if (base_class != null && cl_prop.parent_symbol != cl) {
-				// property inherited from base class
-
-				var base_property = cl_prop;
-				if (cl_prop.base_property != null) {
-					base_property = cl_prop.base_property;
-				} else if (cl_prop.base_interface_property != null) {
-					base_property = cl_prop.base_interface_property;
-				}
-
-				var ciface = new CCodeIdentifier ("iface");
-
-				if (base_property.get_accessor != null) {
-					string cname = base_property.get_accessor.get_cname ();
-					init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ciface, "get_%s".printf (prop.name)), new CCodeIdentifier (cname))));
-				}
-				if (base_property.set_accessor != null) {
-					string cname = base_property.set_accessor.get_cname ();
-					init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ciface, "set_%s".printf (prop.name)), new CCodeIdentifier (cname))));
-				}
+				init_block.add_statement (new CCodeExpressionStatement (cinst));
+			} else {
+				var cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_install_property"));
+				cinst.add_argument (ccall);
+				cinst.add_argument (new CCodeConstant (prop.get_upper_case_cname ()));
+				cinst.add_argument (head.get_param_spec (prop));
+			
+				init_block.add_statement (new CCodeExpressionStatement (cinst));
 			}
 		}
-
-		source_type_member_definition.append (iface_init);
-	}
-	
-	private void add_instance_init_function (Class cl) {
-		var instance_init = new CCodeFunction ("%s_instance_init".printf (cl.get_lower_case_cname (null)), "void");
-		instance_init.add_parameter (new CCodeFormalParameter ("self", "%s *".printf (cl.get_cname ())));
-		instance_init.modifiers = CCodeModifiers.STATIC;
-		
-		if (cl.is_compact) {
-			// Add declaration, since the instance_init function is explicitly called
-			// by the creation methods
-			source_declarations.add_type_member_declaration (instance_init.copy ());
-		}
-
-		var init_block = new CCodeBlock ();
-		instance_init.block = init_block;
-		
-		if (!cl.is_compact && (cl.has_private_fields || cl.get_type_parameters ().size > 0)) {
-			var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (cl.get_upper_case_cname (null))));
-			ccall.add_argument (new CCodeIdentifier ("self"));
-			init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), ccall)));
-		}
-		
-		init_block.add_statement (instance_init_fragment);
-
-		source_type_member_definition.append (instance_init);
-	}
-
-	private void add_class_finalize_function (Class cl) {
-		var function = new CCodeFunction ("%s_class_finalize".printf (cl.get_lower_case_cname (null)), "void");
-		function.modifiers = CCodeModifiers.STATIC;
-
-		function.add_parameter (new CCodeFormalParameter ("klass", cl.get_cname () + "Class *"));
-		source_declarations.add_type_member_declaration (function.copy ());
-		
-		var cblock = new CCodeBlock ();
-
-		if (cl.class_destructor != null) {
-			cblock.add_statement (cl.class_destructor.ccodenode);
-		}
-
-		cblock.add_statement (class_finalize_fragment);
-
-		function.block = cblock;
-		source_type_member_definition.append (function);
-	}
-
-	private void add_base_finalize_function (Class cl) {
-		var function = new CCodeFunction ("%s_base_finalize".printf (cl.get_lower_case_cname (null)), "void");
-		function.modifiers = CCodeModifiers.STATIC;
-
-		function.add_parameter (new CCodeFormalParameter ("klass", cl.get_cname () + "Class *"));
-		source_declarations.add_type_member_declaration (function.copy ());
-		
-		var cblock = new CCodeBlock ();
-
-		if (cl.class_destructor != null) {
-			cblock.add_statement (cl.class_destructor.ccodenode);
-		}
-
-		cblock.add_statement (base_finalize_fragment);
-
-		function.block = cblock;
-		source_type_member_definition.append (function);
-	}
-
-	private void add_finalize_function (Class cl) {
-		var function = new CCodeFunction ("%s_finalize".printf (cl.get_lower_case_cname (null)), "void");
-		function.modifiers = CCodeModifiers.STATIC;
-
-		var fundamental_class = cl;
-		while (fundamental_class.base_class != null) {
-			fundamental_class = fundamental_class.base_class;
-		}
-
-		function.add_parameter (new CCodeFormalParameter ("obj", fundamental_class.get_cname () + "*"));
-
-		source_declarations.add_type_member_declaration (function.copy ());
-
-
-		var cblock = new CCodeBlock ();
-
-		CCodeFunctionCall ccall = new InstanceCast (new CCodeIdentifier ("obj"), cl);
-
-		var cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
-		cdecl.add_declarator (new CCodeVariableDeclarator ("self", ccall));
-		
-		cblock.add_statement (cdecl);
-
-		if (cl.destructor != null) {
-			cblock.add_statement (cl.destructor.ccodenode);
-		}
-
-		cblock.add_statement (instance_finalize_fragment);
-
-		// chain up to finalize function of the base class
-		if (cl.base_class != null) {
-			var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (fundamental_class.get_upper_case_cname ())));
-			ccast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (cl.get_lower_case_cname (null))));
-			ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (ccast, "finalize"));
-			ccall.add_argument (new CCodeIdentifier ("obj"));
-			cblock.add_statement (new CCodeExpressionStatement (ccall));
-		}
-
-
-		function.block = cblock;
-
-		source_type_member_definition.append (function);
 	}
 
 	private bool class_has_readable_properties (Class cl) {
@@ -1614,6 +257,8 @@ internal class Vala.GObjectModule : GTypeModule {
 
 		block.add_statement (cswitch);
 
+		source_declarations.add_type_member_declaration (get_prop.copy ());
+
 		get_prop.block = block;
 		
 		source_type_member_definition.append (get_prop);
@@ -1716,6 +361,8 @@ internal class Vala.GObjectModule : GTypeModule {
 			cswitch.add_statement (new CCodeBreakStatement ());
 		}
 
+		source_declarations.add_type_member_declaration (set_prop.copy ());
+
 		set_prop.block = block;
 		
 		source_type_member_definition.append (set_prop);
@@ -1730,183 +377,6 @@ internal class Vala.GObjectModule : GTypeModule {
 		return new CCodeExpressionStatement (cwarn);
 	}
 
-	public override CCodeFunctionCall get_param_spec (Property prop) {
-		var cspec = new CCodeFunctionCall ();
-		cspec.add_argument (prop.get_canonical_cconstant ());
-		cspec.add_argument (new CCodeConstant ("\"%s\"".printf (prop.nick)));
-		cspec.add_argument (new CCodeConstant ("\"%s\"".printf (prop.blurb)));
-
-
-		if ((prop.property_type.data_type is Class && !(((Class) prop.property_type.data_type).is_compact)) || prop.property_type.data_type is Interface) {
-			string param_spec_name = prop.property_type.data_type.get_param_spec_function ();
-			if (param_spec_name == null) {
-				cspec.call = new CCodeIdentifier ("g_param_spec_pointer");
-			} else {
-				cspec.call = new CCodeIdentifier (param_spec_name);
-				cspec.add_argument (new CCodeIdentifier (prop.property_type.data_type.get_type_id ()));
-			}
-		} else if (prop.property_type.data_type == string_type.data_type) {
-			cspec.call = new CCodeIdentifier ("g_param_spec_string");
-			cspec.add_argument (new CCodeConstant ("NULL"));
-		} else if (prop.property_type.data_type is Enum) {
-			var e = prop.property_type.data_type as Enum;
-			if (e.has_type_id) {
-				if (e.is_flags) {
-					cspec.call = new CCodeIdentifier ("g_param_spec_flags");
-				} else {
-					cspec.call = new CCodeIdentifier ("g_param_spec_enum");
-				}
-				cspec.add_argument (new CCodeIdentifier (e.get_type_id ()));
-			} else {
-				if (e.is_flags) {
-					cspec.call = new CCodeIdentifier ("g_param_spec_uint");
-					cspec.add_argument (new CCodeConstant ("0"));
-					cspec.add_argument (new CCodeConstant ("G_MAXUINT"));
-				} else {
-					cspec.call = new CCodeIdentifier ("g_param_spec_int");
-					cspec.add_argument (new CCodeConstant ("G_MININT"));
-					cspec.add_argument (new CCodeConstant ("G_MAXINT"));
-				}
-			}
-
-			if (prop.default_expression != null) {
-				cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
-			} else {
-				cspec.add_argument (new CCodeConstant (prop.property_type.data_type.get_default_value ()));
-			}
-		} else if (prop.property_type.data_type is Struct) {
-			var st = (Struct) prop.property_type.data_type;
-			if (st.get_type_id () == "G_TYPE_INT") {
-				cspec.call = new CCodeIdentifier ("g_param_spec_int");
-				cspec.add_argument (new CCodeConstant ("G_MININT"));
-				cspec.add_argument (new CCodeConstant ("G_MAXINT"));
-				if (prop.default_expression != null) {
-					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
-				} else {
-					cspec.add_argument (new CCodeConstant ("0"));
-				}
-			} else if (st.get_type_id () == "G_TYPE_UINT") {
-				cspec.call = new CCodeIdentifier ("g_param_spec_uint");
-				cspec.add_argument (new CCodeConstant ("0"));
-				cspec.add_argument (new CCodeConstant ("G_MAXUINT"));
-				if (prop.default_expression != null) {
-					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
-				} else {
-					cspec.add_argument (new CCodeConstant ("0U"));
-				}
-			} else if (st.get_type_id () == "G_TYPE_INT64") {
-				cspec.call = new CCodeIdentifier ("g_param_spec_int64");
-				cspec.add_argument (new CCodeConstant ("G_MININT64"));
-				cspec.add_argument (new CCodeConstant ("G_MAXINT64"));
-				if (prop.default_expression != null) {
-					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
-				} else {
-					cspec.add_argument (new CCodeConstant ("0"));
-				}
-			} else if (st.get_type_id () == "G_TYPE_UINT64") {
-				cspec.call = new CCodeIdentifier ("g_param_spec_uint64");
-				cspec.add_argument (new CCodeConstant ("0"));
-				cspec.add_argument (new CCodeConstant ("G_MAXUINT64"));
-				if (prop.default_expression != null) {
-					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
-				} else {
-					cspec.add_argument (new CCodeConstant ("0U"));
-				}
-			} else if (st.get_type_id () == "G_TYPE_LONG") {
-				cspec.call = new CCodeIdentifier ("g_param_spec_long");
-				cspec.add_argument (new CCodeConstant ("G_MINLONG"));
-				cspec.add_argument (new CCodeConstant ("G_MAXLONG"));
-				if (prop.default_expression != null) {
-					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
-				} else {
-					cspec.add_argument (new CCodeConstant ("0L"));
-				}
-			} else if (st.get_type_id () == "G_TYPE_ULONG") {
-				cspec.call = new CCodeIdentifier ("g_param_spec_ulong");
-				cspec.add_argument (new CCodeConstant ("0"));
-				cspec.add_argument (new CCodeConstant ("G_MAXULONG"));
-				if (prop.default_expression != null) {
-					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
-				} else {
-					cspec.add_argument (new CCodeConstant ("0UL"));
-				}
-			} else if (st.get_type_id () == "G_TYPE_BOOLEAN") {
-				cspec.call = new CCodeIdentifier ("g_param_spec_boolean");
-				if (prop.default_expression != null) {
-					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
-				} else {
-					cspec.add_argument (new CCodeConstant ("FALSE"));
-				}
-			} else if (st.get_type_id () == "G_TYPE_CHAR") {
-				cspec.call = new CCodeIdentifier ("g_param_spec_char");
-				cspec.add_argument (new CCodeConstant ("G_MININT8"));
-				cspec.add_argument (new CCodeConstant ("G_MAXINT8"));
-				if (prop.default_expression != null) {
-					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
-				} else {
-					cspec.add_argument (new CCodeConstant ("0"));
-				}
-			} else if (st.get_type_id () == "G_TYPE_UCHAR") {
-				cspec.call = new CCodeIdentifier ("g_param_spec_uchar");
-				cspec.add_argument (new CCodeConstant ("0"));
-				cspec.add_argument (new CCodeConstant ("G_MAXUINT8"));
-				if (prop.default_expression != null) {
-					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
-				} else {
-					cspec.add_argument (new CCodeConstant ("0"));
-				}
-			}else if (st.get_type_id () == "G_TYPE_FLOAT") {
-				cspec.call = new CCodeIdentifier ("g_param_spec_float");
-				cspec.add_argument (new CCodeConstant ("-G_MAXFLOAT"));
-				cspec.add_argument (new CCodeConstant ("G_MAXFLOAT"));
-				if (prop.default_expression != null) {
-					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
-				} else {
-					cspec.add_argument (new CCodeConstant ("0.0F"));
-				}
-			} else if (st.get_type_id () == "G_TYPE_DOUBLE") {
-				cspec.call = new CCodeIdentifier ("g_param_spec_double");
-				cspec.add_argument (new CCodeConstant ("-G_MAXDOUBLE"));
-				cspec.add_argument (new CCodeConstant ("G_MAXDOUBLE"));
-				if (prop.default_expression != null) {
-					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
-				} else {
-					cspec.add_argument (new CCodeConstant ("0.0"));
-				}
-			} else if (st.get_type_id () == "G_TYPE_GTYPE") {
-				cspec.call = new CCodeIdentifier ("g_param_spec_gtype");
-				if (prop.default_expression != null) {
-					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
-				} else {
-					cspec.add_argument (new CCodeConstant ("G_TYPE_NONE"));
-				}
-			} else {
-				cspec.call = new CCodeIdentifier ("g_param_spec_boxed");
-				cspec.add_argument (new CCodeIdentifier (st.get_type_id ()));
-			}
-		} else {
-			cspec.call = new CCodeIdentifier ("g_param_spec_pointer");
-		}
-		
-		var pflags = "G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB";
-		if (prop.get_accessor != null) {
-			pflags = "%s%s".printf (pflags, " | G_PARAM_READABLE");
-		}
-		if (prop.set_accessor != null) {
-			pflags = "%s%s".printf (pflags, " | G_PARAM_WRITABLE");
-			if (prop.set_accessor.construction) {
-				if (prop.set_accessor.writable) {
-					pflags = "%s%s".printf (pflags, " | G_PARAM_CONSTRUCT");
-				} else {
-					pflags = "%s%s".printf (pflags, " | G_PARAM_CONSTRUCT_ONLY");
-				}
-			}
-		}
-		cspec.add_argument (new CCodeConstant (pflags));
-
-		return cspec;
-	}
-
 	public override CCodeExpression get_construct_property_assignment (CCodeConstant canonical_cconstant, DataType property_type, CCodeExpression value) {
 		// this property is used as a construction parameter
 		var cpointer = new CCodeIdentifier ("__params_it");
diff --git a/gobject/valagtypemodule.vala b/gobject/valagtypemodule.vala
index 5b0aad5..5f748da 100644
--- a/gobject/valagtypemodule.vala
+++ b/gobject/valagtypemodule.vala
@@ -29,6 +29,1554 @@ internal class Vala.GTypeModule : GErrorModule {
 		base (codegen, next);
 	}
 
+	public override void generate_parameter (FormalParameter param, CCodeDeclarationSpace decl_space, Map<int,CCodeFormalParameter> cparam_map, Map<int,CCodeExpression>? carg_map) {
+		if (!(param.parameter_type is ObjectType)) {
+			base.generate_parameter (param, decl_space, cparam_map, carg_map);
+			return;
+		}
+
+		generate_type_declaration (param.parameter_type, decl_space);
+
+		string ctypename = param.parameter_type.get_cname ();
+
+		if (param.direction != ParameterDirection.IN) {
+			ctypename += "*";
+		}
+
+		param.ccodenode = new CCodeFormalParameter (param.name, ctypename);
+
+		cparam_map.set (get_param_pos (param.cparameter_position), (CCodeFormalParameter) param.ccodenode);
+		if (carg_map != null) {
+			carg_map.set (get_param_pos (param.cparameter_position), new CCodeIdentifier (param.name));
+		}
+	}
+
+	public override void generate_class_declaration (Class cl, CCodeDeclarationSpace decl_space) {
+		if (decl_space.add_symbol_declaration (cl, cl.get_cname ())) {
+			return;
+		}
+
+		if (cl.base_class != null) {
+			// base class declaration
+			// necessary for ref and unref function declarations
+			generate_class_declaration (cl.base_class, decl_space);
+		}
+
+		bool is_gtypeinstance = !cl.is_compact;
+		bool is_fundamental = is_gtypeinstance && cl.base_class == null;
+
+		if (is_gtypeinstance) {
+			decl_space.add_type_declaration (new CCodeNewline ());
+			var macro = "(%s_get_type ())".printf (cl.get_lower_case_cname (null));
+			decl_space.add_type_declaration (new CCodeMacroReplacement (cl.get_type_id (), macro));
+
+			macro = "(G_TYPE_CHECK_INSTANCE_CAST ((obj), %s, %s))".printf (cl.get_type_id (), cl.get_cname ());
+			decl_space.add_type_declaration (new CCodeMacroReplacement ("%s(obj)".printf (cl.get_upper_case_cname (null)), macro));
+
+			macro = "(G_TYPE_CHECK_CLASS_CAST ((klass), %s, %sClass))".printf (cl.get_type_id (), cl.get_cname ());
+			decl_space.add_type_declaration (new CCodeMacroReplacement ("%s_CLASS(klass)".printf (cl.get_upper_case_cname (null)), macro));
+
+			macro = "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), %s))".printf (cl.get_type_id ());
+			decl_space.add_type_declaration (new CCodeMacroReplacement ("%s(obj)".printf (get_type_check_function (cl)), macro));
+
+			macro = "(G_TYPE_CHECK_CLASS_TYPE ((klass), %s))".printf (cl.get_type_id ());
+			decl_space.add_type_declaration (new CCodeMacroReplacement ("%s_CLASS(klass)".printf (get_type_check_function (cl)), macro));
+
+			macro = "(G_TYPE_INSTANCE_GET_CLASS ((obj), %s, %sClass))".printf (cl.get_type_id (), cl.get_cname ());
+			decl_space.add_type_declaration (new CCodeMacroReplacement ("%s_GET_CLASS(obj)".printf (cl.get_upper_case_cname (null)), macro));
+			decl_space.add_type_declaration (new CCodeNewline ());
+		}
+
+		decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (cl.get_cname ()), new CCodeVariableDeclarator (cl.get_cname ())));
+
+		if (is_fundamental) {
+			var ref_fun = new CCodeFunction (cl.get_lower_case_cprefix () + "ref", "gpointer");
+			var unref_fun = new CCodeFunction (cl.get_lower_case_cprefix () + "unref", "void");
+			if (cl.access == SymbolAccessibility.PRIVATE) {
+				ref_fun.modifiers = CCodeModifiers.STATIC;
+				unref_fun.modifiers = CCodeModifiers.STATIC;
+			}
+
+			ref_fun.add_parameter (new CCodeFormalParameter ("instance", "gpointer"));
+			unref_fun.add_parameter (new CCodeFormalParameter ("instance", "gpointer"));
+
+			decl_space.add_type_member_declaration (ref_fun.copy ());
+			decl_space.add_type_member_declaration (unref_fun.copy ());
+
+			// GParamSpec and GValue functions
+			var function_name = cl.get_lower_case_cname ("param_spec_");
+
+			var function = new CCodeFunction (function_name, "GParamSpec*");
+			function.add_parameter (new CCodeFormalParameter ("name", "const gchar*"));
+			function.add_parameter (new CCodeFormalParameter ("nick", "const gchar*"));
+			function.add_parameter (new CCodeFormalParameter ("blurb", "const gchar*"));
+			function.add_parameter (new CCodeFormalParameter ("object_type", "GType"));
+			function.add_parameter (new CCodeFormalParameter ("flags", "GParamFlags"));
+
+			cl.set_param_spec_function (function_name);
+
+			if (cl.access == SymbolAccessibility.PRIVATE) {
+				function.modifiers = CCodeModifiers.STATIC;
+			}
+
+			decl_space.add_type_member_declaration (function);
+
+			function = new CCodeFunction (cl.get_set_value_function (), "void");
+			function.add_parameter (new CCodeFormalParameter ("value", "GValue*"));
+			function.add_parameter (new CCodeFormalParameter ("v_object", "gpointer"));
+
+			if (cl.access == SymbolAccessibility.PRIVATE) {
+				function.modifiers = CCodeModifiers.STATIC;
+			}
+
+			decl_space.add_type_member_declaration (function);
+
+			function = new CCodeFunction (cl.get_get_value_function (), "gpointer");
+			function.add_parameter (new CCodeFormalParameter ("value", "const GValue*"));
+
+			if (cl.access == SymbolAccessibility.PRIVATE) {
+				function.modifiers = CCodeModifiers.STATIC;
+			}
+
+			decl_space.add_type_member_declaration (function);
+		}
+
+		if (is_gtypeinstance) {
+			decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%sClass".printf (cl.get_cname ()), new CCodeVariableDeclarator ("%sClass".printf (cl.get_cname ()))));
+
+			var type_fun = new ClassRegisterFunction (cl, context);
+			type_fun.init_from_type (in_plugin);
+			decl_space.add_type_member_declaration (type_fun.get_declaration ());
+		}
+	}
+
+	public override void generate_class_struct_declaration (Class cl, CCodeDeclarationSpace decl_space) {
+		if (decl_space.add_symbol_declaration (cl, "struct _" + cl.get_cname ())) {
+			return;
+		}
+
+		if (cl.base_class != null) {
+			// base class declaration
+			generate_class_struct_declaration (cl.base_class, decl_space);
+		}
+		foreach (DataType base_type in cl.get_base_types ()) {
+			var iface = base_type.data_type as Interface;
+			if (iface != null) {
+				generate_interface_declaration (iface, decl_space);
+			}
+		}
+
+		generate_class_declaration (cl, decl_space);
+
+		bool is_gtypeinstance = !cl.is_compact;
+		bool is_fundamental = is_gtypeinstance && cl.base_class == null;
+
+		var instance_struct = new CCodeStruct ("_%s".printf (cl.get_cname ()));
+		var type_struct = new CCodeStruct ("_%sClass".printf (cl.get_cname ()));
+
+		if (cl.base_class != null) {
+			instance_struct.add_field (cl.base_class.get_cname (), "parent_instance");
+		} else if (is_fundamental) {
+			instance_struct.add_field ("GTypeInstance", "parent_instance");
+			instance_struct.add_field ("volatile int", "ref_count");
+		}
+
+		if (cl.is_compact && cl.base_class == null && cl.get_fields ().size == 0) {
+			// add dummy member, C doesn't allow empty structs
+			instance_struct.add_field ("int", "dummy");
+		}
+
+		if (is_gtypeinstance) {
+			decl_space.add_type_declaration (new CCodeTypeDefinition ("struct %sPrivate".printf (instance_struct.name), new CCodeVariableDeclarator ("%sPrivate".printf (cl.get_cname ()))));
+
+			instance_struct.add_field ("%sPrivate *".printf (cl.get_cname ()), "priv");
+			if (is_fundamental) {
+				type_struct.add_field ("GTypeClass", "parent_class");
+			} else {
+				type_struct.add_field ("%sClass".printf (cl.base_class.get_cname ()), "parent_class");
+			}
+
+			if (is_fundamental) {
+				type_struct.add_field ("void", "(*finalize) (%s *self)".printf (cl.get_cname ()));
+			}
+		}
+
+		foreach (Method m in cl.get_methods ()) {
+			generate_virtual_method_declaration (m, decl_space, type_struct);
+		}
+
+		foreach (Property prop in cl.get_properties ()) {
+			if (!prop.is_abstract && !prop.is_virtual) {
+				continue;
+			}
+			generate_type_declaration (prop.property_type, decl_space);
+
+			var t = (ObjectTypeSymbol) prop.parent_symbol;
+
+			bool returns_real_struct = prop.property_type.is_real_struct_type ();
+
+			var this_type = new ObjectType (t);
+			var cselfparam = new CCodeFormalParameter ("self", this_type.get_cname ());
+			CCodeFormalParameter cvalueparam;
+			if (returns_real_struct) {
+				cvalueparam = new CCodeFormalParameter ("value", prop.property_type.get_cname () + "*");
+			} else {
+				cvalueparam = new CCodeFormalParameter ("value", prop.property_type.get_cname ());
+			}
+
+			if (prop.get_accessor != null) {
+				var vdeclarator = new CCodeFunctionDeclarator ("get_%s".printf (prop.name));
+				vdeclarator.add_parameter (cselfparam);
+				string creturn_type;
+				if (returns_real_struct) {
+					vdeclarator.add_parameter (cvalueparam);
+					creturn_type = "void";
+				} else {
+					creturn_type = prop.property_type.get_cname ();
+				}
+				var vdecl = new CCodeDeclaration (creturn_type);
+				vdecl.add_declarator (vdeclarator);
+				type_struct.add_declaration (vdecl);
+			}
+			if (prop.set_accessor != null) {
+				var vdeclarator = new CCodeFunctionDeclarator ("set_%s".printf (prop.name));
+				vdeclarator.add_parameter (cselfparam);
+				vdeclarator.add_parameter (cvalueparam);
+				var vdecl = new CCodeDeclaration ("void");
+				vdecl.add_declarator (vdeclarator);
+				type_struct.add_declaration (vdecl);
+			}
+		}
+
+		foreach (Field f in cl.get_fields ()) {
+			string field_ctype = f.field_type.get_cname ();
+			if (f.is_volatile) {
+				field_ctype = "volatile " + field_ctype;
+			}
+
+			if (f.binding == MemberBinding.INSTANCE && f.access != SymbolAccessibility.PRIVATE)  {
+				generate_type_declaration (f.field_type, decl_space);
+
+				instance_struct.add_field (field_ctype, f.get_cname ());
+				if (f.field_type is ArrayType && !f.no_array_length) {
+					// create fields to store array dimensions
+					var array_type = (ArrayType) f.field_type;
+					var len_type = int_type.copy ();
+
+					for (int dim = 1; dim <= array_type.rank; dim++) {
+						instance_struct.add_field (len_type.get_cname (), head.get_array_length_cname (f.name, dim));
+					}
+
+					if (array_type.rank == 1 && f.is_internal_symbol ()) {
+						instance_struct.add_field (len_type.get_cname (), head.get_array_size_cname (f.name));
+					}
+				} else if (f.field_type is DelegateType) {
+					var delegate_type = (DelegateType) f.field_type;
+					if (delegate_type.delegate_symbol.has_target) {
+						// create field to store delegate target
+						instance_struct.add_field ("gpointer", get_delegate_target_cname (f.name));
+					}
+				}
+			} else if (f.binding == MemberBinding.CLASS && f.access != SymbolAccessibility.PRIVATE)  {
+				type_struct.add_field (field_ctype, f.get_cname ());
+			}
+		}
+
+		if (cl.source_reference.comment != null) {
+			decl_space.add_type_definition (new CCodeComment (cl.source_reference.comment));
+		}
+		decl_space.add_type_definition (instance_struct);
+
+		if (is_gtypeinstance) {
+			decl_space.add_type_definition (type_struct);
+		}
+	}
+
+	public virtual void generate_virtual_method_declaration (Method m, CCodeDeclarationSpace decl_space, CCodeStruct type_struct) {
+		if (!m.is_abstract && !m.is_virtual) {
+			return;
+		}
+
+		// add vfunc field to the type struct
+		var vdeclarator = new CCodeFunctionDeclarator (m.vfunc_name);
+		var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
+
+		generate_cparameters (m, decl_space, cparam_map, new CCodeFunction ("fake"), vdeclarator);
+
+		var vdecl = new CCodeDeclaration (m.return_type.get_cname ());
+		vdecl.add_declarator (vdeclarator);
+		type_struct.add_declaration (vdecl);
+	}
+
+	void generate_class_private_declaration (Class cl, CCodeDeclarationSpace decl_space) {
+		if (decl_space.add_symbol_declaration (cl, cl.get_cname () + "Private")) {
+			return;
+		}
+
+		bool is_gtypeinstance = !cl.is_compact;
+
+		var instance_priv_struct = new CCodeStruct ("_%sPrivate".printf (cl.get_cname ()));
+		var type_priv_struct = new CCodeStruct ("_%sClassPrivate".printf (cl.get_cname ()));
+
+		if (is_gtypeinstance) {
+			/* create type, dup_func, and destroy_func fields for generic types */
+			foreach (TypeParameter type_param in cl.get_type_parameters ()) {
+				string func_name;
+
+				func_name = "%s_type".printf (type_param.name.down ());
+				instance_priv_struct.add_field ("GType", func_name);
+
+				func_name = "%s_dup_func".printf (type_param.name.down ());
+				instance_priv_struct.add_field ("GBoxedCopyFunc", func_name);
+
+				func_name = "%s_destroy_func".printf (type_param.name.down ());
+				instance_priv_struct.add_field ("GDestroyNotify", func_name);
+			}
+		}
+
+		foreach (Field f in cl.get_fields ()) {
+			string field_ctype = f.field_type.get_cname ();
+			if (f.is_volatile) {
+				field_ctype = "volatile " + field_ctype;
+			}
+
+			if (f.binding == MemberBinding.INSTANCE && f.access == SymbolAccessibility.PRIVATE)  {
+				generate_type_declaration (f.field_type, decl_space);
+
+				instance_priv_struct.add_field (field_ctype, f.get_cname ());
+				if (f.field_type is ArrayType && !f.no_array_length) {
+					// create fields to store array dimensions
+					var array_type = (ArrayType) f.field_type;
+					var len_type = int_type.copy ();
+
+					for (int dim = 1; dim <= array_type.rank; dim++) {
+						instance_priv_struct.add_field (len_type.get_cname (), head.get_array_length_cname (f.name, dim));
+					}
+
+					if (array_type.rank == 1 && f.is_internal_symbol ()) {
+						instance_priv_struct.add_field (len_type.get_cname (), head.get_array_size_cname (f.name));
+					}
+				} else if (f.field_type is DelegateType) {
+					var delegate_type = (DelegateType) f.field_type;
+					if (delegate_type.delegate_symbol.has_target) {
+						// create field to store delegate target
+						instance_priv_struct.add_field ("gpointer", get_delegate_target_cname (f.name));
+					}
+				}
+
+				if (f.get_lock_used ()) {
+					// add field for mutex
+					instance_priv_struct.add_field (mutex_type.get_cname (), get_symbol_lock_name (f));
+				}
+			} else if (f.binding == MemberBinding.CLASS && f.access == SymbolAccessibility.PRIVATE)  {
+				type_priv_struct.add_field (field_ctype, f.get_cname ());
+			}
+		}
+
+		if (is_gtypeinstance) {
+			if (cl.has_class_private_fields) {
+				decl_space.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (type_priv_struct.name), new CCodeVariableDeclarator ("%sClassPrivate".printf (cl.get_cname ()))));
+				var cdecl = new CCodeDeclaration ("GQuark");
+				cdecl.add_declarator (new CCodeVariableDeclarator ("_vala_%s_class_private_quark".printf (cl.get_lower_case_cname ()), new CCodeConstant ("0")));
+				cdecl.modifiers = CCodeModifiers.STATIC;
+				decl_space.add_type_declaration (cdecl);
+			}
+
+			/* only add the *Private struct if it is not empty, i.e. we actually have private data */
+			if (cl.has_private_fields || cl.get_type_parameters ().size > 0) {
+				decl_space.add_type_definition (instance_priv_struct);
+				var macro = "(G_TYPE_INSTANCE_GET_PRIVATE ((o), %s, %sPrivate))".printf (cl.get_type_id (), cl.get_cname ());
+				decl_space.add_type_member_declaration (new CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (cl.get_upper_case_cname (null)), macro));
+			}
+
+			if (cl.has_class_private_fields) {
+				decl_space.add_type_member_declaration (type_priv_struct);
+
+				var macro = "((%sClassPrivate *) g_type_get_qdata (type, _vala_%s_class_private_quark))".printf (cl.get_cname(), cl.get_lower_case_cname ());
+				decl_space.add_type_member_declaration (new CCodeMacroReplacement ("%s_GET_CLASS_PRIVATE(type)".printf (cl.get_upper_case_cname (null)), macro));
+			}
+			decl_space.add_type_member_declaration (prop_enum);
+		} else {
+			var function = new CCodeFunction (cl.get_lower_case_cprefix () + "free", "void");
+			if (cl.access == SymbolAccessibility.PRIVATE) {
+				function.modifiers = CCodeModifiers.STATIC;
+			}
+
+			function.add_parameter (new CCodeFormalParameter ("self", cl.get_cname () + "*"));
+
+			decl_space.add_type_member_declaration (function);
+		}
+	}
+
+	public override void visit_class (Class cl) {
+		var old_symbol = current_symbol;
+		var old_type_symbol = current_type_symbol;
+		var old_class = current_class;
+		var old_param_spec_struct = param_spec_struct;
+		var old_prop_enum = prop_enum;
+		var old_class_init_fragment = class_init_fragment;
+		var old_base_init_fragment = base_init_fragment;
+		var old_class_finalize_fragment = class_finalize_fragment;
+		var old_base_finalize_fragment = base_finalize_fragment;
+		var old_instance_init_fragment = instance_init_fragment;
+		var old_instance_finalize_fragment = instance_finalize_fragment;
+		current_symbol = cl;
+		current_type_symbol = cl;
+		current_class = cl;
+
+		bool is_gtypeinstance = !cl.is_compact;
+		bool is_fundamental = is_gtypeinstance && cl.base_class == null;
+
+		if (cl.get_cname().len () < 3) {
+			cl.error = true;
+			Report.error (cl.source_reference, "Class name `%s' is too short".printf (cl.get_cname ()));
+			return;
+		}
+
+		prop_enum = new CCodeEnum ();
+		prop_enum.add_value (new CCodeEnumValue ("%s_DUMMY_PROPERTY".printf (cl.get_upper_case_cname (null))));
+		class_init_fragment = new CCodeFragment ();
+		base_init_fragment = new CCodeFragment ();
+		class_finalize_fragment = new CCodeFragment ();
+		base_finalize_fragment = new CCodeFragment ();
+		instance_init_fragment = new CCodeFragment ();
+		instance_finalize_fragment = new CCodeFragment ();
+
+
+		generate_class_struct_declaration (cl, source_declarations);
+		generate_class_private_declaration (cl, source_declarations);
+
+		if (!cl.is_internal_symbol ()) {
+			generate_class_struct_declaration (cl, header_declarations);
+		}
+		generate_class_struct_declaration (cl, internal_header_declarations);
+
+		cl.accept_children (codegen);
+
+		if (is_gtypeinstance) {
+			if (is_fundamental) {
+				param_spec_struct = new CCodeStruct ( "_%sParamSpec%s".printf(cl.parent_symbol.get_cprefix (), cl.name));
+				param_spec_struct.add_field ("GParamSpec", "parent_instance");
+				source_declarations.add_type_definition (param_spec_struct);
+
+				source_declarations.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (param_spec_struct.name), new CCodeVariableDeclarator ( "%sParamSpec%s".printf(cl.parent_symbol.get_cprefix (), cl.name))));
+
+
+				gvaluecollector_h_needed = true;
+
+				add_type_value_table_init_function (cl);
+				add_type_value_table_free_function (cl);
+				add_type_value_table_copy_function (cl);
+				add_type_value_table_peek_pointer_function (cl);
+				add_type_value_table_collect_value_function (cl);
+				add_type_value_table_lcopy_value_function (cl);
+				add_g_param_spec_type_function (cl);
+				add_g_value_get_function (cl);
+				add_g_value_set_function (cl);
+
+				var ref_count = new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "ref_count"), new CCodeConstant ("1"));
+				instance_init_fragment.append (new CCodeExpressionStatement (ref_count));
+			}
+
+
+			if (cl.class_constructor != null || cl.has_class_private_fields) {
+				add_base_init_function (cl);
+			}
+			add_class_init_function (cl);
+
+			if (cl.class_destructor != null || cl.has_class_private_fields) {
+				add_base_finalize_function (cl);
+			}
+
+			if (cl.static_destructor != null) {
+				add_class_finalize_function (cl);
+			}
+
+			foreach (DataType base_type in cl.get_base_types ()) {
+				if (base_type.data_type is Interface) {
+					add_interface_init_function (cl, (Interface) base_type.data_type);
+				}
+			}
+			
+			add_instance_init_function (cl);
+
+			if (!cl.is_compact && (cl.get_fields ().size > 0 || cl.destructor != null || cl.is_fundamental ())) {
+				add_finalize_function (cl);
+			}
+
+			var type_fun = new ClassRegisterFunction (cl, context);
+			type_fun.init_from_type (in_plugin);
+			source_type_member_definition.append (type_fun.get_definition ());
+			
+			if (in_plugin) {
+				// FIXME resolve potential dependency issues, i.e. base types have to be registered before derived types
+				var register_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_register_type".printf (cl.get_lower_case_cname (null))));
+				register_call.add_argument (new CCodeIdentifier (module_init_param_name));
+				module_init_fragment.append (new CCodeExpressionStatement (register_call));
+			}
+
+			if (is_fundamental) {
+				var ref_fun = new CCodeFunction (cl.get_lower_case_cprefix () + "ref", "gpointer");
+				var unref_fun = new CCodeFunction (cl.get_lower_case_cprefix () + "unref", "void");
+				if (cl.access == SymbolAccessibility.PRIVATE) {
+					ref_fun.modifiers = CCodeModifiers.STATIC;
+					unref_fun.modifiers = CCodeModifiers.STATIC;
+				}
+
+				ref_fun.add_parameter (new CCodeFormalParameter ("instance", "gpointer"));
+				unref_fun.add_parameter (new CCodeFormalParameter ("instance", "gpointer"));
+
+				var ref_block = new CCodeBlock ();
+				var unref_block = new CCodeBlock ();
+
+				var cdecl = new CCodeDeclaration (cl.get_cname () + "*");
+				cdecl.add_declarator (new CCodeVariableDeclarator ("self", new CCodeIdentifier ("instance")));
+				ref_block.add_statement (cdecl);
+				unref_block.add_statement (cdecl);
+
+				var ref_count = new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "ref_count");
+
+				var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_atomic_int_inc"));
+				ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ref_count));
+				ref_block.add_statement (new CCodeExpressionStatement (ccall));
+
+				ref_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("instance")));
+
+				var destroy_block = new CCodeBlock ();
+				var get_class = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS".printf (cl.get_upper_case_cname (null))));
+				get_class.add_argument (new CCodeIdentifier ("self"));
+
+				// finalize class
+				var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS".printf (cl.get_upper_case_cname (null))));
+				ccast.add_argument (new CCodeIdentifier ("self"));
+				ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (ccast, "finalize"));
+				ccall.add_argument (new CCodeIdentifier ("self"));
+				destroy_block.add_statement (new CCodeExpressionStatement (ccall));
+
+				// free type instance
+				var free = new CCodeFunctionCall (new CCodeIdentifier ("g_type_free_instance"));
+				free.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "GTypeInstance *"));
+				destroy_block.add_statement (new CCodeExpressionStatement (free));
+
+				ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_atomic_int_dec_and_test"));
+				ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ref_count));
+				unref_block.add_statement (new CCodeIfStatement (ccall, destroy_block));
+
+				ref_fun.block = ref_block;
+				unref_fun.block = unref_block;
+
+				source_type_member_definition.append (ref_fun);
+				source_type_member_definition.append (unref_fun);
+			}
+		} else {
+			add_instance_init_function (cl);
+
+			var function = new CCodeFunction (cl.get_lower_case_cprefix () + "free", "void");
+			if (cl.access == SymbolAccessibility.PRIVATE) {
+				function.modifiers = CCodeModifiers.STATIC;
+			}
+
+			function.add_parameter (new CCodeFormalParameter ("self", cl.get_cname () + "*"));
+
+			var cblock = new CCodeBlock ();
+
+			cblock.add_statement (instance_finalize_fragment);
+
+			if (cl.destructor != null) {
+				cblock.add_statement (cl.destructor.ccodenode);
+			}
+
+			var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_free"));
+			ccall.add_argument (new CCodeIdentifier (cl.get_cname ()));
+			ccall.add_argument (new CCodeIdentifier ("self"));
+			cblock.add_statement (new CCodeExpressionStatement (ccall));
+
+			function.block = cblock;
+
+			source_type_member_definition.append (function);
+		}
+
+		current_symbol = old_symbol;
+		current_type_symbol = old_type_symbol;
+		current_class = old_class;
+		param_spec_struct = old_param_spec_struct;
+		prop_enum = old_prop_enum;
+		class_init_fragment = old_class_init_fragment;
+		base_init_fragment = old_base_init_fragment;
+		class_finalize_fragment = old_class_finalize_fragment;
+		base_finalize_fragment = old_base_finalize_fragment;
+		instance_init_fragment = old_instance_init_fragment;
+		instance_finalize_fragment = old_instance_finalize_fragment;
+	}
+
+	private void add_type_value_table_init_function (Class cl) {
+		var function = new CCodeFunction ("%s_init".printf (cl.get_lower_case_cname ("value_")), "void");
+		function.add_parameter (new CCodeFormalParameter ("value", "GValue*"));
+		function.modifiers = CCodeModifiers.STATIC;
+
+		var init_block = new CCodeBlock ();
+		function.block = init_block;
+
+		init_block.add_statement(new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess(new CCodeMemberAccess.pointer (new CCodeIdentifier ("value"), "data[0]"),"v_pointer"),new CCodeConstant ("NULL"), CCodeAssignmentOperator.SIMPLE)));
+		source_type_member_definition.append (function);
+	}
+
+	private void add_type_value_table_free_function (Class cl) {
+		var function = new CCodeFunction ("%s_free_value".printf (cl.get_lower_case_cname ("value_")), "void");
+		function.add_parameter (new CCodeFormalParameter ("value", "GValue*"));
+		function.modifiers = CCodeModifiers.STATIC;
+
+		var init_block = new CCodeBlock ();
+		function.block = init_block;
+		
+		var vpointer = new CCodeMemberAccess(new CCodeMemberAccess.pointer (new CCodeIdentifier ("value"), "data[0]"),"v_pointer");
+		var ccall = new CCodeFunctionCall (new CCodeIdentifier (cl.get_lower_case_cprefix () + "unref"));
+		ccall.add_argument ( vpointer );
+
+		var ifbody = new CCodeBlock ();
+		ifbody.add_statement ( new CCodeExpressionStatement(ccall) );
+
+		init_block.add_statement(new CCodeIfStatement (vpointer, ifbody));
+		source_type_member_definition.append (function);
+	}
+
+	private void add_type_value_table_copy_function (Class cl) {
+		var function = new CCodeFunction ("%s_copy_value".printf (cl.get_lower_case_cname ("value_")), "void");
+		function.add_parameter (new CCodeFormalParameter ("src_value", "const GValue*"));
+		function.add_parameter (new CCodeFormalParameter ("dest_value", "GValue*"));
+		function.modifiers = CCodeModifiers.STATIC;
+
+		var init_block = new CCodeBlock ();
+		function.block = init_block;
+
+		var dest_vpointer = new CCodeMemberAccess (new CCodeMemberAccess.pointer (new CCodeIdentifier ("dest_value"), "data[0]"),"v_pointer");
+		var src_vpointer = new CCodeMemberAccess (new CCodeMemberAccess.pointer (new CCodeIdentifier ("src_value"), "data[0]"),"v_pointer");
+
+		var ref_ccall = new CCodeFunctionCall (new CCodeIdentifier (cl.get_lower_case_cprefix () + "ref"));
+		ref_ccall.add_argument ( src_vpointer );
+
+		var true_stmt = new CCodeBlock ();
+		true_stmt.add_statement(new CCodeExpressionStatement(new CCodeAssignment (dest_vpointer, ref_ccall, CCodeAssignmentOperator.SIMPLE)));
+
+		var false_stmt = new CCodeBlock ();
+		false_stmt.add_statement (new CCodeExpressionStatement( new CCodeAssignment (dest_vpointer, new CCodeConstant ("NULL"), CCodeAssignmentOperator.SIMPLE)));
+
+		var if_statement = new CCodeIfStatement (src_vpointer, true_stmt, false_stmt);
+		init_block.add_statement (if_statement);
+
+		source_type_member_definition.append (function);
+	}
+
+	private void add_type_value_table_peek_pointer_function (Class cl) {
+		var function = new CCodeFunction ("%s_peek_pointer".printf (cl.get_lower_case_cname ("value_")), "gpointer");
+		function.add_parameter (new CCodeFormalParameter ("value", "const GValue*"));
+		function.modifiers = CCodeModifiers.STATIC;
+
+		var init_block = new CCodeBlock ();
+		function.block = init_block;
+
+		var vpointer = new CCodeMemberAccess(new CCodeMemberAccess.pointer (new CCodeIdentifier ("value"), "data[0]"),"v_pointer");
+		var ret = new CCodeReturnStatement ( vpointer );
+		init_block.add_statement (ret);
+
+		source_type_member_definition.append (function);
+	}
+
+	private void add_type_value_table_lcopy_value_function ( Class cl ) {
+		var function = new CCodeFunction ("%s_lcopy_value".printf (cl.get_lower_case_cname ("value_")), "gchar*");
+		function.add_parameter (new CCodeFormalParameter ("value", "const GValue*"));
+		function.add_parameter (new CCodeFormalParameter ("n_collect_values", "guint"));
+		function.add_parameter (new CCodeFormalParameter ("collect_values", "GTypeCValue*"));
+		function.add_parameter (new CCodeFormalParameter ("collect_flags", "guint"));
+		function.modifiers = CCodeModifiers.STATIC;
+
+		var vpointer = new CCodeMemberAccess (new CCodeMemberAccess.pointer (new CCodeIdentifier ("value"), "data[0]"), "v_pointer");
+		var object_p_ptr = new CCodeIdentifier ("*object_p");
+		var null_ = new CCodeConstant ("NULL");
+
+		var init_block = new CCodeBlock ();
+
+		var ctypedecl = new CCodeDeclaration (cl.get_cname () + "**");
+		ctypedecl.add_declarator (new CCodeVariableDeclarator ("object_p", new CCodeMemberAccess (new CCodeIdentifier ("collect_values[0]"),"v_pointer")));
+		init_block.add_statement (ctypedecl);
+
+		var value_type_name_fct = new CCodeFunctionCall (new CCodeIdentifier ("G_VALUE_TYPE_NAME"));
+		value_type_name_fct.add_argument (new CCodeConstant ("value"));
+
+		var assert_condition = new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("object_p"));
+		function.block = init_block;
+		var assert_true = new CCodeBlock ();
+		var assert_printf = new CCodeFunctionCall (new CCodeIdentifier ("g_strdup_printf"));
+		assert_printf.add_argument (new CCodeConstant ("\"value location for `%s' passed as NULL\""));
+		assert_printf.add_argument (value_type_name_fct);
+		assert_true.add_statement (new CCodeReturnStatement (assert_printf));
+		var if_assert = new CCodeIfStatement (assert_condition, assert_true);
+		init_block.add_statement (if_assert);
+
+		var main_else_true = new CCodeBlock ();
+		var main_else_if_true = new CCodeBlock ();
+		var main_else_if_condition = new CCodeBinaryExpression (CCodeBinaryOperator.AND, new CCodeIdentifier ("collect_flags"), new CCodeIdentifier ("G_VALUE_NOCOPY_CONTENTS"));
+		var main_else_if = new CCodeIfStatement (main_else_if_condition, main_else_if_true, main_else_true);
+
+		var main_true = new CCodeBlock ();
+		var main_condition = new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, vpointer);
+		var if_main = new CCodeIfStatement (main_condition, main_true, main_else_if);
+		init_block.add_statement (if_main);
+
+		var ref_fct = new CCodeFunctionCall (new CCodeIdentifier (cl.get_ref_function()));
+		ref_fct.add_argument (vpointer);
+
+		main_true.add_statement (new CCodeExpressionStatement (new CCodeAssignment (object_p_ptr, null_, CCodeAssignmentOperator.SIMPLE)));
+		main_else_if_true.add_statement (new CCodeExpressionStatement (new CCodeAssignment (object_p_ptr, vpointer, CCodeAssignmentOperator.SIMPLE)));
+		main_else_true.add_statement (new CCodeExpressionStatement (new CCodeAssignment (object_p_ptr, ref_fct, CCodeAssignmentOperator.SIMPLE)));
+
+		init_block.add_statement (new CCodeReturnStatement (null_));
+		source_type_member_definition.append (function);
+	}
+
+	private void add_type_value_table_collect_value_function (Class cl) {
+		var function = new CCodeFunction ("%s_collect_value".printf (cl.get_lower_case_cname ("value_")), "gchar*");
+		function.add_parameter (new CCodeFormalParameter ("value", "GValue*"));
+		function.add_parameter (new CCodeFormalParameter ("n_collect_values", "guint"));
+		function.add_parameter (new CCodeFormalParameter ("collect_values", "GTypeCValue*"));
+		function.add_parameter (new CCodeFormalParameter ("collect_flags", "guint"));
+		function.modifiers = CCodeModifiers.STATIC;
+
+		var vpointer = new CCodeMemberAccess(new CCodeMemberAccess.pointer (new CCodeIdentifier ("value"), "data[0]"),"v_pointer");
+
+		var init_block = new CCodeBlock ();
+		function.block = init_block;
+
+		var collect_vpointer = new CCodeMemberAccess (new CCodeIdentifier ("collect_values[0]"), "v_pointer");
+
+		var true_stmt = new CCodeBlock ();
+		var false_stmt = new CCodeBlock ();
+		var if_statement = new CCodeIfStatement (collect_vpointer, true_stmt, false_stmt);
+		init_block.add_statement (if_statement);
+
+		var obj_identifier = new CCodeIdentifier ("object");
+
+		var ctypedecl = new CCodeDeclaration (cl.get_cname () + "*");
+		ctypedecl.add_declarator (new CCodeVariableDeclarator ("object", collect_vpointer));
+		true_stmt.add_statement (ctypedecl);
+
+		var l_expression = new CCodeMemberAccess (new CCodeMemberAccess.pointer (obj_identifier, "parent_instance"), "g_class");
+		var sub_condition = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, l_expression, new CCodeConstant ("NULL"));
+		var sub_true_stmt = new CCodeBlock ();
+		var sub_false_stmt = new CCodeBlock ();
+
+		var reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_value_type_compatible"));
+		var type_check = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_FROM_INSTANCE"));
+		type_check.add_argument (new CCodeIdentifier ("object"));
+		reg_call.add_argument (type_check);
+
+		var type_name_fct = new CCodeFunctionCall (new CCodeIdentifier ("g_type_name"));
+		type_name_fct.add_argument (type_check);
+
+		var stored_type = new CCodeFunctionCall (new CCodeIdentifier ("G_VALUE_TYPE"));
+		stored_type.add_argument (new CCodeIdentifier ("value"));
+		reg_call.add_argument (stored_type);
+
+		var value_type_name_fct = new CCodeFunctionCall (new CCodeIdentifier ("G_VALUE_TYPE_NAME"));
+		value_type_name_fct.add_argument (new CCodeConstant ("value"));
+
+		var true_return = new CCodeFunctionCall (new CCodeIdentifier ("g_strconcat"));
+		true_return.add_argument (new CCodeConstant ("\"invalid unclassed object pointer for value type `\""));
+		true_return.add_argument (value_type_name_fct);
+		true_return.add_argument (new CCodeConstant ("\"'\""));
+		true_return.add_argument (new CCodeConstant ("NULL"));
+		sub_true_stmt.add_statement (new CCodeReturnStatement (true_return));
+
+		var false_return = new CCodeFunctionCall (new CCodeIdentifier ("g_strconcat"));
+		false_return.add_argument (new CCodeConstant ("\"invalid object type `\""));
+		false_return.add_argument (type_name_fct);
+		false_return.add_argument (new CCodeConstant ("\"' for value type `\""));
+		false_return.add_argument (value_type_name_fct);
+		false_return.add_argument (new CCodeConstant ("\"'\""));
+		false_return.add_argument (new CCodeConstant ("NULL"));
+		sub_false_stmt.add_statement (new CCodeReturnStatement (false_return));
+
+		var sub_else_if_statement = new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, reg_call), sub_false_stmt );
+		sub_else_if_statement.else_if = true;
+		var sub_if_statement = new CCodeIfStatement (sub_condition, sub_true_stmt, sub_else_if_statement);
+		true_stmt.add_statement (sub_if_statement);
+
+		var ref_call = new CCodeFunctionCall (new CCodeIdentifier (cl.get_ref_function ()));
+		ref_call.add_argument (new CCodeIdentifier ("object"));
+
+		var true_assignment = new CCodeExpressionStatement (new CCodeAssignment (vpointer, ref_call, CCodeAssignmentOperator.SIMPLE));
+		true_stmt.add_statement (true_assignment);
+
+		var else_assigment = new CCodeExpressionStatement (new CCodeAssignment (vpointer, new CCodeConstant ("NULL"), CCodeAssignmentOperator.SIMPLE));
+		false_stmt.add_statement (else_assigment);
+
+		init_block.add_statement (new CCodeReturnStatement (new CCodeConstant ("NULL")));
+		source_type_member_definition.append (function);
+	}
+
+	private void add_g_param_spec_type_function (Class cl) {
+		var function_name = cl.get_lower_case_cname ("param_spec_");
+
+		var function = new CCodeFunction (function_name, "GParamSpec*");
+		function.add_parameter (new CCodeFormalParameter ("name", "const gchar*"));
+		function.add_parameter (new CCodeFormalParameter ("nick", "const gchar*"));
+		function.add_parameter (new CCodeFormalParameter ("blurb", "const gchar*"));
+		function.add_parameter (new CCodeFormalParameter ("object_type", "GType"));
+		function.add_parameter (new CCodeFormalParameter ("flags", "GParamFlags"));
+
+		cl.set_param_spec_function ( function_name );
+
+		if (cl.access == SymbolAccessibility.PRIVATE) {
+			function.modifiers = CCodeModifiers.STATIC;
+		}
+
+		var init_block = new CCodeBlock ();
+		function.block = init_block;
+
+		var ctypedecl = new CCodeDeclaration ("%sParamSpec%s*".printf (cl.parent_symbol.get_cprefix (), cl.name));
+		ctypedecl.add_declarator ( new CCodeVariableDeclarator ("spec"));
+		init_block.add_statement (ctypedecl);
+
+		var subccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_is_a"));
+		subccall.add_argument (new CCodeIdentifier ("object_type"));
+		subccall.add_argument (new CCodeIdentifier ( cl.get_type_id() ));
+
+		var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_return_val_if_fail"));
+		ccall.add_argument (subccall);
+		ccall.add_argument (new CCodeIdentifier ("NULL"));
+		init_block.add_statement (new CCodeExpressionStatement (ccall));
+
+		ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_param_spec_internal"));
+		ccall.add_argument (new CCodeIdentifier ( "G_TYPE_PARAM_OBJECT" ));
+		ccall.add_argument (new CCodeIdentifier ("name"));
+		ccall.add_argument (new CCodeIdentifier ("nick"));
+		ccall.add_argument (new CCodeIdentifier ("blurb"));
+		ccall.add_argument (new CCodeIdentifier ("flags"));
+
+		init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("spec"), ccall, CCodeAssignmentOperator.SIMPLE )));
+
+		ccall = new CCodeFunctionCall (new CCodeIdentifier ("G_PARAM_SPEC"));
+		ccall.add_argument (new CCodeIdentifier ("spec"));
+
+		init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "value_type"), new CCodeIdentifier ("object_type"), CCodeAssignmentOperator.SIMPLE )));
+		init_block.add_statement (new CCodeReturnStatement (ccall));
+		source_type_member_definition.append (function);
+	}
+
+	private void add_g_value_set_function (Class cl) {
+		var function = new CCodeFunction (cl.get_set_value_function (), "void");
+		function.add_parameter (new CCodeFormalParameter ("value", "GValue*"));
+		function.add_parameter (new CCodeFormalParameter ("v_object", "gpointer"));
+
+		if (cl.access == SymbolAccessibility.PRIVATE) {
+			function.modifiers = CCodeModifiers.STATIC;
+		}
+
+		var vpointer = new CCodeMemberAccess(new CCodeMemberAccess.pointer (new CCodeIdentifier ("value"), "data[0]"),"v_pointer");
+
+		var init_block = new CCodeBlock ();
+		function.block = init_block;
+
+		var ctypedecl = new CCodeDeclaration (cl.get_cname()+"*");
+		ctypedecl.add_declarator ( new CCodeVariableDeclarator ("old"));
+		init_block.add_statement (ctypedecl);
+
+		var ccall_typecheck = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_CHECK_VALUE_TYPE"));
+		ccall_typecheck.add_argument (new CCodeIdentifier ( "value" ));
+		ccall_typecheck.add_argument (new CCodeIdentifier ( cl.get_type_id() ));
+
+		var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_return_if_fail"));
+		ccall.add_argument (ccall_typecheck);
+		init_block.add_statement (new CCodeExpressionStatement (ccall));
+
+		init_block.add_statement(new CCodeExpressionStatement (new CCodeAssignment (new CCodeConstant ("old"), vpointer, CCodeAssignmentOperator.SIMPLE)));
+
+		var true_stmt = new CCodeBlock ();
+		var false_stmt = new CCodeBlock ();
+		var if_statement = new CCodeIfStatement (new CCodeIdentifier ("v_object"), true_stmt, false_stmt);
+		init_block.add_statement (if_statement);
+
+
+		ccall_typecheck = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_CHECK_INSTANCE_TYPE"));
+		ccall_typecheck.add_argument (new CCodeIdentifier ( "v_object" ));
+		ccall_typecheck.add_argument (new CCodeIdentifier ( cl.get_type_id() ));
+
+		ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_return_if_fail"));
+		ccall.add_argument (ccall_typecheck);
+		true_stmt.add_statement (new CCodeExpressionStatement (ccall));
+
+		var ccall_typefrominstance = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_FROM_INSTANCE"));
+		ccall_typefrominstance.add_argument (new CCodeIdentifier ( "v_object" ));
+
+		var ccall_gvaluetype = new CCodeFunctionCall (new CCodeIdentifier ("G_VALUE_TYPE"));
+		ccall_gvaluetype.add_argument (new CCodeIdentifier ( "value" ));
+
+		var ccall_typecompatible = new CCodeFunctionCall (new CCodeIdentifier ("g_value_type_compatible"));
+		ccall_typecompatible.add_argument (ccall_typefrominstance);
+		ccall_typecompatible.add_argument (ccall_gvaluetype);
+
+		ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_return_if_fail"));
+		ccall.add_argument (ccall_typecompatible);
+		true_stmt.add_statement (new CCodeExpressionStatement (ccall));
+
+		true_stmt.add_statement(new CCodeExpressionStatement (new CCodeAssignment (vpointer, new CCodeConstant ("v_object"), CCodeAssignmentOperator.SIMPLE)));
+
+		ccall = new CCodeFunctionCall (new CCodeIdentifier (cl.get_ref_function ()));
+		ccall.add_argument (vpointer);
+		true_stmt.add_statement (new CCodeExpressionStatement (ccall));
+
+		false_stmt.add_statement(new CCodeExpressionStatement (new CCodeAssignment (vpointer, new CCodeConstant ("NULL"), CCodeAssignmentOperator.SIMPLE)));
+
+		true_stmt = new CCodeBlock ();
+		if_statement = new CCodeIfStatement (new CCodeIdentifier ("old"), true_stmt);
+		init_block.add_statement (if_statement);
+		
+		ccall = new CCodeFunctionCall (new CCodeIdentifier (cl.get_unref_function ()));
+		ccall.add_argument (new CCodeIdentifier ("old"));
+		true_stmt.add_statement (new CCodeExpressionStatement (ccall));
+		source_type_member_definition.append (function);
+	}
+
+	private void add_g_value_get_function (Class cl) {
+		var function = new CCodeFunction (cl.get_get_value_function (), "gpointer");
+		function.add_parameter (new CCodeFormalParameter ("value", "const GValue*"));
+
+		if (cl.access == SymbolAccessibility.PRIVATE) {
+			function.modifiers = CCodeModifiers.STATIC;
+		}
+
+		var vpointer = new CCodeMemberAccess(new CCodeMemberAccess.pointer (new CCodeIdentifier ("value"), "data[0]"),"v_pointer");
+
+		var init_block = new CCodeBlock ();
+		function.block = init_block;
+
+		var ccall_typecheck = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_CHECK_VALUE_TYPE"));
+		ccall_typecheck.add_argument (new CCodeIdentifier ( "value" ));
+		ccall_typecheck.add_argument (new CCodeIdentifier ( cl.get_type_id() ));
+
+		var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_return_val_if_fail"));
+		ccall.add_argument (ccall_typecheck);
+		ccall.add_argument (new CCodeIdentifier ( "NULL" ));
+		init_block.add_statement (new CCodeExpressionStatement (ccall));
+
+		init_block.add_statement (new CCodeReturnStatement ( vpointer ));
+		source_type_member_definition.append (function);
+	}
+
+	private void add_base_init_function (Class cl) {
+		var base_init = new CCodeFunction ("%s_base_init".printf (cl.get_lower_case_cname (null)), "void");
+		base_init.add_parameter (new CCodeFormalParameter ("klass", "%sClass *".printf (cl.get_cname ())));
+		base_init.modifiers = CCodeModifiers.STATIC;
+
+		var init_block = new CCodeBlock ();
+		base_init.block = init_block;
+
+		if (cl.has_class_private_fields) {
+			var block = new CCodeBlock ();
+			var cdecl = new CCodeDeclaration ("%sClassPrivate *".printf (cl.get_cname ()));
+			cdecl.add_declarator (new CCodeVariableDeclarator ("priv"));
+			block.add_statement (cdecl);
+			cdecl = new CCodeDeclaration ("%sClassPrivate *".printf (cl.get_cname ()));
+			cdecl.add_declarator (new CCodeVariableDeclarator ("parent_priv", new CCodeConstant ("NULL")));
+			block.add_statement (cdecl);
+			cdecl = new CCodeDeclaration ("GType");
+			cdecl.add_declarator (new CCodeVariableDeclarator ("parent_type"));
+			block.add_statement (cdecl);
+
+			var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_parent"));
+			var ccall2 = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_FROM_CLASS"));
+			ccall2.add_argument (new CCodeIdentifier ("klass"));
+			ccall.add_argument (ccall2);
+			block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("parent_type"), ccall)));
+
+			var iftrue = new CCodeBlock ();
+			ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS_PRIVATE".printf (cl.get_upper_case_cname (null))));
+			ccall.add_argument (new CCodeIdentifier ("parent_type"));
+			iftrue.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("parent_priv"), ccall)));
+			block.add_statement (new CCodeIfStatement (new CCodeIdentifier ("parent_type"), iftrue));
+
+			ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_new0"));
+			ccall.add_argument (new CCodeIdentifier ("%sClassPrivate".printf(cl.get_cname())));
+
+			block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("priv"), ccall)));
+
+			source_declarations.add_include ("string.h");
+
+			iftrue = new CCodeBlock ();
+			ccall = new CCodeFunctionCall (new CCodeIdentifier ("memcpy"));
+			ccall.add_argument (new CCodeIdentifier ("priv"));
+			ccall.add_argument (new CCodeIdentifier ("parent_priv"));
+			ccall.add_argument (new CCodeIdentifier ("sizeof (%sClassPrivate)".printf(cl.get_cname())));
+			iftrue.add_statement (new CCodeExpressionStatement (ccall));
+
+			block.add_statement (new CCodeIfStatement (new CCodeIdentifier ("parent_priv"), iftrue));
+
+			ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_set_qdata"));
+			ccall2 = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_FROM_CLASS"));
+			ccall2.add_argument (new CCodeIdentifier ("klass"));
+			ccall.add_argument (ccall2);
+			ccall.add_argument (new CCodeIdentifier ("_vala_%s_class_private_quark".printf (cl.get_lower_case_cname ())));
+			ccall.add_argument (new CCodeIdentifier ("priv"));
+			block.add_statement (new CCodeExpressionStatement (ccall));
+
+			init_block.add_statement (block);
+
+			block = new CCodeBlock ();
+			cdecl = new CCodeDeclaration ("%sClassPrivate *".printf (cl.get_cname ()));
+			cdecl.add_declarator (new CCodeVariableDeclarator ("priv"));
+			block.add_statement (cdecl);
+
+			ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS_PRIVATE".printf (cl.get_upper_case_cname (null))));
+			ccall2 = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_FROM_CLASS"));
+			ccall2.add_argument (new CCodeIdentifier ("klass"));
+			ccall.add_argument (ccall2);
+			block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("priv"), ccall)));
+
+			ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_free"));
+			ccall.add_argument (new CCodeIdentifier ("%sClassPrivate".printf (cl.get_cname ())));
+			ccall.add_argument (new CCodeIdentifier ("priv"));
+			block.add_statement (new CCodeExpressionStatement (ccall));
+			base_finalize_fragment.append (block);
+		}
+
+		init_block.add_statement (base_init_fragment);
+
+		source_type_member_definition.append (base_init);
+	}
+
+	public virtual void generate_class_init (Class cl, CCodeBlock init_block) {
+	}
+
+	private void add_class_init_function (Class cl) {
+		var class_init = new CCodeFunction ("%s_class_init".printf (cl.get_lower_case_cname (null)), "void");
+		class_init.add_parameter (new CCodeFormalParameter ("klass", "%sClass *".printf (cl.get_cname ())));
+		class_init.modifiers = CCodeModifiers.STATIC;
+
+		var init_block = new CCodeBlock ();
+		class_init.block = init_block;
+		
+		CCodeFunctionCall ccall;
+		
+		/* save pointer to parent class */
+		var parent_decl = new CCodeDeclaration ("gpointer");
+		var parent_var_decl = new CCodeVariableDeclarator ("%s_parent_class".printf (cl.get_lower_case_cname (null)));
+		parent_var_decl.initializer = new CCodeConstant ("NULL");
+		parent_decl.add_declarator (parent_var_decl);
+		parent_decl.modifiers = CCodeModifiers.STATIC;
+		source_declarations.add_type_member_declaration (parent_decl);
+		ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek_parent"));
+		ccall.add_argument (new CCodeIdentifier ("klass"));
+		var parent_assignment = new CCodeAssignment (new CCodeIdentifier ("%s_parent_class".printf (cl.get_lower_case_cname (null))), ccall);
+		init_block.add_statement (new CCodeExpressionStatement (parent_assignment));
+		
+
+		if (!cl.is_compact && !cl.is_subtype_of (gobject_type) && (cl.get_fields ().size > 0 || cl.destructor != null || cl.is_fundamental ())) {
+			// set finalize function
+			var fundamental_class = cl;
+			while (fundamental_class.base_class != null) {
+				fundamental_class = fundamental_class.base_class;
+			}
+
+			ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (fundamental_class.get_upper_case_cname (null))));
+			ccall.add_argument (new CCodeIdentifier ("klass"));
+			var finalize_assignment = new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "finalize"), new CCodeIdentifier (cl.get_lower_case_cprefix () + "finalize"));
+			init_block.add_statement (new CCodeExpressionStatement (finalize_assignment));
+		}
+
+		/* add struct for private fields */
+		if (cl.has_private_fields || cl.get_type_parameters ().size > 0) {
+			ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_add_private"));
+			ccall.add_argument (new CCodeIdentifier ("klass"));
+			ccall.add_argument (new CCodeConstant ("sizeof (%sPrivate)".printf (cl.get_cname ())));
+			init_block.add_statement (new CCodeExpressionStatement (ccall));
+		}
+
+		/* connect overridden methods */
+		foreach (Method m in cl.get_methods ()) {
+			if (m.base_method == null) {
+				continue;
+			}
+			var base_type = m.base_method.parent_symbol;
+			
+			var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (((Class) base_type).get_upper_case_cname (null))));
+			ccast.add_argument (new CCodeIdentifier ("klass"));
+			init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, m.base_method.vfunc_name), new CCodeIdentifier (m.get_real_cname ()))));
+		}
+
+		/* connect overridden properties */
+		foreach (Property prop in cl.get_properties ()) {
+			if (prop.base_property == null) {
+				continue;
+			}
+			var base_type = prop.base_property.parent_symbol;
+			
+			var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (((Class) base_type).get_upper_case_cname (null))));
+			ccast.add_argument (new CCodeIdentifier ("klass"));
+
+			if (prop.get_accessor != null) {
+				string cname = "%s_real_get_%s".printf (cl.get_lower_case_cname (null), prop.name);
+				init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "get_%s".printf (prop.name)), new CCodeIdentifier (cname))));
+			}
+			if (prop.set_accessor != null) {
+				string cname = "%s_real_set_%s".printf (cl.get_lower_case_cname (null), prop.name);
+				init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "set_%s".printf (prop.name)), new CCodeIdentifier (cname))));
+			}
+		}
+
+		/* initialize class fields */
+		var fields = cl.get_fields ();
+		foreach (Field field in fields) {
+			if (field.binding != MemberBinding.CLASS || field.initializer == null) {
+				continue;
+			}
+
+			CCodeExpression left;
+
+			if (field.access == SymbolAccessibility.PRIVATE) {
+				ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS_PRIVATE".printf (cl.get_upper_case_cname ())));
+				var ccall2 = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_FROM_CLASS"));
+				ccall2.add_argument (new CCodeIdentifier ("klass"));
+				ccall.add_argument (ccall2);
+				left = new CCodeMemberAccess (ccall, field.get_cname (), true);
+			} else {
+				left = new CCodeMemberAccess (new CCodeIdentifier ("klass"), field.get_cname (), true);
+			}
+			CCodeExpression right = (CCodeExpression) field.initializer.ccodenode;
+			CCodeAssignment assign = new CCodeAssignment (left, right);
+			init_block.add_statement (new CCodeExpressionStatement (assign));
+		}
+
+		generate_class_init (cl, init_block);
+
+		if (!cl.is_compact) {
+			/* create signals */
+			foreach (Signal sig in cl.get_signals ()) {
+				init_block.add_statement (new CCodeExpressionStatement (head.get_signal_creation (sig, cl)));
+			}
+		}
+
+		init_block.add_statement (head.register_dbus_info (cl));
+		init_block.add_statement (class_init_fragment);
+
+		source_type_member_definition.append (class_init);
+	}
+	
+	private void add_interface_init_function (Class cl, Interface iface) {
+		var iface_init = new CCodeFunction ("%s_%s_interface_init".printf (cl.get_lower_case_cname (null), iface.get_lower_case_cname (null)), "void");
+		iface_init.add_parameter (new CCodeFormalParameter ("iface", "%s *".printf (iface.get_type_cname ())));
+		iface_init.modifiers = CCodeModifiers.STATIC;
+		
+		var init_block = new CCodeBlock ();
+		iface_init.block = init_block;
+		
+		CCodeFunctionCall ccall;
+		
+		/* save pointer to parent vtable */
+		string parent_iface_var = "%s_%s_parent_iface".printf (cl.get_lower_case_cname (null), iface.get_lower_case_cname (null));
+		var parent_decl = new CCodeDeclaration (iface.get_type_cname () + "*");
+		var parent_var_decl = new CCodeVariableDeclarator (parent_iface_var);
+		parent_var_decl.initializer = new CCodeConstant ("NULL");
+		parent_decl.add_declarator (parent_var_decl);
+		parent_decl.modifiers = CCodeModifiers.STATIC;
+		source_declarations.add_type_member_declaration (parent_decl);
+		ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_interface_peek_parent"));
+		ccall.add_argument (new CCodeIdentifier ("iface"));
+		var parent_assignment = new CCodeAssignment (new CCodeIdentifier (parent_iface_var), ccall);
+		init_block.add_statement (new CCodeExpressionStatement (parent_assignment));
+
+		foreach (Method m in cl.get_methods ()) {
+			if (m.base_interface_method == null) {
+				continue;
+			}
+
+			var base_type = m.base_interface_method.parent_symbol;
+			if (base_type != iface) {
+				continue;
+			}
+			
+			var ciface = new CCodeIdentifier ("iface");
+			string cname = m.get_real_cname ();
+			if (m.is_abstract || m.is_virtual) {
+				// FIXME results in C compiler warning
+				cname = m.get_cname ();
+			}
+			init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ciface, m.base_interface_method.vfunc_name), new CCodeIdentifier (cname))));
+		}
+
+		// connect inherited implementations
+		foreach (Method m in iface.get_methods ()) {
+			if (m.is_abstract) {
+				Method cl_method = null;
+				var base_class = cl;
+				while (base_class != null && cl_method == null) {
+					cl_method = base_class.scope.lookup (m.name) as Method;
+					base_class = base_class.base_class;
+				}
+				if (base_class != null && cl_method.parent_symbol != cl) {
+					// method inherited from base class
+
+					var base_method = cl_method;
+					if (cl_method.base_method != null) {
+						base_method = cl_method.base_method;
+					} else if (cl_method.base_interface_method != null) {
+						base_method = cl_method.base_interface_method;
+					}
+
+					var ciface = new CCodeIdentifier ("iface");
+					init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ciface, m.vfunc_name), new CCodeIdentifier (base_method.get_cname ()))));
+				}
+			}
+		}
+
+		foreach (Property prop in cl.get_properties ()) {
+			if (prop.base_interface_property == null) {
+				continue;
+			}
+
+			var base_type = prop.base_interface_property.parent_symbol;
+			if (base_type != iface) {
+				continue;
+			}
+			
+			var ciface = new CCodeIdentifier ("iface");
+
+			if (prop.get_accessor != null) {
+				string cname = "%s_real_get_%s".printf (cl.get_lower_case_cname (null), prop.name);
+				if (prop.is_abstract || prop.is_virtual) {
+					cname = "%s_get_%s".printf (cl.get_lower_case_cname (null), prop.name);
+				}
+				init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ciface, "get_%s".printf (prop.name)), new CCodeIdentifier (cname))));
+			}
+			if (prop.set_accessor != null) {
+				string cname = "%s_real_set_%s".printf (cl.get_lower_case_cname (null), prop.name);
+				if (prop.is_abstract || prop.is_virtual) {
+					cname = "%s_set_%s".printf (cl.get_lower_case_cname (null), prop.name);
+				}
+				init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ciface, "set_%s".printf (prop.name)), new CCodeIdentifier (cname))));
+			}
+		}
+
+		foreach (Property prop in iface.get_properties ()) {
+			if (!prop.is_abstract) {
+				continue;
+			}
+
+			Property cl_prop = null;
+			var base_class = cl;
+			while (base_class != null && cl_prop == null) {
+				cl_prop = base_class.scope.lookup (prop.name) as Property;
+				base_class = base_class.base_class;
+			}
+			if (base_class != null && cl_prop.parent_symbol != cl) {
+				// property inherited from base class
+
+				var base_property = cl_prop;
+				if (cl_prop.base_property != null) {
+					base_property = cl_prop.base_property;
+				} else if (cl_prop.base_interface_property != null) {
+					base_property = cl_prop.base_interface_property;
+				}
+
+				var ciface = new CCodeIdentifier ("iface");
+
+				if (base_property.get_accessor != null) {
+					string cname = base_property.get_accessor.get_cname ();
+					init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ciface, "get_%s".printf (prop.name)), new CCodeIdentifier (cname))));
+				}
+				if (base_property.set_accessor != null) {
+					string cname = base_property.set_accessor.get_cname ();
+					init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ciface, "set_%s".printf (prop.name)), new CCodeIdentifier (cname))));
+				}
+			}
+		}
+
+		source_type_member_definition.append (iface_init);
+	}
+	
+	private void add_instance_init_function (Class cl) {
+		var instance_init = new CCodeFunction ("%s_instance_init".printf (cl.get_lower_case_cname (null)), "void");
+		instance_init.add_parameter (new CCodeFormalParameter ("self", "%s *".printf (cl.get_cname ())));
+		instance_init.modifiers = CCodeModifiers.STATIC;
+		
+		if (cl.is_compact) {
+			// Add declaration, since the instance_init function is explicitly called
+			// by the creation methods
+			source_declarations.add_type_member_declaration (instance_init.copy ());
+		}
+
+		var init_block = new CCodeBlock ();
+		instance_init.block = init_block;
+		
+		if (!cl.is_compact && (cl.has_private_fields || cl.get_type_parameters ().size > 0)) {
+			var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (cl.get_upper_case_cname (null))));
+			ccall.add_argument (new CCodeIdentifier ("self"));
+			init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), ccall)));
+		}
+		
+		init_block.add_statement (instance_init_fragment);
+
+		source_type_member_definition.append (instance_init);
+	}
+
+	private void add_class_finalize_function (Class cl) {
+		var function = new CCodeFunction ("%s_class_finalize".printf (cl.get_lower_case_cname (null)), "void");
+		function.modifiers = CCodeModifiers.STATIC;
+
+		function.add_parameter (new CCodeFormalParameter ("klass", cl.get_cname () + "Class *"));
+		source_declarations.add_type_member_declaration (function.copy ());
+		
+		var cblock = new CCodeBlock ();
+
+		if (cl.class_destructor != null) {
+			cblock.add_statement (cl.class_destructor.ccodenode);
+		}
+
+		cblock.add_statement (class_finalize_fragment);
+
+		function.block = cblock;
+		source_type_member_definition.append (function);
+	}
+
+	private void add_base_finalize_function (Class cl) {
+		var function = new CCodeFunction ("%s_base_finalize".printf (cl.get_lower_case_cname (null)), "void");
+		function.modifiers = CCodeModifiers.STATIC;
+
+		function.add_parameter (new CCodeFormalParameter ("klass", cl.get_cname () + "Class *"));
+		source_declarations.add_type_member_declaration (function.copy ());
+		
+		var cblock = new CCodeBlock ();
+
+		if (cl.class_destructor != null) {
+			cblock.add_statement (cl.class_destructor.ccodenode);
+		}
+
+		cblock.add_statement (base_finalize_fragment);
+
+		function.block = cblock;
+		source_type_member_definition.append (function);
+	}
+
+	private void add_finalize_function (Class cl) {
+		var function = new CCodeFunction ("%s_finalize".printf (cl.get_lower_case_cname (null)), "void");
+		function.modifiers = CCodeModifiers.STATIC;
+
+		var fundamental_class = cl;
+		while (fundamental_class.base_class != null) {
+			fundamental_class = fundamental_class.base_class;
+		}
+
+		function.add_parameter (new CCodeFormalParameter ("obj", fundamental_class.get_cname () + "*"));
+
+		source_declarations.add_type_member_declaration (function.copy ());
+
+
+		var cblock = new CCodeBlock ();
+
+		CCodeFunctionCall ccall = new InstanceCast (new CCodeIdentifier ("obj"), cl);
+
+		var cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
+		cdecl.add_declarator (new CCodeVariableDeclarator ("self", ccall));
+		
+		cblock.add_statement (cdecl);
+
+		if (cl.destructor != null) {
+			cblock.add_statement (cl.destructor.ccodenode);
+		}
+
+		cblock.add_statement (instance_finalize_fragment);
+
+		// chain up to finalize function of the base class
+		if (cl.base_class != null) {
+			var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (fundamental_class.get_upper_case_cname ())));
+			ccast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (cl.get_lower_case_cname (null))));
+			ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (ccast, "finalize"));
+			ccall.add_argument (new CCodeIdentifier ("obj"));
+			cblock.add_statement (new CCodeExpressionStatement (ccall));
+		}
+
+
+		function.block = cblock;
+
+		source_type_member_definition.append (function);
+	}
+
+	public override CCodeFunctionCall get_param_spec (Property prop) {
+		var cspec = new CCodeFunctionCall ();
+		cspec.add_argument (prop.get_canonical_cconstant ());
+		cspec.add_argument (new CCodeConstant ("\"%s\"".printf (prop.nick)));
+		cspec.add_argument (new CCodeConstant ("\"%s\"".printf (prop.blurb)));
+
+
+		if ((prop.property_type.data_type is Class && !(((Class) prop.property_type.data_type).is_compact)) || prop.property_type.data_type is Interface) {
+			string param_spec_name = prop.property_type.data_type.get_param_spec_function ();
+			if (param_spec_name == null) {
+				cspec.call = new CCodeIdentifier ("g_param_spec_pointer");
+			} else {
+				cspec.call = new CCodeIdentifier (param_spec_name);
+				cspec.add_argument (new CCodeIdentifier (prop.property_type.data_type.get_type_id ()));
+			}
+		} else if (prop.property_type.data_type == string_type.data_type) {
+			cspec.call = new CCodeIdentifier ("g_param_spec_string");
+			cspec.add_argument (new CCodeConstant ("NULL"));
+		} else if (prop.property_type.data_type is Enum) {
+			var e = prop.property_type.data_type as Enum;
+			if (e.has_type_id) {
+				if (e.is_flags) {
+					cspec.call = new CCodeIdentifier ("g_param_spec_flags");
+				} else {
+					cspec.call = new CCodeIdentifier ("g_param_spec_enum");
+				}
+				cspec.add_argument (new CCodeIdentifier (e.get_type_id ()));
+			} else {
+				if (e.is_flags) {
+					cspec.call = new CCodeIdentifier ("g_param_spec_uint");
+					cspec.add_argument (new CCodeConstant ("0"));
+					cspec.add_argument (new CCodeConstant ("G_MAXUINT"));
+				} else {
+					cspec.call = new CCodeIdentifier ("g_param_spec_int");
+					cspec.add_argument (new CCodeConstant ("G_MININT"));
+					cspec.add_argument (new CCodeConstant ("G_MAXINT"));
+				}
+			}
+
+			if (prop.default_expression != null) {
+				cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
+			} else {
+				cspec.add_argument (new CCodeConstant (prop.property_type.data_type.get_default_value ()));
+			}
+		} else if (prop.property_type.data_type is Struct) {
+			var st = (Struct) prop.property_type.data_type;
+			if (st.get_type_id () == "G_TYPE_INT") {
+				cspec.call = new CCodeIdentifier ("g_param_spec_int");
+				cspec.add_argument (new CCodeConstant ("G_MININT"));
+				cspec.add_argument (new CCodeConstant ("G_MAXINT"));
+				if (prop.default_expression != null) {
+					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
+				} else {
+					cspec.add_argument (new CCodeConstant ("0"));
+				}
+			} else if (st.get_type_id () == "G_TYPE_UINT") {
+				cspec.call = new CCodeIdentifier ("g_param_spec_uint");
+				cspec.add_argument (new CCodeConstant ("0"));
+				cspec.add_argument (new CCodeConstant ("G_MAXUINT"));
+				if (prop.default_expression != null) {
+					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
+				} else {
+					cspec.add_argument (new CCodeConstant ("0U"));
+				}
+			} else if (st.get_type_id () == "G_TYPE_INT64") {
+				cspec.call = new CCodeIdentifier ("g_param_spec_int64");
+				cspec.add_argument (new CCodeConstant ("G_MININT64"));
+				cspec.add_argument (new CCodeConstant ("G_MAXINT64"));
+				if (prop.default_expression != null) {
+					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
+				} else {
+					cspec.add_argument (new CCodeConstant ("0"));
+				}
+			} else if (st.get_type_id () == "G_TYPE_UINT64") {
+				cspec.call = new CCodeIdentifier ("g_param_spec_uint64");
+				cspec.add_argument (new CCodeConstant ("0"));
+				cspec.add_argument (new CCodeConstant ("G_MAXUINT64"));
+				if (prop.default_expression != null) {
+					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
+				} else {
+					cspec.add_argument (new CCodeConstant ("0U"));
+				}
+			} else if (st.get_type_id () == "G_TYPE_LONG") {
+				cspec.call = new CCodeIdentifier ("g_param_spec_long");
+				cspec.add_argument (new CCodeConstant ("G_MINLONG"));
+				cspec.add_argument (new CCodeConstant ("G_MAXLONG"));
+				if (prop.default_expression != null) {
+					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
+				} else {
+					cspec.add_argument (new CCodeConstant ("0L"));
+				}
+			} else if (st.get_type_id () == "G_TYPE_ULONG") {
+				cspec.call = new CCodeIdentifier ("g_param_spec_ulong");
+				cspec.add_argument (new CCodeConstant ("0"));
+				cspec.add_argument (new CCodeConstant ("G_MAXULONG"));
+				if (prop.default_expression != null) {
+					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
+				} else {
+					cspec.add_argument (new CCodeConstant ("0UL"));
+				}
+			} else if (st.get_type_id () == "G_TYPE_BOOLEAN") {
+				cspec.call = new CCodeIdentifier ("g_param_spec_boolean");
+				if (prop.default_expression != null) {
+					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
+				} else {
+					cspec.add_argument (new CCodeConstant ("FALSE"));
+				}
+			} else if (st.get_type_id () == "G_TYPE_CHAR") {
+				cspec.call = new CCodeIdentifier ("g_param_spec_char");
+				cspec.add_argument (new CCodeConstant ("G_MININT8"));
+				cspec.add_argument (new CCodeConstant ("G_MAXINT8"));
+				if (prop.default_expression != null) {
+					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
+				} else {
+					cspec.add_argument (new CCodeConstant ("0"));
+				}
+			} else if (st.get_type_id () == "G_TYPE_UCHAR") {
+				cspec.call = new CCodeIdentifier ("g_param_spec_uchar");
+				cspec.add_argument (new CCodeConstant ("0"));
+				cspec.add_argument (new CCodeConstant ("G_MAXUINT8"));
+				if (prop.default_expression != null) {
+					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
+				} else {
+					cspec.add_argument (new CCodeConstant ("0"));
+				}
+			}else if (st.get_type_id () == "G_TYPE_FLOAT") {
+				cspec.call = new CCodeIdentifier ("g_param_spec_float");
+				cspec.add_argument (new CCodeConstant ("-G_MAXFLOAT"));
+				cspec.add_argument (new CCodeConstant ("G_MAXFLOAT"));
+				if (prop.default_expression != null) {
+					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
+				} else {
+					cspec.add_argument (new CCodeConstant ("0.0F"));
+				}
+			} else if (st.get_type_id () == "G_TYPE_DOUBLE") {
+				cspec.call = new CCodeIdentifier ("g_param_spec_double");
+				cspec.add_argument (new CCodeConstant ("-G_MAXDOUBLE"));
+				cspec.add_argument (new CCodeConstant ("G_MAXDOUBLE"));
+				if (prop.default_expression != null) {
+					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
+				} else {
+					cspec.add_argument (new CCodeConstant ("0.0"));
+				}
+			} else if (st.get_type_id () == "G_TYPE_GTYPE") {
+				cspec.call = new CCodeIdentifier ("g_param_spec_gtype");
+				if (prop.default_expression != null) {
+					cspec.add_argument ((CCodeExpression) prop.default_expression.ccodenode);
+				} else {
+					cspec.add_argument (new CCodeConstant ("G_TYPE_NONE"));
+				}
+			} else {
+				cspec.call = new CCodeIdentifier ("g_param_spec_boxed");
+				cspec.add_argument (new CCodeIdentifier (st.get_type_id ()));
+			}
+		} else {
+			cspec.call = new CCodeIdentifier ("g_param_spec_pointer");
+		}
+		
+		var pflags = "G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB";
+		if (prop.get_accessor != null) {
+			pflags = "%s%s".printf (pflags, " | G_PARAM_READABLE");
+		}
+		if (prop.set_accessor != null) {
+			pflags = "%s%s".printf (pflags, " | G_PARAM_WRITABLE");
+			if (prop.set_accessor.construction) {
+				if (prop.set_accessor.writable) {
+					pflags = "%s%s".printf (pflags, " | G_PARAM_CONSTRUCT");
+				} else {
+					pflags = "%s%s".printf (pflags, " | G_PARAM_CONSTRUCT_ONLY");
+				}
+			}
+		}
+		cspec.add_argument (new CCodeConstant (pflags));
+
+		return cspec;
+	}
+
 	public override void generate_interface_declaration (Interface iface, CCodeDeclarationSpace decl_space) {
 		if (decl_space.add_symbol_declaration (iface, iface.get_cname ())) {
 			return;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]