]> git.pld-linux.org Git - packages/vala.git/commitdiff
- obsoleted by 0.5.2
authoraredridel <aredridel@pld-linux.org>
Tue, 2 Dec 2008 02:28:26 +0000 (02:28 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    vala-0.5.1-2004.patch -> 1.2

vala-0.5.1-2004.patch [deleted file]

diff --git a/vala-0.5.1-2004.patch b/vala-0.5.1-2004.patch
deleted file mode 100644 (file)
index 3da3e24..0000000
+++ /dev/null
@@ -1,10306 +0,0 @@
-Index: vala/valablock.vala
-===================================================================
---- vala/valablock.vala        (revision 1971)
-+++ vala/valablock.vala        (revision 2004)
-@@ -90,4 +90,29 @@
-                       stmt.accept (visitor);
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              owner = analyzer.current_symbol.scope;
-+              analyzer.current_symbol = this;
-+
-+              accept_children (analyzer);
-+
-+              foreach (LocalVariable local in get_local_variables ()) {
-+                      local.active = false;
-+              }
-+
-+              foreach (Statement stmt in get_statements()) {
-+                      add_error_types (stmt.get_error_types ());
-+              }
-+
-+              analyzer.current_symbol = analyzer.current_symbol.parent_symbol;
-+
-+              return !error;
-+      }
- }
-Index: vala/valalocalvariable.vala
-===================================================================
---- vala/valalocalvariable.vala        (revision 1971)
-+++ vala/valalocalvariable.vala        (revision 2004)
-@@ -98,4 +98,96 @@
-                       variable_type = new_type;
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              if (initializer != null) {
-+                      initializer.target_type = variable_type;
-+              }
-+
-+              accept_children (analyzer);
-+
-+              if (variable_type == null) {
-+                      /* var type */
-+
-+                      if (initializer == null) {
-+                              error = true;
-+                              Report.error (source_reference, "var declaration not allowed without initializer");
-+                              return false;
-+                      }
-+                      if (initializer.value_type == null) {
-+                              error = true;
-+                              Report.error (source_reference, "var declaration not allowed with non-typed initializer");
-+                              return false;
-+                      }
-+
-+                      variable_type = initializer.value_type.copy ();
-+                      variable_type.value_owned = true;
-+                      variable_type.floating_reference = false;
-+
-+                      initializer.target_type = variable_type;
-+              }
-+
-+              if (initializer != null) {
-+                      if (initializer.value_type == null) {
-+                              if (!(initializer is MemberAccess) && !(initializer is LambdaExpression)) {
-+                                      error = true;
-+                                      Report.error (source_reference, "expression type not allowed as initializer");
-+                                      return false;
-+                              }
-+
-+                              if (initializer.symbol_reference is Method &&
-+                                  variable_type is DelegateType) {
-+                                      var m = (Method) initializer.symbol_reference;
-+                                      var dt = (DelegateType) variable_type;
-+                                      var cb = dt.delegate_symbol;
-+
-+                                      /* check whether method matches callback type */
-+                                      if (!cb.matches_method (m)) {
-+                                              error = true;
-+                                              Report.error (source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.get_full_name (), cb.get_full_name ()));
-+                                              return false;
-+                                      }
-+
-+                                      initializer.value_type = variable_type;
-+                              } else {
-+                                      error = true;
-+                                      Report.error (source_reference, "expression type not allowed as initializer");
-+                                      return false;
-+                              }
-+                      }
-+
-+                      if (!initializer.value_type.compatible (variable_type)) {
-+                              error = true;
-+                              Report.error (source_reference, "Assignment: Cannot convert from `%s' to `%s'".printf (initializer.value_type.to_string (), variable_type.to_string ()));
-+                              return false;
-+                      }
-+
-+                      if (initializer.value_type.is_disposable ()) {
-+                              /* rhs transfers ownership of the expression */
-+                              if (!(variable_type is PointerType) && !variable_type.value_owned) {
-+                                      /* lhs doesn't own the value */
-+                                      error = true;
-+                                      Report.error (source_reference, "Invalid assignment from owned expression to unowned variable");
-+                                      return false;
-+                              }
-+                      }
-+              }
-+
-+              analyzer.current_source_file.add_type_dependency (variable_type, SourceFileDependencyType.SOURCE);
-+
-+              analyzer.current_symbol.scope.add (name, this);
-+
-+              var block = (Block) analyzer.current_symbol;
-+              block.add_local_variable (this);
-+
-+              active = true;
-+
-+              return !error;
-+      }
- }
-Index: vala/valainterface.vala
-===================================================================
---- vala/valainterface.vala    (revision 1971)
-+++ vala/valainterface.vala    (revision 2004)
-@@ -540,4 +540,61 @@
-               return null;
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              process_attributes ();
-+
-+              var old_source_file = analyzer.current_source_file;
-+              var old_symbol = analyzer.current_symbol;
-+
-+              if (source_reference != null) {
-+                      analyzer.current_source_file = source_reference.file;
-+              }
-+              analyzer.current_symbol = this;
-+
-+              foreach (DataType prerequisite_reference in get_prerequisites ()) {
-+                      // check whether prerequisite is at least as accessible as the interface
-+                      if (!analyzer.is_type_accessible (this, prerequisite_reference)) {
-+                              error = true;
-+                              Report.error (source_reference, "prerequisite `%s` is less accessible than interface `%s`".printf (prerequisite_reference.to_string (), get_full_name ()));
-+                              return false;
-+                      }
-+
-+                      analyzer.current_source_file.add_type_dependency (prerequisite_reference, SourceFileDependencyType.HEADER_FULL);
-+              }
-+
-+              /* check prerequisites */
-+              Class prereq_class;
-+              foreach (DataType prereq in get_prerequisites ()) {
-+                      TypeSymbol class_or_interface = prereq.data_type;
-+                      /* skip on previous errors */
-+                      if (class_or_interface == null) {
-+                              error = true;
-+                              continue;
-+                      }
-+                      /* interfaces are not allowed to have multiple instantiable prerequisites */
-+                      if (class_or_interface is Class) {
-+                              if (prereq_class != null) {
-+                                      error = true;
-+                                      Report.error (source_reference, "%s: Interfaces cannot have multiple instantiable prerequisites (`%s' and `%s')".printf (get_full_name (), class_or_interface.get_full_name (), prereq_class.get_full_name ()));
-+                                      return false;
-+                              }
-+
-+                              prereq_class = (Class) class_or_interface;
-+                      }
-+              }
-+
-+              accept_children (analyzer);
-+
-+              analyzer.current_source_file = old_source_file;
-+              analyzer.current_symbol = old_symbol;
-+
-+              return !error;
-+      }
- }
-Index: vala/valamethod.vala
-===================================================================
---- vala/valamethod.vala       (revision 1971)
-+++ vala/valamethod.vala       (revision 2004)
-@@ -594,4 +594,152 @@
-                       }
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              process_attributes ();
-+
-+              if (is_abstract) {
-+                      if (parent_symbol is Class) {
-+                              var cl = (Class) parent_symbol;
-+                              if (!cl.is_abstract) {
-+                                      error = true;
-+                                      Report.error (source_reference, "Abstract methods may not be declared in non-abstract classes");
-+                                      return false;
-+                              }
-+                      } else if (!(parent_symbol is Interface)) {
-+                              error = true;
-+                              Report.error (source_reference, "Abstract methods may not be declared outside of classes and interfaces");
-+                              return false;
-+                      }
-+              } else if (is_virtual) {
-+                      if (!(parent_symbol is Class) && !(parent_symbol is Interface)) {
-+                              error = true;
-+                              Report.error (source_reference, "Virtual methods may not be declared outside of classes and interfaces");
-+                              return false;
-+                      }
-+
-+                      if (parent_symbol is Class) {
-+                              var cl = (Class) parent_symbol;
-+                              if (cl.is_compact) {
-+                                      Report.error (source_reference, "Virtual methods may not be declared in compact classes");
-+                                      return false;
-+                              }
-+                      }
-+              } else if (overrides) {
-+                      if (!(parent_symbol is Class)) {
-+                              error = true;
-+                              Report.error (source_reference, "Methods may not be overridden outside of classes");
-+                              return false;
-+                      }
-+              }
-+
-+              if (is_abstract && body != null) {
-+                      Report.error (source_reference, "Abstract methods cannot have bodies");
-+              } else if (external && body != null) {
-+                      Report.error (source_reference, "Extern methods cannot have bodies");
-+              } else if (!is_abstract && !external && !external_package && body == null) {
-+                      Report.error (source_reference, "Non-abstract, non-extern methods must have bodies");
-+              }
-+
-+              var old_symbol = analyzer.current_symbol;
-+              var old_return_type = analyzer.current_return_type;
-+              analyzer.current_symbol = this;
-+              analyzer.current_return_type = return_type;
-+
-+              var init_attr = get_attribute ("ModuleInit");
-+              if (init_attr != null) {
-+                      source_reference.file.context.module_init_method = this;
-+              }
-+
-+              if (!is_internal_symbol ()) {
-+                      if (return_type is ValueType) {
-+                              analyzer.current_source_file.add_type_dependency (return_type, SourceFileDependencyType.HEADER_FULL);
-+                      } else {
-+                              analyzer.current_source_file.add_type_dependency (return_type, SourceFileDependencyType.HEADER_SHALLOW);
-+                      }
-+              }
-+              analyzer.current_source_file.add_type_dependency (return_type, SourceFileDependencyType.SOURCE);
-+
-+              accept_children (analyzer);
-+
-+              analyzer.current_symbol = old_symbol;
-+              analyzer.current_return_type = old_return_type;
-+
-+              if (analyzer.current_symbol.parent_symbol is Method) {
-+                      /* lambda expressions produce nested methods */
-+                      var up_method = (Method) analyzer.current_symbol.parent_symbol;
-+                      analyzer.current_return_type = up_method.return_type;
-+              }
-+
-+              if (analyzer.current_symbol is Struct) {
-+                      if (is_abstract || is_virtual || overrides) {
-+                              Report.error (source_reference, "A struct member `%s' cannot be marked as override, virtual, or abstract".printf (get_full_name ()));
-+                              return false;
-+                      }
-+              } else if (overrides && base_method == null) {
-+                      Report.error (source_reference, "%s: no suitable method found to override".printf (get_full_name ()));
-+              }
-+
-+              // check whether return type is at least as accessible as the method
-+              if (!analyzer.is_type_accessible (this, return_type)) {
-+                      error = true;
-+                      Report.error (source_reference, "return type `%s` is less accessible than method `%s`".printf (return_type.to_string (), get_full_name ()));
-+                      return false;
-+              }
-+
-+              foreach (Expression precondition in get_preconditions ()) {
-+                      if (precondition.error) {
-+                              // if there was an error in the precondition, skip this check
-+                              error = true;
-+                              return false;
-+                      }
-+
-+                      if (!precondition.value_type.compatible (analyzer.bool_type)) {
-+                              error = true;
-+                              Report.error (precondition.source_reference, "Precondition must be boolean");
-+                              return false;
-+                      }
-+              }
-+
-+              foreach (Expression postcondition in get_postconditions ()) {
-+                      if (postcondition.error) {
-+                              // if there was an error in the postcondition, skip this check
-+                              error = true;
-+                              return false;
-+                      }
-+
-+                      if (!postcondition.value_type.compatible (analyzer.bool_type)) {
-+                              error = true;
-+                              Report.error (postcondition.source_reference, "Postcondition must be boolean");
-+                              return false;
-+                      }
-+              }
-+
-+              if (tree_can_fail && name == "main") {
-+                      Report.error (source_reference, "\"main\" method cannot throw errors");
-+              }
-+
-+              // check that all errors that can be thrown in the method body are declared
-+              if (body != null) { 
-+                      foreach (DataType body_error_type in body.get_error_types ()) {
-+                              bool can_propagate_error = false;
-+                              foreach (DataType method_error_type in get_error_types ()) {
-+                                      if (body_error_type.compatible (method_error_type)) {
-+                                              can_propagate_error = true;
-+                                      }
-+                              }
-+                              if (!can_propagate_error) {
-+                                      Report.warning (body_error_type.source_reference, "unhandled error `%s'".printf (body_error_type.to_string()));
-+                              }
-+                      }
-+              }
-+
-+              return !error;
-+      }
- }
-Index: vala/valafield.vala
-===================================================================
---- vala/valafield.vala        (revision 1971)
-+++ vala/valafield.vala        (revision 2004)
-@@ -195,4 +195,44 @@
-               }
-               attr.add_argument ("type", new StringLiteral ("\"%s\"".printf (ctype)));
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              process_attributes ();
-+
-+              if (initializer != null) {
-+                      initializer.target_type = field_type;
-+              }
-+
-+              accept_children (analyzer);
-+
-+              if (binding == MemberBinding.INSTANCE && parent_symbol is Interface) {
-+                      error = true;
-+                      Report.error (source_reference, "Interfaces may not have instance fields");
-+                      return false;
-+              }
-+
-+              if (!is_internal_symbol ()) {
-+                      if (field_type is ValueType) {
-+                              analyzer.current_source_file.add_type_dependency (field_type, SourceFileDependencyType.HEADER_FULL);
-+                      } else {
-+                              analyzer.current_source_file.add_type_dependency (field_type, SourceFileDependencyType.HEADER_SHALLOW);
-+                      }
-+              } else {
-+                      if (parent_symbol is Namespace) {
-+                              error = true;
-+                              Report.error (source_reference, "Namespaces may not have private members");
-+                              return false;
-+                      }
-+
-+                      analyzer.current_source_file.add_type_dependency (field_type, SourceFileDependencyType.SOURCE);
-+              }
-+
-+              return !error;
-+      }
- }
-Index: vala/valadostatement.vala
-===================================================================
---- vala/valadostatement.vala  (revision 1971)
-+++ vala/valadostatement.vala  (revision 2004)
-@@ -86,4 +86,31 @@
-                       condition = new_node;
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              accept_children (analyzer);
-+
-+              if (condition.error) {
-+                      /* if there was an error in the condition, skip this check */
-+                      error = true;
-+                      return false;
-+              }
-+
-+              if (!condition.value_type.compatible (analyzer.bool_type)) {
-+                      error = true;
-+                      Report.error (condition.source_reference, "Condition must be boolean");
-+                      return false;
-+              }
-+
-+              add_error_types (condition.get_error_types ());
-+              add_error_types (body.get_error_types ());
-+
-+              return !error;
-+      }
- }
-Index: vala/valanamespace.vala
-===================================================================
---- vala/valanamespace.vala    (revision 1971)
-+++ vala/valanamespace.vala    (revision 2004)
-@@ -515,4 +515,16 @@
-                       }
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              process_attributes ();
-+
-+              return !error;
-+      }
- }
-Index: vala/valawhilestatement.vala
-===================================================================
---- vala/valawhilestatement.vala       (revision 1971)
-+++ vala/valawhilestatement.vala       (revision 2004)
-@@ -86,4 +86,31 @@
-                       condition = new_node;
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              accept_children (analyzer);
-+
-+              if (condition.error) {
-+                      /* if there was an error in the condition, skip this check */
-+                      error = true;
-+                      return false;
-+              }
-+
-+              if (!condition.value_type.compatible (analyzer.bool_type)) {
-+                      error = true;
-+                      Report.error (condition.source_reference, "Condition must be boolean");
-+                      return false;
-+              }
-+
-+              add_error_types (condition.get_error_types ());
-+              add_error_types (body.get_error_types ());
-+
-+              return !error;
-+      }
- }
-Index: vala/valaconstant.vala
-===================================================================
---- vala/valaconstant.vala     (revision 1971)
-+++ vala/valaconstant.vala     (revision 2004)
-@@ -150,4 +150,29 @@
-                       }
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              process_attributes ();
-+
-+              type_reference.accept (analyzer);
-+
-+              if (!external_package) {
-+                      if (initializer == null) {
-+                              error = true;
-+                              Report.error (source_reference, "A const field requires a initializer to be provided");
-+                      } else {
-+                              initializer.target_type = type_reference;
-+
-+                              initializer.accept (analyzer);
-+                      }
-+              }
-+
-+              return !error;
-+      }
- }
-Index: vala/valadynamicproperty.vala
-===================================================================
---- vala/valadynamicproperty.vala      (revision 1971)
-+++ vala/valadynamicproperty.vala      (revision 2004)
-@@ -40,4 +40,7 @@
-               return new ArrayList<string> ();
-       }
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              return true;
-+      }
- }
-Index: vala/valaforeachstatement.vala
-===================================================================
---- vala/valaforeachstatement.vala     (revision 1971)
-+++ vala/valaforeachstatement.vala     (revision 2004)
-@@ -134,4 +134,119 @@
-                       type_reference = new_type;
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              // analyze collection expression first, used for type inference
-+              collection.accept (analyzer);
-+
-+              if (collection.error) {
-+                      // ignore inner error
-+                      error = true;
-+                      return false;
-+              } else if (collection.value_type == null) {
-+                      Report.error (collection.source_reference, "invalid collection expression");
-+                      error = true;
-+                      return false;
-+              }
-+
-+              var collection_type = collection.value_type.copy ();
-+              collection.target_type = collection_type.copy ();
-+              
-+              DataType element_data_type = null;
-+              bool element_owned = false;
-+
-+              if (collection_type.is_array ()) {
-+                      var array_type = (ArrayType) collection_type;
-+                      element_data_type = array_type.element_type;
-+              } else if (collection_type.compatible (analyzer.glist_type) || collection_type.compatible (analyzer.gslist_type)) {
-+                      if (collection_type.get_type_arguments ().size > 0) {
-+                              element_data_type = (DataType) collection_type.get_type_arguments ().get (0);
-+                      }
-+              } else if (analyzer.iterable_type != null && collection_type.compatible (analyzer.iterable_type)) {
-+                      element_owned = true;
-+
-+                      if (analyzer.list_type == null || !collection_type.compatible (new ObjectType (analyzer.list_type))) {
-+                              // don't use iterator objects for lists for performance reasons
-+                              var foreach_iterator_type = new ObjectType (analyzer.iterator_type);
-+                              foreach_iterator_type.value_owned = true;
-+                              foreach_iterator_type.add_type_argument (type_reference);
-+                              iterator_variable = new LocalVariable (foreach_iterator_type, "%s_it".printf (variable_name));
-+
-+                              add_local_variable (iterator_variable);
-+                              iterator_variable.active = true;
-+                      }
-+
-+                      var it_method = (Method) analyzer.iterable_type.data_type.scope.lookup ("iterator");
-+                      if (it_method.return_type.get_type_arguments ().size > 0) {
-+                              var type_arg = it_method.return_type.get_type_arguments ().get (0);
-+                              if (type_arg.type_parameter != null) {
-+                                      element_data_type = SemanticAnalyzer.get_actual_type (collection_type, it_method, type_arg, this);
-+                              } else {
-+                                      element_data_type = type_arg;
-+                              }
-+                      }
-+              } else {
-+                      error = true;
-+                      Report.error (source_reference, "Gee.List not iterable");
-+                      return false;
-+              }
-+
-+              if (element_data_type == null) {
-+                      error = true;
-+                      Report.error (collection.source_reference, "missing type argument for collection");
-+                      return false;
-+              }
-+
-+              // analyze element type
-+              if (type_reference == null) {
-+                      // var type
-+                      type_reference = element_data_type.copy ();
-+              } else if (!element_data_type.compatible (type_reference)) {
-+                      error = true;
-+                      Report.error (source_reference, "Foreach: Cannot convert from `%s' to `%s'".printf (element_data_type.to_string (), type_reference.to_string ()));
-+                      return false;
-+              } else if (element_data_type.is_disposable () && element_owned && !type_reference.value_owned) {
-+                      error = true;
-+                      Report.error (source_reference, "Foreach: Invalid assignment from owned expression to unowned variable");
-+                      return false;
-+              }
-+              
-+              analyzer.current_source_file.add_type_dependency (type_reference, SourceFileDependencyType.SOURCE);
-+
-+              element_variable = new LocalVariable (type_reference, variable_name);
-+
-+              body.scope.add (variable_name, element_variable);
-+
-+              body.add_local_variable (element_variable);
-+              element_variable.active = true;
-+
-+              // analyze body
-+              owner = analyzer.current_symbol.scope;
-+              analyzer.current_symbol = this;
-+
-+              body.accept (analyzer);
-+
-+              foreach (LocalVariable local in get_local_variables ()) {
-+                      local.active = false;
-+              }
-+
-+              analyzer.current_symbol = analyzer.current_symbol.parent_symbol;
-+
-+              collection_variable = new LocalVariable (collection_type, "%s_collection".printf (variable_name));
-+
-+              add_local_variable (collection_variable);
-+              collection_variable.active = true;
-+
-+
-+              add_error_types (collection.get_error_types ());
-+              add_error_types (body.get_error_types ());
-+
-+              return !error;
-+      }
- }
-Index: vala/valadeclarationstatement.vala
-===================================================================
---- vala/valadeclarationstatement.vala (revision 1971)
-+++ vala/valadeclarationstatement.vala (revision 2004)
-@@ -48,4 +48,25 @@
-       
-               visitor.visit_declaration_statement (this);
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              var local = declaration as LocalVariable;
-+              if (local != null && local.initializer != null) {
-+                      foreach (DataType error_type in local.initializer.get_error_types ()) {
-+                              // ensure we can trace back which expression may throw errors of this type
-+                              var initializer_error_type = error_type.copy ();
-+                              initializer_error_type.source_reference = local.initializer.source_reference;
-+
-+                              add_error_type (initializer_error_type);
-+                      }
-+              }
-+
-+              return !error;
-+      }
- }
-Index: vala/valaelementaccess.vala
-===================================================================
---- vala/valaelementaccess.vala        (revision 1971)
-+++ vala/valaelementaccess.vala        (revision 2004)
-@@ -85,4 +85,127 @@
-               }
-               return container.is_pure ();
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              container.accept (analyzer);
-+
-+              if (container.value_type == null) {
-+                      /* don't proceed if a child expression failed */
-+                      error = true;
-+                      return false;
-+              }
-+
-+              var container_type = container.value_type.data_type;
-+
-+              if (container is MemberAccess && container.symbol_reference is Signal) {
-+                      // signal detail access
-+                      if (get_indices ().size != 1) {
-+                              error = true;
-+                              Report.error (source_reference, "Element access with more than one dimension is not supported for signals");
-+                              return false;
-+                      }
-+                      get_indices ().get (0).target_type = analyzer.string_type.copy ();
-+              }
-+
-+              foreach (Expression index in get_indices ()) {
-+                      index.accept (analyzer);
-+              }
-+
-+              bool index_int_type_check = true;
-+
-+              var pointer_type = container.value_type as PointerType;
-+
-+              /* assign a value_type when possible */
-+              if (container.value_type is ArrayType) {
-+                      var array_type = (ArrayType) container.value_type;
-+                      value_type = array_type.element_type.copy ();
-+                      if (!lvalue) {
-+                              value_type.value_owned = false;
-+                      }
-+              } else if (pointer_type != null && !pointer_type.base_type.is_reference_type_or_type_parameter ()) {
-+                      value_type = pointer_type.base_type.copy ();
-+              } else if (container_type == analyzer.string_type.data_type) {
-+                      if (get_indices ().size != 1) {
-+                              error = true;
-+                              Report.error (source_reference, "Element access with more than one dimension is not supported for strings");
-+                              return false;
-+                      }
-+
-+                      value_type = analyzer.unichar_type;
-+              } else if (container_type != null && analyzer.list_type != null && analyzer.map_type != null &&
-+                         (container_type.is_subtype_of (analyzer.list_type) || container_type.is_subtype_of (analyzer.map_type))) {
-+                      Gee.List<Expression> indices = get_indices ();
-+                      if (indices.size != 1) {
-+                              error = true;
-+                              Report.error (source_reference, "Element access with more than one dimension is not supported for the specified type");
-+                              return false;
-+                      }
-+                      Iterator<Expression> indices_it = indices.iterator ();
-+                      indices_it.next ();
-+                      var index = indices_it.get ();
-+                      index_int_type_check = false;
-+
-+                      // lookup symbol in interface instead of class as implemented interface methods are not in VAPI files
-+                      Symbol get_sym = null;
-+                      if (container_type.is_subtype_of (analyzer.list_type)) {
-+                              get_sym = analyzer.list_type.scope.lookup ("get");
-+                      } else if (container_type.is_subtype_of (analyzer.map_type)) {
-+                              get_sym = analyzer.map_type.scope.lookup ("get");
-+                      }
-+                      var get_method = (Method) get_sym;
-+                      Gee.List<FormalParameter> get_params = get_method.get_parameters ();
-+                      Iterator<FormalParameter> get_params_it = get_params.iterator ();
-+                      get_params_it.next ();
-+                      var get_param = get_params_it.get ();
-+
-+                      var index_type = get_param.parameter_type;
-+                      if (index_type.type_parameter != null) {
-+                              index_type = analyzer.get_actual_type (container.value_type, get_method, get_param.parameter_type, this);
-+                      }
-+
-+                      if (!index.value_type.compatible (index_type)) {
-+                              error = true;
-+                              Report.error (source_reference, "index expression: Cannot convert from `%s' to `%s'".printf (index.value_type.to_string (), index_type.to_string ()));
-+                              return false;
-+                      }
-+
-+                      value_type = analyzer.get_actual_type (container.value_type, get_method, get_method.return_type, this).copy ();
-+                      if (lvalue) {
-+                              // get () returns owned value, set () accepts unowned value
-+                              value_type.value_owned = false;
-+                      }
-+              } else if (container is MemberAccess && container.symbol_reference is Signal) {
-+                      index_int_type_check = false;
-+
-+                      symbol_reference = container.symbol_reference;
-+                      value_type = container.value_type;
-+              } else {
-+                      error = true;
-+                      Report.error (source_reference, "The expression `%s' does not denote an Array".printf (container.value_type.to_string ()));
-+              }
-+
-+              if (index_int_type_check) {
-+                      /* check if the index is of type integer */
-+                      foreach (Expression e in get_indices ()) {
-+                              /* don't proceed if a child expression failed */
-+                              if (e.value_type == null) {
-+                                      return false;
-+                              }
-+
-+                              /* check if the index is of type integer */
-+                              if (!(e.value_type.data_type is Struct) || !((Struct) e.value_type.data_type).is_integer_type ()) {
-+                                      error = true;
-+                                      Report.error (e.source_reference, "Expression of integer type expected");
-+                              }
-+                      }
-+              }
-+
-+              return !error;
-+      }
- }
-Index: vala/valacatchclause.vala
-===================================================================
---- vala/valacatchclause.vala  (revision 1971)
-+++ vala/valacatchclause.vala  (revision 2004)
-@@ -1,4 +1,4 @@
--/* valacatchclause.vala
-+/* valacatchvala
-  *
-  * Copyright (C) 2007-2008  Jürg Billeter
-  *
-@@ -62,7 +62,7 @@
-       private DataType _data_type;
-       /**
--       * Creates a new catch clause.
-+       * Creates a new catch 
-        *
-        * @param type_reference   error type
-        * @param variable_name    error variable name
-@@ -94,4 +94,27 @@
-                       error_type = new_type;
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              if (error_type != null) {
-+                      analyzer.current_source_file.add_type_dependency (error_type, SourceFileDependencyType.SOURCE);
-+
-+                      error_variable = new LocalVariable (error_type.copy (), variable_name);
-+
-+                      body.scope.add (variable_name, error_variable);
-+                      body.add_local_variable (error_variable);
-+              } else {
-+                      error_type = new ErrorType (null, null, source_reference);
-+              }
-+
-+              accept_children (analyzer);
-+
-+              return !error;
-+      }
- }
-Index: vala/valainitializerlist.vala
-===================================================================
---- vala/valainitializerlist.vala      (revision 1971)
-+++ vala/valainitializerlist.vala      (revision 2004)
-@@ -1,4 +1,4 @@
--/* valainitializerlist.vala
-+/* valainitializervala
-  *
-  * Copyright (C) 2006-2008  Jürg Billeter, Raffaele Sandrini
-  *
-@@ -31,7 +31,7 @@
-       private Gee.List<Expression> initializers = new ArrayList<Expression> ();
-       
-       /**
--       * Appends the specified expression to this initializer list.
-+       * Appends the specified expression to this initializer 
-        *
-        * @param expr an expression
-        */
-@@ -41,7 +41,7 @@
-       }
-       
-       /**
--       * Returns a copy of the expression list.
-+       * Returns a copy of the expression 
-        *
-        * @return expression list
-        */
-@@ -50,14 +50,14 @@
-       }
-       /**
--       * Returns the initializer count in this initializer list.
-+       * Returns the initializer count in this initializer 
-        */
-       public int size {
-               get { return initializers.size; }
-       }
-       /**
--       * Creates a new initializer list.
-+       * Creates a new initializer 
-        *
-        * @param source_reference reference to source code
-        * @return                 newly created initializer list
-@@ -92,4 +92,80 @@
-                       }
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              if (target_type == null) {
-+                      error = true;
-+                      Report.error (source_reference, "initializer list used for unknown type");
-+                      return false;
-+              } else if (target_type is ArrayType) {
-+                      /* initializer is used as array initializer */
-+                      var array_type = (ArrayType) target_type;
-+
-+                      foreach (Expression e in get_initializers ()) {
-+                              e.target_type = array_type.element_type.copy ();
-+                      }
-+              } else if (target_type.data_type is Struct) {
-+                      /* initializer is used as struct initializer */
-+                      var st = (Struct) target_type.data_type;
-+
-+                      var field_it = st.get_fields ().iterator ();
-+                      foreach (Expression e in get_initializers ()) {
-+                              Field field = null;
-+                              while (field == null) {
-+                                      if (!field_it.next ()) {
-+                                              error = true;
-+                                              Report.error (e.source_reference, "too many expressions in initializer list for `%s'".printf (target_type.to_string ()));
-+                                              return false;
-+                                      }
-+                                      field = field_it.get ();
-+                                      if (field.binding != MemberBinding.INSTANCE) {
-+                                              // we only initialize instance fields
-+                                              field = null;
-+                                      }
-+                              }
-+
-+                              e.target_type = field.field_type.copy ();
-+                              if (!target_type.value_owned) {
-+                                      e.target_type.value_owned = false;
-+                              }
-+                      }
-+              } else {
-+                      error = true;
-+                      Report.error (source_reference, "initializer list used for `%s', which is neither array nor struct".printf (target_type.to_string ()));
-+                      return false;
-+              }
-+
-+              accept_children (analyzer);
-+
-+              bool error = false;
-+              foreach (Expression e in get_initializers ()) {
-+                      if (e.value_type == null) {
-+                              error = true;
-+                              continue;
-+                      }
-+
-+                      var unary = e as UnaryExpression;
-+                      if (unary != null && (unary.operator == UnaryOperator.REF || unary.operator == UnaryOperator.OUT)) {
-+                              // TODO check type for ref and out expressions
-+                      } else if (!e.value_type.compatible (e.target_type)) {
-+                              error = true;
-+                              e.error = true;
-+                              Report.error (e.source_reference, "Expected initializer of type `%s' but got `%s'".printf (e.target_type.to_string (), e.value_type.to_string ()));
-+                      }
-+              }
-+
-+              if (!error) {
-+                      /* everything seems to be correct */
-+                      value_type = target_type;
-+              }
-+
-+              return !error;
-+      }
- }
-Index: vala/valaproperty.vala
-===================================================================
---- vala/valaproperty.vala     (revision 1971)
-+++ vala/valaproperty.vala     (revision 2004)
-@@ -34,7 +34,9 @@
-               get { return _data_type; }
-               set {
-                       _data_type = value;
--                      _data_type.parent_node = this;
-+                      if (value != null) {
-+                              _data_type.parent_node = this;
-+                      }
-               }
-       }
-       
-@@ -409,6 +411,8 @@
-               checked = true;
-+              process_attributes ();
-+
-               var old_source_file = analyzer.current_source_file;
-               var old_symbol = analyzer.current_symbol;
-Index: vala/valaerrorcode.vala
-===================================================================
---- vala/valaerrorcode.vala    (revision 1971)
-+++ vala/valaerrorcode.vala    (revision 2004)
-@@ -72,4 +72,16 @@
-               }
-               return cname;
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              accept_children (analyzer);
-+
-+              return !error;
-+      }
- }
-Index: vala/valaformalparameter.vala
-===================================================================
---- vala/valaformalparameter.vala      (revision 1971)
-+++ vala/valaformalparameter.vala      (revision 2004)
-@@ -174,6 +174,8 @@
-               checked = true;
-+              process_attributes ();
-+
-               var old_source_file = analyzer.current_source_file;
-               var old_symbol = analyzer.current_symbol;
-Index: vala/valadeletestatement.vala
-===================================================================
---- vala/valadeletestatement.vala      (revision 1971)
-+++ vala/valadeletestatement.vala      (revision 2004)
-@@ -43,4 +43,26 @@
-       public override void accept_children (CodeVisitor visitor) {
-               expression.accept (visitor);
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              accept_children (analyzer);
-+
-+              if (expression.error) {
-+                      // if there was an error in the inner expression, skip this check
-+                      return false;
-+              }
-+
-+              if (!(expression.value_type is PointerType)) {
-+                      error = true;
-+                      Report.error (source_reference, "delete operator not supported for `%s'".printf (expression.value_type.to_string ()));
-+              }
-+
-+              return !error;
-+      }
- }
-Index: vala/valadestructor.vala
-===================================================================
---- vala/valadestructor.vala   (revision 1971)
-+++ vala/valadestructor.vala   (revision 2004)
-@@ -60,4 +60,21 @@
-                       body.accept (visitor);
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              owner = analyzer.current_symbol.scope;
-+              analyzer.current_symbol = this;
-+
-+              accept_children (analyzer);
-+
-+              analyzer.current_symbol = analyzer.current_symbol.parent_symbol;
-+
-+              return !error;
-+      }
- }
-Index: vala/valaassignment.vala
-===================================================================
---- vala/valaassignment.vala   (revision 1971)
-+++ vala/valaassignment.vala   (revision 2004)
-@@ -1,6 +1,6 @@
- /* valaassignment.vala
-  *
-- * Copyright (C) 2006-2007  Jürg Billeter
-+ * Copyright (C) 2006-2008  Jürg Billeter
-  *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Lesser General Public
-@@ -97,6 +97,289 @@
-       public override bool is_pure () {
-               return false;
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              left.lvalue = true;
-+
-+              left.accept (analyzer);
-+
-+              if (left.error) {
-+                      // skip on error in inner expression
-+                      error = true;
-+                      return false;
-+              }
-+
-+              if (left is MemberAccess) {
-+                      var ma = (MemberAccess) left;
-+
-+                      if (!(ma.symbol_reference is Signal || ma.symbol_reference is DynamicProperty) && ma.value_type == null) {
-+                              error = true;
-+                              Report.error (source_reference, "unsupported lvalue in assignment");
-+                              return false;
-+                      }
-+                      if (ma.prototype_access) {
-+                              error = true;
-+                              Report.error (source_reference, "Access to instance member `%s' denied".printf (ma.symbol_reference.get_full_name ()));
-+                              return false;
-+                      }
-+
-+                      if (ma.error || ma.symbol_reference == null) {
-+                              error = true;
-+                              /* if no symbol found, skip this check */
-+                              return false;
-+                      }
-+
-+                      if (ma.symbol_reference is DynamicSignal) {
-+                              // target_type not available for dynamic signals
-+                      } else if (ma.symbol_reference is Signal) {
-+                              var sig = (Signal) ma.symbol_reference;
-+                              right.target_type = new DelegateType (sig.get_delegate (ma.inner.value_type));
-+                      } else {
-+                              right.target_type = ma.value_type;
-+                      }
-+              } else if (left is ElementAccess) {
-+                      var ea = (ElementAccess) left;
-+
-+                      if (ea.container is MemberAccess && ea.container.symbol_reference is Signal) {
-+                              var ma = (MemberAccess) ea.container;
-+                              var sig = (Signal) ea.container.symbol_reference;
-+                              right.target_type = new DelegateType (sig.get_delegate (ma.inner.value_type));
-+                      } else {
-+                              right.target_type = left.value_type;
-+                      }
-+              } else if (left is PointerIndirection) {
-+                      right.target_type = left.value_type;
-+              } else {
-+                      error = true;
-+                      Report.error (source_reference, "unsupported lvalue in assignment");
-+                      return false;
-+              }
-+
-+              right.accept (analyzer);
-+
-+              if (right.error) {
-+                      // skip on error in inner expression
-+                      error = true;
-+                      return false;
-+              }
-+
-+              if (operator != AssignmentOperator.SIMPLE && left is MemberAccess) {
-+                      // transform into simple assignment
-+                      // FIXME: only do this if the backend doesn't support
-+                      // the assignment natively
-+
-+                      var ma = (MemberAccess) left;
-+
-+                      if (!(ma.symbol_reference is Signal)) {
-+                              var old_value = new MemberAccess (ma.inner, ma.member_name);
-+
-+                              var bin = new BinaryExpression (BinaryOperator.PLUS, old_value, new ParenthesizedExpression (right, right.source_reference));
-+                              bin.target_type = right.target_type;
-+                              right.target_type = right.target_type.copy ();
-+                              right.target_type.value_owned = false;
-+
-+                              if (operator == AssignmentOperator.BITWISE_OR) {
-+                                      bin.operator = BinaryOperator.BITWISE_OR;
-+                              } else if (operator == AssignmentOperator.BITWISE_AND) {
-+                                      bin.operator = BinaryOperator.BITWISE_AND;
-+                              } else if (operator == AssignmentOperator.BITWISE_XOR) {
-+                                      bin.operator = BinaryOperator.BITWISE_XOR;
-+                              } else if (operator == AssignmentOperator.ADD) {
-+                                      bin.operator = BinaryOperator.PLUS;
-+                              } else if (operator == AssignmentOperator.SUB) {
-+                                      bin.operator = BinaryOperator.MINUS;
-+                              } else if (operator == AssignmentOperator.MUL) {
-+                                      bin.operator = BinaryOperator.MUL;
-+                              } else if (operator == AssignmentOperator.DIV) {
-+                                      bin.operator = BinaryOperator.DIV;
-+                              } else if (operator == AssignmentOperator.PERCENT) {
-+                                      bin.operator = BinaryOperator.MOD;
-+                              } else if (operator == AssignmentOperator.SHIFT_LEFT) {
-+                                      bin.operator = BinaryOperator.SHIFT_LEFT;
-+                              } else if (operator == AssignmentOperator.SHIFT_RIGHT) {
-+                                      bin.operator = BinaryOperator.SHIFT_RIGHT;
-+                              }
-+
-+                              right = bin;
-+                              right.accept (analyzer);
-+
-+                              operator = AssignmentOperator.SIMPLE;
-+                      }
-+              }
-+
-+              if (left.symbol_reference is Signal) {
-+                      var sig = (Signal) left.symbol_reference;
-+
-+                      var m = right.symbol_reference as Method;
-+
-+                      if (m == null) {
-+                              error = true;
-+                              Report.error (right.source_reference, "unsupported expression for signal handler");
-+                              return false;
-+                      }
-+
-+                      var dynamic_sig = sig as DynamicSignal;
-+                      if (dynamic_sig != null) {
-+                              bool first = true;
-+                              foreach (FormalParameter param in dynamic_sig.handler.value_type.get_parameters ()) {
-+                                      if (first) {
-+                                              // skip sender parameter
-+                                              first = false;
-+                                      } else {
-+                                              dynamic_sig.add_parameter (param.copy ());
-+                                      }
-+                              }
-+                              right.target_type = new DelegateType (sig.get_delegate (new ObjectType ((ObjectTypeSymbol) sig.parent_symbol)));
-+                      } else if (!right.value_type.compatible (right.target_type)) {
-+                              var delegate_type = (DelegateType) right.target_type;
-+
-+                              error = true;
-+                              Report.error (right.source_reference, "method `%s' is incompatible with signal `%s', expected `%s'".printf (right.value_type.to_string (), right.target_type.to_string (), delegate_type.delegate_symbol.get_prototype_string (m.name)));
-+                              return false;
-+                      }
-+              } else if (left is MemberAccess) {
-+                      var ma = (MemberAccess) left;
-+
-+                      if (ma.symbol_reference is Property) {
-+                              var prop = (Property) ma.symbol_reference;
-+
-+                              var dynamic_prop = prop as DynamicProperty;
-+                              if (dynamic_prop != null) {
-+                                      dynamic_prop.property_type = right.value_type.copy ();
-+                                      left.value_type = dynamic_prop.property_type.copy ();
-+                              }
-+
-+                              if (prop.set_accessor == null
-+                                  || (!prop.set_accessor.writable && !(analyzer.find_current_method () is CreationMethod || analyzer.is_in_constructor ()))) {
-+                                      ma.error = true;
-+                                      Report.error (ma.source_reference, "Property `%s' is read-only".printf (prop.get_full_name ()));
-+                                      return false;
-+                              }
-+                      } else if (ma.symbol_reference is LocalVariable && right.value_type == null) {
-+                              var local = (LocalVariable) ma.symbol_reference;
-+
-+                              if (right.symbol_reference is Method &&
-+                                  local.variable_type is DelegateType) {
-+                                      var m = (Method) right.symbol_reference;
-+                                      var dt = (DelegateType) local.variable_type;
-+                                      var cb = dt.delegate_symbol;
-+
-+                                      /* check whether method matches callback type */
-+                                      if (!cb.matches_method (m)) {
-+                                              error = true;
-+                                              Report.error (source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.get_full_name (), cb.get_full_name ()));
-+                                              return false;
-+                                      }
-+
-+                                      right.value_type = local.variable_type;
-+                              } else {
-+                                      error = true;
-+                                      Report.error (source_reference, "Assignment: Invalid callback assignment attempt");
-+                                      return false;
-+                              }
-+                      } else if (ma.symbol_reference is Field && right.value_type == null) {
-+                              var f = (Field) ma.symbol_reference;
-+
-+                              if (right.symbol_reference is Method &&
-+                                  f.field_type is DelegateType) {
-+                                      var m = (Method) right.symbol_reference;
-+                                      var dt = (DelegateType) f.field_type;
-+                                      var cb = dt.delegate_symbol;
-+
-+                                      /* check whether method matches callback type */
-+                                      if (!cb.matches_method (m)) {
-+                                              f.error = true;
-+                                              Report.error (source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.get_full_name (), cb.get_full_name ()));
-+                                              return false;
-+                                      }
-+
-+                                      right.value_type = f.field_type;
-+                              } else {
-+                                      error = true;
-+                                      Report.error (source_reference, "Assignment: Invalid callback assignment attempt");
-+                                      return false;
-+                              }
-+                      } else if (left.value_type != null && right.value_type != null) {
-+                              /* if there was an error on either side,
-+                               * i.e. {left|right}.value_type == null, skip type check */
-+
-+                              if (!right.value_type.compatible (left.value_type)) {
-+                                      error = true;
-+                                      Report.error (source_reference, "Assignment: Cannot convert from `%s' to `%s'".printf (right.value_type.to_string (), left.value_type.to_string ()));
-+                                      return false;
-+                              }
-+
-+                              if (right.value_type.is_disposable ()) {
-+                                      /* rhs transfers ownership of the expression */
-+                                      if (!(left.value_type is PointerType) && !left.value_type.value_owned) {
-+                                              /* lhs doesn't own the value */
-+                                              error = true;
-+                                              Report.error (source_reference, "Invalid assignment from owned expression to unowned variable");
-+                                      }
-+                              } else if (left.value_type.value_owned) {
-+                                      /* lhs wants to own the value
-+                                       * rhs doesn't transfer the ownership
-+                                       * code generator needs to add reference
-+                                       * increment calls */
-+                              }
-+                      }
-+              } else if (left is ElementAccess) {
-+                      var ea = (ElementAccess) left;
-+
-+                      if (!right.value_type.compatible (left.value_type)) {
-+                              error = true;
-+                              Report.error (source_reference, "Assignment: Cannot convert from `%s' to `%s'".printf (right.value_type.to_string (), left.value_type.to_string ()));
-+                              return false;
-+                      }
-+
-+                      if (right.value_type.is_disposable ()) {
-+                              /* rhs transfers ownership of the expression */
-+
-+                              DataType element_type;
-+
-+                              if (ea.container.value_type is ArrayType) {
-+                                      var array_type = (ArrayType) ea.container.value_type;
-+                                      element_type = array_type.element_type;
-+                              } else {
-+                                      var args = ea.container.value_type.get_type_arguments ();
-+                                      assert (args.size == 1);
-+                                      element_type = args.get (0);
-+                              }
-+
-+                              if (!(element_type is PointerType) && !element_type.value_owned) {
-+                                      /* lhs doesn't own the value */
-+                                      error = true;
-+                                      Report.error (source_reference, "Invalid assignment from owned expression to unowned variable");
-+                                      return false;
-+                              }
-+                      } else if (left.value_type.value_owned) {
-+                              /* lhs wants to own the value
-+                               * rhs doesn't transfer the ownership
-+                               * code generator needs to add reference
-+                               * increment calls */
-+                      }
-+              } else {
-+                      return false;
-+              }
-+
-+              if (left.value_type != null) {
-+                      value_type = left.value_type.copy ();
-+                      value_type.value_owned = false;
-+              } else {
-+                      value_type = null;
-+              }
-+
-+              add_error_types (left.get_error_types ());
-+              add_error_types (right.get_error_types ());
-+
-+              return !error;
-+      }
- }
-       
- public enum Vala.AssignmentOperator {
-Index: vala/valalockstatement.vala
-===================================================================
---- vala/valalockstatement.vala        (revision 1971)
-+++ vala/valalockstatement.vala        (revision 2004)
-@@ -47,4 +47,31 @@
-               body.accept (visitor);
-               visitor.visit_lock_statement (this);
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              /* resource must be a member access and denote a Lockable */
-+              if (!(resource is MemberAccess && resource.symbol_reference is Lockable)) {
-+                      error = true;
-+                      resource.error = true;
-+                      Report.error (resource.source_reference, "Expression is either not a member access or does not denote a lockable member");
-+                      return false;
-+              }
-+
-+              /* parent symbol must be the current class */
-+              if (resource.symbol_reference.parent_symbol != analyzer.current_class) {
-+                      error = true;
-+                      resource.error = true;
-+                      Report.error (resource.source_reference, "Only members of the current class are lockable");
-+              }
-+
-+              ((Lockable) resource.symbol_reference).set_lock_used (true);
-+
-+              return !error;
-+      }
- }
-Index: vala/valathrowstatement.vala
-===================================================================
---- vala/valathrowstatement.vala       (revision 1971)
-+++ vala/valathrowstatement.vala       (revision 2004)
-@@ -72,4 +72,24 @@
-                       error_expression = new_node;
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              error_expression.target_type = new ErrorType (null, null, source_reference);
-+              error_expression.target_type.value_owned = true;
-+
-+              accept_children (analyzer);
-+
-+              var error_type = error_expression.value_type.copy ();
-+              error_type.source_reference = source_reference;
-+
-+              add_error_type (error_type);
-+
-+              return !error;
-+      }
- }
-Index: vala/valamemberaccess.vala
-===================================================================
---- vala/valamemberaccess.vala (revision 1971)
-+++ vala/valamemberaccess.vala (revision 2004)
-@@ -174,4 +174,355 @@
-                       return false;
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              Symbol base_symbol = null;
-+              FormalParameter this_parameter = null;
-+              bool may_access_instance_members = false;
-+
-+              symbol_reference = null;
-+
-+              if (qualified) {
-+                      base_symbol = analyzer.root_symbol;
-+                      symbol_reference = analyzer.root_symbol.scope.lookup (member_name);
-+              } else if (inner == null) {
-+                      if (member_name == "this") {
-+                              if (!analyzer.is_in_instance_method ()) {
-+                                      error = true;
-+                                      Report.error (source_reference, "This access invalid outside of instance methods");
-+                                      return false;
-+                              }
-+                      }
-+
-+                      base_symbol = analyzer.current_symbol;
-+
-+                      var sym = analyzer.current_symbol;
-+                      while (sym != null && symbol_reference == null) {
-+                              if (this_parameter == null) {
-+                                      if (sym is CreationMethod) {
-+                                              var cm = (CreationMethod) sym;
-+                                              this_parameter = cm.this_parameter;
-+                                              may_access_instance_members = true;
-+                                      } else if (sym is Property) {
-+                                              var prop = (Property) sym;
-+                                              this_parameter = prop.this_parameter;
-+                                              may_access_instance_members = true;
-+                                      } else if (sym is Constructor) {
-+                                              var c = (Constructor) sym;
-+                                              this_parameter = c.this_parameter;
-+                                              may_access_instance_members = true;
-+                                      } else if (sym is Destructor) {
-+                                              var d = (Destructor) sym;
-+                                              this_parameter = d.this_parameter;
-+                                              may_access_instance_members = true;
-+                                      } else if (sym is Method) {
-+                                              var m = (Method) sym;
-+                                              this_parameter = m.this_parameter;
-+                                              may_access_instance_members = (m.binding == MemberBinding.INSTANCE);
-+                                      }
-+                              }
-+
-+                              symbol_reference = analyzer.symbol_lookup_inherited (sym, member_name);
-+                              sym = sym.parent_symbol;
-+                      }
-+
-+                      if (symbol_reference == null) {
-+                              foreach (UsingDirective ns in analyzer.current_source_file.get_using_directives ()) {
-+                                      var local_sym = ns.namespace_symbol.scope.lookup (member_name);
-+                                      if (local_sym != null) {
-+                                              if (symbol_reference != null) {
-+                                                      error = true;
-+                                                      Report.error (source_reference, "`%s' is an ambiguous reference between `%s' and `%s'".printf (member_name, symbol_reference.get_full_name (), local_sym.get_full_name ()));
-+                                                      return false;
-+                                              }
-+                                              symbol_reference = local_sym;
-+                                      }
-+                              }
-+                      }
-+              } else {
-+                      if (inner.error) {
-+                              /* if there was an error in the inner expression, skip this check */
-+                              error = true;
-+                              return false;
-+                      }
-+
-+                      if (pointer_member_access) {
-+                              var pointer_type = inner.value_type as PointerType;
-+                              if (pointer_type != null && pointer_type.base_type is ValueType) {
-+                                      // transform foo->bar to (*foo).bar
-+                                      inner = new PointerIndirection (inner, source_reference);
-+                                      inner.accept (analyzer);
-+                                      pointer_member_access = false;
-+                              }
-+                      }
-+
-+                      if (inner is MemberAccess) {
-+                              var ma = (MemberAccess) inner;
-+                              if (ma.prototype_access) {
-+                                      error = true;
-+                                      Report.error (source_reference, "Access to instance member `%s' denied".printf (inner.symbol_reference.get_full_name ()));
-+                                      return false;
-+                              }
-+                      }
-+
-+                      if (inner is MemberAccess || inner is BaseAccess) {
-+                              base_symbol = inner.symbol_reference;
-+
-+                              if (symbol_reference == null && (base_symbol is Namespace || base_symbol is TypeSymbol)) {
-+                                      symbol_reference = base_symbol.scope.lookup (member_name);
-+                                      if (inner is BaseAccess) {
-+                                              // inner expression is base access
-+                                              // access to instance members of the base type possible
-+                                              may_access_instance_members = true;
-+                                      }
-+                              }
-+                      }
-+
-+                      if (symbol_reference == null && inner.value_type != null) {
-+                              if (pointer_member_access) {
-+                                      symbol_reference = inner.value_type.get_pointer_member (member_name);
-+                              } else {
-+                                      if (inner.value_type.data_type != null) {
-+                                              base_symbol = inner.value_type.data_type;
-+                                      }
-+                                      symbol_reference = inner.value_type.get_member (member_name);
-+                              }
-+                              if (symbol_reference != null) {
-+                                      // inner expression is variable, field, or parameter
-+                                      // access to instance members of the corresponding type possible
-+                                      may_access_instance_members = true;
-+                              }
-+                      }
-+
-+                      if (symbol_reference == null && inner.value_type != null && inner.value_type.is_dynamic) {
-+                              // allow late bound members for dynamic types
-+                              var dynamic_object_type = (ObjectType) inner.value_type;
-+                              if (parent_node is InvocationExpression) {
-+                                      var invoc = (InvocationExpression) parent_node;
-+                                      if (invoc.call == this) {
-+                                              // dynamic method
-+                                              DataType ret_type;
-+                                              if (invoc.target_type != null) {
-+                                                      ret_type = invoc.target_type.copy ();
-+                                                      ret_type.value_owned = true;
-+                                              } else if (invoc.parent_node is ExpressionStatement) {
-+                                                      ret_type = new VoidType ();
-+                                              } else {
-+                                                      // expect dynamic object of the same type
-+                                                      ret_type = inner.value_type.copy ();
-+                                              }
-+                                              var m = new DynamicMethod (inner.value_type, member_name, ret_type, source_reference);
-+                                              m.invocation = invoc;
-+                                              m.add_error_type (new ErrorType (null, null));
-+                                              m.access = SymbolAccessibility.PUBLIC;
-+                                              m.add_parameter (new FormalParameter.with_ellipsis ());
-+                                              dynamic_object_type.type_symbol.scope.add (null, m);
-+                                              symbol_reference = m;
-+                                      }
-+                              } else if (parent_node is Assignment) {
-+                                      var a = (Assignment) parent_node;
-+                                      if (a.left == this
-+                                          && (a.operator == AssignmentOperator.ADD
-+                                              || a.operator == AssignmentOperator.SUB)) {
-+                                              // dynamic signal
-+                                              var s = new DynamicSignal (inner.value_type, member_name, new VoidType (), source_reference);
-+                                              s.handler = a.right;
-+                                              s.access = SymbolAccessibility.PUBLIC;
-+                                              dynamic_object_type.type_symbol.scope.add (null, s);
-+                                              symbol_reference = s;
-+                                      } else if (a.left == this) {
-+                                              // dynamic property assignment
-+                                              var prop = new DynamicProperty (inner.value_type, member_name, source_reference);
-+                                              prop.access = SymbolAccessibility.PUBLIC;
-+                                              prop.set_accessor = new PropertyAccessor (false, true, false, null, prop.source_reference);
-+                                              prop.set_accessor.access = SymbolAccessibility.PUBLIC;
-+                                              prop.owner = inner.value_type.data_type.scope;
-+                                              dynamic_object_type.type_symbol.scope.add (null, prop);
-+                                              symbol_reference = prop;
-+                                      }
-+                              }
-+                              if (symbol_reference == null) {
-+                                      // dynamic property read access
-+                                      var prop = new DynamicProperty (inner.value_type, member_name, source_reference);
-+                                      if (target_type != null) {
-+                                              prop.property_type = target_type;
-+                                      } else {
-+                                              // expect dynamic object of the same type
-+                                              prop.property_type = inner.value_type.copy ();
-+                                      }
-+                                      prop.access = SymbolAccessibility.PUBLIC;
-+                                      prop.get_accessor = new PropertyAccessor (true, false, false, null, prop.source_reference);
-+                                      prop.get_accessor.access = SymbolAccessibility.PUBLIC;
-+                                      prop.owner = inner.value_type.data_type.scope;
-+                                      dynamic_object_type.type_symbol.scope.add (null, prop);
-+                                      symbol_reference = prop;
-+                              }
-+                              if (symbol_reference != null) {
-+                                      may_access_instance_members = true;
-+                              }
-+                      }
-+              }
-+
-+              if (symbol_reference == null) {
-+                      error = true;
-+
-+                      string base_type_name = "(null)";
-+                      if (inner != null && inner.value_type != null) {
-+                              base_type_name = inner.value_type.to_string ();
-+                      } else if (base_symbol != null) {
-+                              base_type_name = base_symbol.get_full_name ();
-+                      }
-+
-+                      Report.error (source_reference, "The name `%s' does not exist in the context of `%s'".printf (member_name, base_type_name));
-+                      return false;
-+              }
-+
-+              var member = symbol_reference;
-+              var access = SymbolAccessibility.PUBLIC;
-+              bool instance = false;
-+              bool klass = false;
-+              if (member is Field) {
-+                      var f = (Field) member;
-+                      access = f.access;
-+                      instance = (f.binding == MemberBinding.INSTANCE);
-+                      klass = (f.binding == MemberBinding.CLASS);
-+              } else if (member is Method) {
-+                      var m = (Method) member;
-+                      access = m.access;
-+                      if (!(m is CreationMethod)) {
-+                              instance = (m.binding == MemberBinding.INSTANCE);
-+                      }
-+                      klass = (m.binding == MemberBinding.CLASS);
-+              } else if (member is Property) {
-+                      var prop = (Property) member;
-+                      if (!prop.check (analyzer)) {
-+                              error = true;
-+                              return false;
-+                      }
-+                      access = prop.access;
-+                      if (lvalue) {
-+                              if (prop.set_accessor == null) {
-+                                      error = true;
-+                                      Report.error (source_reference, "Property `%s' is read-only".printf (prop.get_full_name ()));
-+                                      return false;
-+                              }
-+                              if (prop.access == SymbolAccessibility.PUBLIC) {
-+                                      access = prop.set_accessor.access;
-+                              } else if (prop.access == SymbolAccessibility.PROTECTED
-+                                         && prop.set_accessor.access != SymbolAccessibility.PUBLIC) {
-+                                      access = prop.set_accessor.access;
-+                              }
-+                      } else {
-+                              if (prop.get_accessor == null) {
-+                                      error = true;
-+                                      Report.error (source_reference, "Property `%s' is write-only".printf (prop.get_full_name ()));
-+                                      return false;
-+                              }
-+                              if (prop.access == SymbolAccessibility.PUBLIC) {
-+                                      access = prop.get_accessor.access;
-+                              } else if (prop.access == SymbolAccessibility.PROTECTED
-+                                         && prop.get_accessor.access != SymbolAccessibility.PUBLIC) {
-+                                      access = prop.get_accessor.access;
-+                              }
-+                      }
-+                      instance = (prop.binding == MemberBinding.INSTANCE);
-+              } else if (member is Signal) {
-+                      instance = true;
-+              }
-+
-+              if (access == SymbolAccessibility.PRIVATE) {
-+                      var target_type = member.parent_symbol;
-+
-+                      bool in_target_type = false;
-+                      for (Symbol this_symbol = analyzer.current_symbol; this_symbol != null; this_symbol = this_symbol.parent_symbol) {
-+                              if (target_type == this_symbol) {
-+                                      in_target_type = true;
-+                                      break;
-+                              }
-+                      }
-+
-+                      if (!in_target_type) {
-+                              error = true;
-+                              Report.error (source_reference, "Access to private member `%s' denied".printf (member.get_full_name ()));
-+                              return false;
-+                      }
-+              }
-+              if ((instance || klass) && !may_access_instance_members) {
-+                      prototype_access = true;
-+
-+                      if (symbol_reference is Method) {
-+                              // also set static type for prototype access
-+                              // required when using instance methods as delegates in constants
-+                              // TODO replace by MethodPrototype
-+                              value_type = analyzer.get_value_type_for_symbol (symbol_reference, lvalue);
-+                      } else if (symbol_reference is Field) {
-+                              value_type = new FieldPrototype ((Field) symbol_reference);
-+                      }
-+              } else {
-+                      // implicit this access
-+                      if (instance && inner == null) {
-+                              inner = new MemberAccess (null, "this", source_reference);
-+                              inner.value_type = this_parameter.parameter_type.copy ();
-+                              inner.symbol_reference = this_parameter;
-+                      }
-+
-+                      value_type = analyzer.get_value_type_for_symbol (symbol_reference, lvalue);
-+
-+                      // resolve generic return values
-+                      if (value_type != null && value_type.type_parameter != null) {
-+                              if (inner != null) {
-+                                      value_type = analyzer.get_actual_type (inner.value_type, symbol_reference, value_type, this);
-+                                      if (value_type == null) {
-+                                              return false;
-+                                      }
-+                              }
-+                      }
-+
-+                      if (symbol_reference is Method) {
-+                              var m = (Method) symbol_reference;
-+
-+                              Method base_method;
-+                              if (m.base_method != null) {
-+                                      base_method = m.base_method;
-+                              } else if (m.base_interface_method != null) {
-+                                      base_method = m.base_interface_method;
-+                              } else {
-+                                      base_method = m;
-+                              }
-+
-+                              if (instance && base_method.parent_symbol != null) {
-+                                      inner.target_type = analyzer.get_data_type_for_symbol ((TypeSymbol) base_method.parent_symbol);
-+                              }
-+                      } else if (symbol_reference is Property) {
-+                              var prop = (Property) symbol_reference;
-+
-+                              Property base_property;
-+                              if (prop.base_property != null) {
-+                                      base_property = prop.base_property;
-+                              } else if (prop.base_interface_property != null) {
-+                                      base_property = prop.base_interface_property;
-+                              } else {
-+                                      base_property = prop;
-+                              }
-+
-+                              if (instance && base_property.parent_symbol != null) {
-+                                      inner.target_type = analyzer.get_data_type_for_symbol ((TypeSymbol) base_property.parent_symbol);
-+                              }
-+                      } else if ((symbol_reference is Field
-+                                  || symbol_reference is Signal)
-+                                 && instance && symbol_reference.parent_symbol != null) {
-+                              inner.target_type = analyzer.get_data_type_for_symbol ((TypeSymbol) symbol_reference.parent_symbol);
-+                      }
-+              }
-+
-+              analyzer.current_source_file.add_symbol_dependency (symbol_reference, SourceFileDependencyType.SOURCE);
-+
-+              return !error;
-+      }
- }
-Index: vala/valaenumvalue.vala
-===================================================================
---- vala/valaenumvalue.vala    (revision 1971)
-+++ vala/valaenumvalue.vala    (revision 2004)
-@@ -128,4 +128,18 @@
-       public void set_cname (string cname) {
-               this.cname = cname;
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              process_attributes ();
-+
-+              accept_children (analyzer);
-+
-+              return !error;
-+      }
- }
-Index: vala/valabinaryexpression.vala
-===================================================================
---- vala/valabinaryexpression.vala     (revision 1971)
-+++ vala/valabinaryexpression.vala     (revision 2004)
-@@ -20,7 +20,7 @@
-  *    Jürg Billeter <j@bitron.ch>
-  */
--using GLib;
-+using Gee;
- /**
-  * Represents an expression with two operands in the source code.
-@@ -137,6 +137,169 @@
-       public override bool is_non_null () {
-               return left.is_non_null () && right.is_non_null ();
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              if (left.error || right.error) {
-+                      /* if there were any errors in inner expressions, skip type check */
-+                      error = true;
-+                      return false;
-+              }
-+
-+              if (left.value_type == null) {
-+                      Report.error (left.source_reference, "invalid left operand");
-+                      error = true;
-+                      return false;
-+              }
-+
-+              if (operator != BinaryOperator.IN && right.value_type == null) {
-+                      Report.error (right.source_reference, "invalid right operand");
-+                      error = true;
-+                      return false;
-+              }
-+
-+              if (left.value_type.data_type == analyzer.string_type.data_type
-+                  && operator == BinaryOperator.PLUS) {
-+                      // string concatenation
-+
-+                      if (right.value_type == null || right.value_type.data_type != analyzer.string_type.data_type) {
-+                              error = true;
-+                              Report.error (source_reference, "Operands must be strings");
-+                              return false;
-+                      }
-+
-+                      value_type = analyzer.string_type.copy ();
-+                      if (left.is_constant () && right.is_constant ()) {
-+                              value_type.value_owned = false;
-+                      } else {
-+                              value_type.value_owned = true;
-+                      }
-+              } else if (operator == BinaryOperator.PLUS
-+                         || operator == BinaryOperator.MINUS
-+                         || operator == BinaryOperator.MUL
-+                         || operator == BinaryOperator.DIV) {
-+                      // check for pointer arithmetic
-+                      if (left.value_type is PointerType) {
-+                              var offset_type = right.value_type.data_type as Struct;
-+                              if (offset_type != null && offset_type.is_integer_type ()) {
-+                                      if (operator == BinaryOperator.PLUS
-+                                          || operator == BinaryOperator.MINUS) {
-+                                              // pointer arithmetic: pointer +/- offset
-+                                              value_type = left.value_type.copy ();
-+                                      }
-+                              } else if (right.value_type is PointerType) {
-+                                      // pointer arithmetic: pointer - pointer
-+                                      value_type = analyzer.size_t_type;
-+                              }
-+                      }
-+
-+                      if (value_type == null) {
-+                              value_type = analyzer.get_arithmetic_result_type (left.value_type, right.value_type);
-+                      }
-+
-+                      if (value_type == null) {
-+                              error = true;
-+                              Report.error (source_reference, "Arithmetic operation not supported for types `%s' and `%s'".printf (left.value_type.to_string (), right.value_type.to_string ()));
-+                              return false;
-+                      }
-+              } else if (operator == BinaryOperator.MOD
-+                         || operator == BinaryOperator.SHIFT_LEFT
-+                         || operator == BinaryOperator.SHIFT_RIGHT
-+                         || operator == BinaryOperator.BITWISE_XOR) {
-+                      value_type = analyzer.get_arithmetic_result_type (left.value_type, right.value_type);
-+
-+                      if (value_type == null) {
-+                              error = true;
-+                              Report.error (source_reference, "Arithmetic operation not supported for types `%s' and `%s'".printf (left.value_type.to_string (), right.value_type.to_string ()));
-+                              return false;
-+                      }
-+              } else if (operator == BinaryOperator.LESS_THAN
-+                         || operator == BinaryOperator.GREATER_THAN
-+                         || operator == BinaryOperator.LESS_THAN_OR_EQUAL
-+                         || operator == BinaryOperator.GREATER_THAN_OR_EQUAL) {
-+                      if (left.value_type.compatible (analyzer.string_type)
-+                          && right.value_type.compatible (analyzer.string_type)) {
-+                              // string comparison
-+                              } else if (left.value_type is PointerType && right.value_type is PointerType) {
-+                                      // pointer arithmetic
-+                      } else {
-+                              var resulting_type = analyzer.get_arithmetic_result_type (left.value_type, right.value_type);
-+
-+                              if (resulting_type == null) {
-+                                      error = true;
-+                                      Report.error (source_reference, "Relational operation not supported for types `%s' and `%s'".printf (left.value_type.to_string (), right.value_type.to_string ()));
-+                                      return false;
-+                              }
-+                      }
-+
-+                      value_type = analyzer.bool_type;
-+              } else if (operator == BinaryOperator.EQUALITY
-+                         || operator == BinaryOperator.INEQUALITY) {
-+                      /* relational operation */
-+
-+                      if (!right.value_type.compatible (left.value_type)
-+                          && !left.value_type.compatible (right.value_type)) {
-+                              Report.error (source_reference, "Equality operation: `%s' and `%s' are incompatible".printf (right.value_type.to_string (), left.value_type.to_string ()));
-+                              error = true;
-+                              return false;
-+                      }
-+
-+                      if (left.value_type.compatible (analyzer.string_type)
-+                          && right.value_type.compatible (analyzer.string_type)) {
-+                              // string comparison
-+                      }
-+
-+                      value_type = analyzer.bool_type;
-+              } else if (operator == BinaryOperator.BITWISE_AND
-+                         || operator == BinaryOperator.BITWISE_OR) {
-+                      // integer type or flags type
-+
-+                      value_type = left.value_type;
-+              } else if (operator == BinaryOperator.AND
-+                         || operator == BinaryOperator.OR) {
-+                      if (!left.value_type.compatible (analyzer.bool_type) || !right.value_type.compatible (analyzer.bool_type)) {
-+                              error = true;
-+                              Report.error (source_reference, "Operands must be boolean");
-+                      }
-+
-+                      value_type = analyzer.bool_type;
-+              } else if (operator == BinaryOperator.IN) {
-+                      // integer type or flags type or collection/map
-+
-+                      /* handle collections and maps */
-+                      var container_type = right.value_type.data_type;
-+                      
-+                      if ((analyzer.collection_type != null && container_type.is_subtype_of (analyzer.collection_type))
-+                          || (analyzer.map_type != null && container_type.is_subtype_of (analyzer.map_type))) {
-+                              Symbol contains_sym = null;
-+                              if (container_type.is_subtype_of (analyzer.collection_type)) {
-+                                      contains_sym = analyzer.collection_type.scope.lookup ("contains");
-+                              } else if (container_type.is_subtype_of (analyzer.map_type)) {
-+                                      contains_sym = analyzer.map_type.scope.lookup ("contains");
-+                              }
-+                              var contains_method = (Method) contains_sym;
-+                              Gee.List<FormalParameter> contains_params = contains_method.get_parameters ();
-+                              Iterator<FormalParameter> contains_params_it = contains_params.iterator ();
-+                              contains_params_it.next ();
-+                              var contains_param = contains_params_it.get ();
-+
-+                              var key_type = analyzer.get_actual_type (right.value_type, contains_method, contains_param.parameter_type, this);
-+                              left.target_type = key_type;
-+                      }
-+                      
-+                      value_type = analyzer.bool_type;
-+                      
-+              } else {
-+                      assert_not_reached ();
-+              }
-+
-+              return !error;
-+      }
- }
- public enum Vala.BinaryOperator {
-Index: vala/valacreationmethod.vala
-===================================================================
---- vala/valacreationmethod.vala       (revision 1971)
-+++ vala/valacreationmethod.vala       (revision 2004)
-@@ -114,4 +114,42 @@
-                       return "%s%s_%s".printf (parent.get_lower_case_cprefix (), infix, name);
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              process_attributes ();
-+
-+              if (type_name != null && type_name != analyzer.current_symbol.name) {
-+                      // type_name is null for constructors generated by GIdlParser
-+                      Report.error (source_reference, "missing return type in method `%s.%s´".printf (analyzer.current_symbol.get_full_name (), type_name));
-+                      error = true;
-+                      return false;
-+              }
-+
-+              analyzer.current_symbol = this;
-+              analyzer.current_return_type = return_type;
-+
-+              accept_children (analyzer);
-+
-+              analyzer.current_symbol = analyzer.current_symbol.parent_symbol;
-+              analyzer.current_return_type = null;
-+
-+              if (analyzer.current_symbol.parent_symbol is Method) {
-+                      /* lambda expressions produce nested methods */
-+                      var up_method = (Method) analyzer.current_symbol.parent_symbol;
-+                      analyzer.current_return_type = up_method.return_type;
-+              }
-+
-+              if (is_abstract || is_virtual || overrides) {
-+                      Report.error (source_reference, "The creation method `%s' cannot be marked as override, virtual, or abstract".printf (get_full_name ()));
-+                      return false;
-+              }
-+
-+              return !error;
-+      }
- }
-Index: vala/valadelegate.vala
-===================================================================
---- vala/valadelegate.vala     (revision 1971)
-+++ vala/valadelegate.vala     (revision 2004)
-@@ -327,4 +327,18 @@
-               return str;
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              process_attributes ();
-+
-+              accept_children (analyzer);
-+
-+              return !error;
-+      }
- }
-Index: vala/valaobjectcreationexpression.vala
-===================================================================
---- vala/valaobjectcreationexpression.vala     (revision 1971)
-+++ vala/valaobjectcreationexpression.vala     (revision 2004)
-@@ -149,4 +149,201 @@
-                       type_reference = new_type;
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              if (member_name != null) {
-+                      member_name.accept (analyzer);
-+              }
-+
-+              TypeSymbol type = null;
-+
-+              if (type_reference == null) {
-+                      if (member_name == null) {
-+                              error = true;
-+                              Report.error (source_reference, "Incomplete object creation expression");
-+                              return false;
-+                      }
-+
-+                      if (member_name.symbol_reference == null) {
-+                              error = true;
-+                              return false;
-+                      }
-+
-+                      var constructor_sym = member_name.symbol_reference;
-+                      var type_sym = member_name.symbol_reference;
-+
-+                      var type_args = member_name.get_type_arguments ();
-+
-+                      if (constructor_sym is Method) {
-+                              type_sym = constructor_sym.parent_symbol;
-+
-+                              var constructor = (Method) constructor_sym;
-+                              if (!(constructor_sym is CreationMethod)) {
-+                                      error = true;
-+                                      Report.error (source_reference, "`%s' is not a creation method".printf (constructor.get_full_name ()));
-+                                      return false;
-+                              }
-+
-+                              symbol_reference = constructor;
-+
-+                              // inner expression can also be base access when chaining constructors
-+                              var ma = member_name.inner as MemberAccess;
-+                              if (ma != null) {
-+                                      type_args = ma.get_type_arguments ();
-+                              }
-+                      }
-+
-+                      if (type_sym is Class) {
-+                              type = (TypeSymbol) type_sym;
-+                              type_reference = new ObjectType ((Class) type);
-+                      } else if (type_sym is Struct) {
-+                              type = (TypeSymbol) type_sym;
-+                              type_reference = new ValueType (type);
-+                      } else if (type_sym is ErrorCode) {
-+                              type_reference = new ErrorType ((ErrorDomain) type_sym.parent_symbol, (ErrorCode) type_sym, source_reference);
-+                              symbol_reference = type_sym;
-+                      } else {
-+                              error = true;
-+                              Report.error (source_reference, "`%s' is not a class, struct, or error code".printf (type_sym.get_full_name ()));
-+                              return false;
-+                      }
-+
-+                      foreach (DataType type_arg in type_args) {
-+                              type_reference.add_type_argument (type_arg);
-+
-+                              analyzer.current_source_file.add_type_dependency (type_arg, SourceFileDependencyType.SOURCE);
-+                      }
-+              } else {
-+                      type = type_reference.data_type;
-+              }
-+
-+              analyzer.current_source_file.add_symbol_dependency (type, SourceFileDependencyType.SOURCE);
-+
-+              value_type = type_reference.copy ();
-+              value_type.value_owned = true;
-+
-+              int given_num_type_args = type_reference.get_type_arguments ().size;
-+              int expected_num_type_args = 0;
-+
-+              if (type is Class) {
-+                      var cl = (Class) type;
-+
-+                      expected_num_type_args = cl.get_type_parameters ().size;
-+
-+                      if (struct_creation) {
-+                              error = true;
-+                              Report.error (source_reference, "syntax error, use `new' to create new objects");
-+                              return false;
-+                      }
-+
-+                      if (cl.is_abstract) {
-+                              value_type = null;
-+                              error = true;
-+                              Report.error (source_reference, "Can't create instance of abstract class `%s'".printf (cl.get_full_name ()));
-+                              return false;
-+                      }
-+
-+                      if (symbol_reference == null) {
-+                              symbol_reference = cl.default_construction_method;
-+                      }
-+
-+                      while (cl != null) {
-+                              if (cl == analyzer.initially_unowned_type) {
-+                                      value_type.floating_reference = true;
-+                                      break;
-+                              }
-+
-+                              cl = cl.base_class;
-+                      }
-+              } else if (type is Struct) {
-+                      var st = (Struct) type;
-+
-+                      expected_num_type_args = st.get_type_parameters ().size;
-+
-+                      if (!struct_creation) {
-+                              Report.warning (source_reference, "deprecated syntax, don't use `new' to initialize structs");
-+                      }
-+
-+                      if (symbol_reference == null) {
-+                              symbol_reference = st.default_construction_method;
-+                      }
-+              }
-+
-+              if (expected_num_type_args > given_num_type_args) {
-+                      error = true;
-+                      Report.error (source_reference, "too few type arguments");
-+                      return false;
-+              } else if (expected_num_type_args < given_num_type_args) {
-+                      error = true;
-+                      Report.error (source_reference, "too many type arguments");
-+                      return false;
-+              }
-+
-+              if (symbol_reference == null && get_argument_list ().size != 0) {
-+                      value_type = null;
-+                      error = true;
-+                      Report.error (source_reference, "No arguments allowed when constructing type `%s'".printf (type.get_full_name ()));
-+                      return false;
-+              }
-+
-+              if (symbol_reference is Method) {
-+                      var m = (Method) symbol_reference;
-+
-+                      var args = get_argument_list ();
-+                      Iterator<Expression> arg_it = args.iterator ();
-+                      foreach (FormalParameter param in m.get_parameters ()) {
-+                              if (param.ellipsis) {
-+                                      break;
-+                              }
-+
-+                              if (arg_it.next ()) {
-+                                      Expression arg = arg_it.get ();
-+
-+                                      /* store expected type for callback parameters */
-+                                      arg.target_type = param.parameter_type;
-+                              }
-+                      }
-+
-+                      foreach (Expression arg in args) {
-+                              arg.accept (analyzer);
-+                      }
-+
-+                      analyzer.check_arguments (this, new MethodType (m), m.get_parameters (), args);
-+
-+                      foreach (DataType error_type in m.get_error_types ()) {
-+                              // ensure we can trace back which expression may throw errors of this type
-+                              var call_error_type = error_type.copy ();
-+                              call_error_type.source_reference = source_reference;
-+
-+                              add_error_type (call_error_type);
-+                      }
-+              } else if (type_reference is ErrorType) {
-+                      accept_children (analyzer);
-+
-+                      if (get_argument_list ().size == 0) {
-+                              error = true;
-+                              Report.error (source_reference, "Too few arguments, errors need at least 1 argument");
-+                      } else {
-+                              Iterator<Expression> arg_it = get_argument_list ().iterator ();
-+                              arg_it.next ();
-+                              var ex = arg_it.get ();
-+                              if (ex.value_type == null || !ex.value_type.compatible (analyzer.string_type)) {
-+                                      error = true;
-+                                      Report.error (source_reference, "Invalid type for argument 1");
-+                              }
-+                      }
-+              }
-+
-+              foreach (MemberInitializer init in get_object_initializer ()) {
-+                      analyzer.visit_member_initializer (init, type_reference);
-+              }
-+
-+              return !error;
-+      }
- }
-Index: vala/valaerrordomain.vala
-===================================================================
---- vala/valaerrordomain.vala  (revision 1971)
-+++ vala/valaerrordomain.vala  (revision 2004)
-@@ -215,4 +215,18 @@
-       public override string? get_set_value_function () {
-               return "g_value_set_pointer";
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              process_attributes ();
-+
-+              accept_children (analyzer);
-+
-+              return !error;
-+      }
- }
-Index: vala/valaifstatement.vala
-===================================================================
---- vala/valaifstatement.vala  (revision 1971)
-+++ vala/valaifstatement.vala  (revision 2004)
-@@ -86,4 +86,35 @@
-                       condition = new_node;
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              accept_children (analyzer);
-+
-+              if (condition.error) {
-+                      /* if there was an error in the condition, skip this check */
-+                      error = true;
-+                      return false;
-+              }
-+
-+              if (!condition.value_type.compatible (analyzer.bool_type)) {
-+                      error = true;
-+                      Report.error (condition.source_reference, "Condition must be boolean");
-+                      return false;
-+              }
-+
-+              add_error_types (condition.get_error_types ());
-+              add_error_types (true_statement.get_error_types ());
-+
-+              if (false_statement != null) {
-+                      add_error_types (false_statement.get_error_types ());
-+              }
-+
-+              return !error;
-+      }
- }
-Index: vala/valaswitchsection.vala
-===================================================================
---- vala/valaswitchsection.vala        (revision 1971)
-+++ vala/valaswitchsection.vala        (revision 2004)
-@@ -80,4 +80,31 @@
-                       st.accept (visitor);
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              foreach (SwitchLabel label in get_labels ()) {
-+                      label.accept (analyzer);
-+              }
-+
-+              owner = analyzer.current_symbol.scope;
-+              analyzer.current_symbol = this;
-+
-+              foreach (Statement st in get_statements ()) {
-+                      st.accept (analyzer);
-+              }
-+
-+              foreach (LocalVariable local in get_local_variables ()) {
-+                      local.active = false;
-+              }
-+
-+              analyzer.current_symbol = analyzer.current_symbol.parent_symbol;
-+
-+              return !error;
-+      }
- }
-Index: vala/valaenum.vala
-===================================================================
---- vala/valaenum.vala (revision 1971)
-+++ vala/valaenum.vala (revision 2004)
-@@ -289,4 +289,26 @@
-       public override string? get_default_value () {
-               return "0";
-       }
-+
-+      public override string? get_type_signature () {
-+              if (is_flags) {
-+                      return "u";
-+              } else {
-+                      return "i";
-+              }
-+      }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              process_attributes ();
-+
-+              accept_children (analyzer);
-+
-+              return !error;
-+      }
- }
-Index: vala/valapropertyaccessor.vala
-===================================================================
---- vala/valapropertyaccessor.vala     (revision 1971)
-+++ vala/valapropertyaccessor.vala     (revision 2004)
-@@ -131,4 +131,55 @@
-                       }
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              process_attributes ();
-+
-+              var old_return_type = analyzer.current_return_type;
-+              if (readable) {
-+                      analyzer.current_return_type = prop.property_type;
-+              } else {
-+                      // void
-+                      analyzer.current_return_type = new VoidType ();
-+              }
-+
-+              if (!prop.external_package) {
-+                      if (body == null && !prop.interface_only && !prop.is_abstract) {
-+                              /* no accessor body specified, insert default body */
-+
-+                              if (prop.parent_symbol is Interface) {
-+                                      error = true;
-+                                      Report.error (source_reference, "Automatic properties can't be used in interfaces");
-+                                      return false;
-+                              }
-+                              automatic_body = true;
-+                              body = new Block (source_reference);
-+                              var ma = new MemberAccess.simple ("_%s".printf (prop.name), source_reference);
-+                              if (readable) {
-+                                      body.add_statement (new ReturnStatement (ma, source_reference));
-+                              } else {
-+                                      var assignment = new Assignment (ma, new MemberAccess.simple ("value", source_reference), AssignmentOperator.SIMPLE, source_reference);
-+                                      body.add_statement (new ExpressionStatement (assignment));
-+                              }
-+                      }
-+
-+                      if (body != null && (writable || construction)) {
-+                              var value_type = prop.property_type.copy ();
-+                              value_parameter = new FormalParameter ("value", value_type, source_reference);
-+                              body.scope.add (value_parameter.name, value_parameter);
-+                      }
-+              }
-+
-+              accept_children (analyzer);
-+
-+              analyzer.current_return_type = old_return_type;
-+
-+              return !error;
-+      }
- }
-Index: vala/valaobjecttype.vala
-===================================================================
---- vala/valaobjecttype.vala   (revision 1971)
-+++ vala/valaobjecttype.vala   (revision 2004)
-@@ -98,4 +98,8 @@
-                       return null;
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              return type_symbol.check (analyzer);
-+      }
- }
-Index: vala/valasemanticanalyzer.vala
-===================================================================
---- vala/valasemanticanalyzer.vala     (revision 1971)
-+++ vala/valasemanticanalyzer.vala     (revision 2004)
-@@ -30,46 +30,44 @@
- public class Vala.SemanticAnalyzer : CodeVisitor {
-       public CodeContext context { get; set; }
--      Symbol root_symbol;
-+      public Symbol root_symbol;
-       public Symbol current_symbol { get; set; }
-       public SourceFile current_source_file { get; set; }
--      DataType current_return_type;
--      Class current_class;
--      Struct current_struct;
-+      public DataType current_return_type;
-+      public Class current_class;
-+      public Struct current_struct;
--      Gee.List<UsingDirective> current_using_directives;
-+      public DataType bool_type;
-+      public DataType string_type;
-+      public DataType uchar_type;
-+      public DataType short_type;
-+      public DataType ushort_type;
-+      public DataType int_type;
-+      public DataType uint_type;
-+      public DataType long_type;
-+      public DataType ulong_type;
-+      public DataType size_t_type;
-+      public DataType ssize_t_type;
-+      public DataType int8_type;
-+      public DataType unichar_type;
-+      public DataType double_type;
-+      public DataType type_type;
-+      public Class object_type;
-+      public TypeSymbol initially_unowned_type;
-+      public DataType glist_type;
-+      public DataType gslist_type;
-+      public Class gerror_type;
-+      public DataType iterable_type;
-+      public Interface iterator_type;
-+      public Interface list_type;
-+      public Interface collection_type;
-+      public Interface map_type;
--      DataType bool_type;
--      DataType string_type;
--      DataType uchar_type;
--      DataType short_type;
--      DataType ushort_type;
--      DataType int_type;
--      DataType uint_type;
--      DataType long_type;
--      DataType ulong_type;
--      DataType size_t_type;
--      DataType ssize_t_type;
--      DataType int8_type;
--      DataType unichar_type;
--      DataType double_type;
--      DataType type_type;
--      Class object_type;
--      TypeSymbol initially_unowned_type;
--      DataType glist_type;
--      DataType gslist_type;
--      Class gerror_type;
--      DataType iterable_type;
--      Interface iterator_type;
--      Interface list_type;
--      Interface collection_type;
--      Interface map_type;
--
-       private int next_lambda_id = 0;
-       // keep replaced alive to make sure they remain valid
-       // for the whole execution of CodeNode.accept
--      Gee.List<CodeNode> replaced_nodes = new ArrayList<CodeNode> ();
-+      public Gee.List<CodeNode> replaced_nodes = new ArrayList<CodeNode> ();
-       public SemanticAnalyzer () {
-       }
-@@ -129,499 +127,65 @@
-       public override void visit_source_file (SourceFile file) {
-               current_source_file = file;
--              current_using_directives = file.get_using_directives ();
-               next_lambda_id = 0;
-               file.accept_children (this);
--
--              current_using_directives = null;
-       }
-       public override void visit_namespace (Namespace ns) {
--              ns.process_attributes ();
-+              ns.check (this);
-       }
-       public override void visit_class (Class cl) {
--              cl.process_attributes ();
--
--              current_symbol = cl;
--              current_class = cl;
--
--              foreach (DataType base_type_reference in cl.get_base_types ()) {
--                      // check whether base type is at least as accessible as the class
--                      if (!is_type_accessible (cl, base_type_reference)) {
--                              cl.error = true;
--                              Report.error (cl.source_reference, "base type `%s` is less accessible than class `%s`".printf (base_type_reference.to_string (), cl.get_full_name ()));
--                              return;
--                      }
--
--                      current_source_file.add_type_dependency (base_type_reference, SourceFileDependencyType.HEADER_FULL);
--              }
--
--              cl.accept_children (this);
--
--              /* compact classes cannot implement interfaces */
--              if (cl.is_compact) {
--                      foreach (DataType base_type in cl.get_base_types ()) {
--                              if (base_type.data_type is Interface) {
--                                      cl.error = true;
--                                      Report.error (cl.source_reference, "compact classes `%s` may not implement interfaces".printf (cl.get_full_name ()));
--                              }
--                      }
--              }
--
--              /* gather all prerequisites */
--              Gee.List<TypeSymbol> prerequisites = new ArrayList<TypeSymbol> ();
--              foreach (DataType base_type in cl.get_base_types ()) {
--                      if (base_type.data_type is Interface) {
--                              get_all_prerequisites ((Interface) base_type.data_type, prerequisites);
--                      }
--              }
--              /* check whether all prerequisites are met */
--              Gee.List<string> missing_prereqs = new ArrayList<string> ();
--              foreach (TypeSymbol prereq in prerequisites) {
--                      if (!class_is_a (cl, prereq)) {
--                              missing_prereqs.insert (0, prereq.get_full_name ());
--                      }
--              }
--              /* report any missing prerequisites */
--              if (missing_prereqs.size > 0) {
--                      cl.error = true;
--
--                      string error_string = "%s: some prerequisites (".printf (cl.get_full_name ());
--                      bool first = true;
--                      foreach (string s in missing_prereqs) {
--                              if (first) {
--                                      error_string = "%s`%s'".printf (error_string, s);
--                                      first = false;
--                              } else {
--                                      error_string = "%s, `%s'".printf (error_string, s);
--                              }
--                      }
--                      error_string += ") are not met";
--                      Report.error (cl.source_reference, error_string);
--              }
--
--              /* VAPI classes don't have to specify overridden methods */
--              if (!cl.external_package) {
--                      /* all abstract symbols defined in base types have to be at least defined (or implemented) also in this type */
--                      foreach (DataType base_type in cl.get_base_types ()) {
--                              if (base_type.data_type is Interface) {
--                                      Interface iface = (Interface) base_type.data_type;
--
--                                      if (cl.base_class != null && cl.base_class.is_subtype_of (iface)) {
--                                              // reimplementation of interface, class is not required to reimplement all methods
--                                              break;
--                                      }
--
--                                      /* We do not need to do expensive equality checking here since this is done
--                                       * already. We only need to guarantee the symbols are present.
--                                       */
--
--                                      /* check methods */
--                                      foreach (Method m in iface.get_methods ()) {
--                                              if (m.is_abstract) {
--                                                      Symbol sym = null;
--                                                      var base_class = cl;
--                                                      while (base_class != null && !(sym is Method)) {
--                                                              sym = base_class.scope.lookup (m.name);
--                                                              base_class = base_class.base_class;
--                                                      }
--                                                      if (!(sym is Method)) {
--                                                              cl.error = true;
--                                                              Report.error (cl.source_reference, "`%s' does not implement interface method `%s'".printf (cl.get_full_name (), m.get_full_name ()));
--                                                      }
--                                              }
--                                      }
--
--                                      /* check properties */
--                                      foreach (Property prop in iface.get_properties ()) {
--                                              if (prop.is_abstract) {
--                                                      Symbol sym = null;
--                                                      var base_class = cl;
--                                                      while (base_class != null && !(sym is Property)) {
--                                                              sym = base_class.scope.lookup (prop.name);
--                                                              base_class = base_class.base_class;
--                                                      }
--                                                      if (!(sym is Property)) {
--                                                              cl.error = true;
--                                                              Report.error (cl.source_reference, "`%s' does not implement interface property `%s'".printf (cl.get_full_name (), prop.get_full_name ()));
--                                                      }
--                                              }
--                                      }
--                              }
--                      }
--
--                      /* all abstract symbols defined in base classes have to be implemented in non-abstract classes */
--                      if (!cl.is_abstract) {
--                              var base_class = cl.base_class;
--                              while (base_class != null && base_class.is_abstract) {
--                                      foreach (Method base_method in base_class.get_methods ()) {
--                                              if (base_method.is_abstract) {
--                                                      var override_method = symbol_lookup_inherited (cl, base_method.name) as Method;
--                                                      if (override_method == null || !override_method.overrides) {
--                                                              cl.error = true;
--                                                              Report.error (cl.source_reference, "`%s' does not implement abstract method `%s'".printf (cl.get_full_name (), base_method.get_full_name ()));
--                                                      }
--                                              }
--                                      }
--                                      foreach (Property base_property in base_class.get_properties ()) {
--                                              if (base_property.is_abstract) {
--                                                      var override_property = symbol_lookup_inherited (cl, base_property.name) as Property;
--                                                      if (override_property == null || !override_property.overrides) {
--                                                              cl.error = true;
--                                                              Report.error (cl.source_reference, "`%s' does not implement abstract property `%s'".printf (cl.get_full_name (), base_property.get_full_name ()));
--                                                      }
--                                              }
--                                      }
--                                      base_class = base_class.base_class;
--                              }
--                      }
--              }
--
--              current_symbol = current_symbol.parent_symbol;
--              current_class = null;
-+              cl.check (this);
-       }
--      private void get_all_prerequisites (Interface iface, Gee.List<TypeSymbol> list) {
--              foreach (DataType prereq in iface.get_prerequisites ()) {
--                      TypeSymbol type = prereq.data_type;
--                      /* skip on previous errors */
--                      if (type == null) {
--                              continue;
--                      }
--
--                      list.add (type);
--                      if (type is Interface) {
--                              get_all_prerequisites ((Interface) type, list);
--
--                      }
--              }
--      }
--
--      private bool class_is_a (Class cl, TypeSymbol t) {
--              if (cl == t) {
--                      return true;
--              }
--
--              foreach (DataType base_type in cl.get_base_types ()) {
--                      if (base_type.data_type is Class) {
--                              if (class_is_a ((Class) base_type.data_type, t)) {
--                                      return true;
--                              }
--                      } else if (base_type.data_type == t) {
--                              return true;
--                      }
--              }
--
--              return false;
--      }
--
-       public override void visit_struct (Struct st) {
--              st.process_attributes ();
--
--              current_symbol = st;
--              current_struct = st;
--
--              st.accept_children (this);
--
--              if (!st.external && !st.external_package && st.get_base_types ().size == 0 && st.get_fields ().size == 0) {
--                      Report.error (st.source_reference, "structs cannot be empty");
--              }
--
--              current_symbol = current_symbol.parent_symbol;
--              current_struct = null;
-+              st.check (this);
-       }
-       public override void visit_interface (Interface iface) {
--              iface.process_attributes ();
--
--              current_symbol = iface;
--
--              foreach (DataType prerequisite_reference in iface.get_prerequisites ()) {
--                      // check whether prerequisite is at least as accessible as the interface
--                      if (!is_type_accessible (iface, prerequisite_reference)) {
--                              iface.error = true;
--                              Report.error (iface.source_reference, "prerequisite `%s` is less accessible than interface `%s`".printf (prerequisite_reference.to_string (), iface.get_full_name ()));
--                              return;
--                      }
--
--                      current_source_file.add_type_dependency (prerequisite_reference, SourceFileDependencyType.HEADER_FULL);
--              }
--
--              /* check prerequisites */
--              Class prereq_class;
--              foreach (DataType prereq in iface.get_prerequisites ()) {
--                      TypeSymbol class_or_interface = prereq.data_type;
--                      /* skip on previous errors */
--                      if (class_or_interface == null) {
--                              iface.error = true;
--                              continue;
--                      }
--                      /* interfaces are not allowed to have multiple instantiable prerequisites */
--                      if (class_or_interface is Class) {
--                              if (prereq_class != null) {
--                                      iface.error = true;
--                                      Report.error (iface.source_reference, "%s: Interfaces cannot have multiple instantiable prerequisites (`%s' and `%s')".printf (iface.get_full_name (), class_or_interface.get_full_name (), prereq_class.get_full_name ()));
--                                      return;
--                              }
--
--                              prereq_class = (Class) class_or_interface;
--                      }
--              }
--
--              iface.accept_children (this);
--
--              current_symbol = current_symbol.parent_symbol;
-+              iface.check (this);
-       }
-       public override void visit_enum (Enum en) {
--              en.process_attributes ();
--
--              en.accept_children (this);
-+              en.check (this);
-       }
-       public override void visit_enum_value (EnumValue ev) {
--              ev.process_attributes ();
--
--              ev.accept_children (this);
-+              ev.check (this);
-       }
-       public override void visit_error_domain (ErrorDomain ed) {
--              ed.process_attributes ();
-+              ed.check (this);
-+      }
--              ed.accept_children (this);
-+      public override void visit_error_code (ErrorCode ec) {
-+              ec.check (this);
-       }
-       public override void visit_delegate (Delegate d) {
--              d.process_attributes ();
--
--              d.accept_children (this);
-+              d.check (this);
-       }
-       public override void visit_constant (Constant c) {
--              c.process_attributes ();
--
--              c.type_reference.accept (this);
--
--              if (!c.external_package) {
--                      if (c.initializer == null) {
--                              c.error = true;
--                              Report.error (c.source_reference, "A const field requires a initializer to be provided");
--                      } else {
--                              c.initializer.target_type = c.type_reference;
--
--                              c.initializer.accept (this);
--                      }
--              }
-+              c.check (this);
-       }
-       public override void visit_field (Field f) {
--              f.process_attributes ();
--
--              if (f.initializer != null) {
--                      f.initializer.target_type = f.field_type;
--              }
--
--              f.accept_children (this);
--
--              if (f.binding == MemberBinding.INSTANCE && f.parent_symbol is Interface) {
--                      f.error = true;
--                      Report.error (f.source_reference, "Interfaces may not have instance fields");
--                      return;
--              }
--
--              if (!f.is_internal_symbol ()) {
--                      if (f.field_type is ValueType) {
--                              current_source_file.add_type_dependency (f.field_type, SourceFileDependencyType.HEADER_FULL);
--                      } else {
--                              current_source_file.add_type_dependency (f.field_type, SourceFileDependencyType.HEADER_SHALLOW);
--                      }
--              } else {
--                      if (f.parent_symbol is Namespace) {
--                              f.error = true;
--                              Report.error (f.source_reference, "Namespaces may not have private members");
--                              return;
--                      }
--
--                      current_source_file.add_type_dependency (f.field_type, SourceFileDependencyType.SOURCE);
--              }
-+              f.check (this);
-       }
-       public override void visit_method (Method m) {
--              m.process_attributes ();
--
--              if (m.is_abstract) {
--                      if (m.parent_symbol is Class) {
--                              var cl = (Class) m.parent_symbol;
--                              if (!cl.is_abstract) {
--                                      m.error = true;
--                                      Report.error (m.source_reference, "Abstract methods may not be declared in non-abstract classes");
--                                      return;
--                              }
--                      } else if (!(m.parent_symbol is Interface)) {
--                              m.error = true;
--                              Report.error (m.source_reference, "Abstract methods may not be declared outside of classes and interfaces");
--                              return;
--                      }
--              } else if (m.is_virtual) {
--                      if (!(m.parent_symbol is Class) && !(m.parent_symbol is Interface)) {
--                              m.error = true;
--                              Report.error (m.source_reference, "Virtual methods may not be declared outside of classes and interfaces");
--                              return;
--                      }
--
--                      if (m.parent_symbol is Class) {
--                              var cl = (Class) m.parent_symbol;
--                              if (cl.is_compact) {
--                                      Report.error (m.source_reference, "Virtual methods may not be declared in compact classes");
--                                      return;
--                              }
--                      }
--              } else if (m.overrides) {
--                      if (!(m.parent_symbol is Class)) {
--                              m.error = true;
--                              Report.error (m.source_reference, "Methods may not be overridden outside of classes");
--                              return;
--                      }
--              }
--
--              if (m.is_abstract && m.body != null) {
--                      Report.error (m.source_reference, "Abstract methods cannot have bodies");
--              } else if (m.external && m.body != null) {
--                      Report.error (m.source_reference, "Extern methods cannot have bodies");
--              } else if (!m.is_abstract && !m.external && !m.external_package && m.body == null) {
--                      Report.error (m.source_reference, "Non-abstract, non-extern methods must have bodies");
--              }
--
--              var old_symbol = current_symbol;
--              var old_return_type = current_return_type;
--              current_symbol = m;
--              current_return_type = m.return_type;
--
--              var init_attr = m.get_attribute ("ModuleInit");
--              if (init_attr != null) {
--                      m.source_reference.file.context.module_init_method = m;
--              }
--
--              if (!m.is_internal_symbol ()) {
--                      if (m.return_type is ValueType) {
--                              current_source_file.add_type_dependency (m.return_type, SourceFileDependencyType.HEADER_FULL);
--                      } else {
--                              current_source_file.add_type_dependency (m.return_type, SourceFileDependencyType.HEADER_SHALLOW);
--                      }
--              }
--              current_source_file.add_type_dependency (m.return_type, SourceFileDependencyType.SOURCE);
--
--              m.accept_children (this);
--
--              current_symbol = old_symbol;
--              current_return_type = old_return_type;
--
--              if (current_symbol.parent_symbol is Method) {
--                      /* lambda expressions produce nested methods */
--                      var up_method = (Method) current_symbol.parent_symbol;
--                      current_return_type = up_method.return_type;
--              }
--
--              if (current_symbol is Struct) {
--                      if (m.is_abstract || m.is_virtual || m.overrides) {
--                              Report.error (m.source_reference, "A struct member `%s' cannot be marked as override, virtual, or abstract".printf (m.get_full_name ()));
--                              return;
--                      }
--              } else if (m.overrides && m.base_method == null) {
--                      Report.error (m.source_reference, "%s: no suitable method found to override".printf (m.get_full_name ()));
--              }
--
--              // check whether return type is at least as accessible as the method
--              if (!is_type_accessible (m, m.return_type)) {
--                      m.error = true;
--                      Report.error (m.source_reference, "return type `%s` is less accessible than method `%s`".printf (m.return_type.to_string (), m.get_full_name ()));
--                      return;
--              }
--
--              foreach (Expression precondition in m.get_preconditions ()) {
--                      if (precondition.error) {
--                              // if there was an error in the precondition, skip this check
--                              m.error = true;
--                              return;
--                      }
--
--                      if (!precondition.value_type.compatible (bool_type)) {
--                              m.error = true;
--                              Report.error (precondition.source_reference, "Precondition must be boolean");
--                              return;
--                      }
--              }
--
--              foreach (Expression postcondition in m.get_postconditions ()) {
--                      if (postcondition.error) {
--                              // if there was an error in the postcondition, skip this check
--                              m.error = true;
--                              return;
--                      }
--
--                      if (!postcondition.value_type.compatible (bool_type)) {
--                              m.error = true;
--                              Report.error (postcondition.source_reference, "Postcondition must be boolean");
--                              return;
--                      }
--              }
--
--              if (m.tree_can_fail && m.name == "main") {
--                      Report.error (m.source_reference, "\"main\" method cannot throw errors");
--              }
--
--              // check that all errors that can be thrown in the method body are declared
--              if (m.body != null) { 
--                      foreach (DataType body_error_type in m.body.get_error_types ()) {
--                              bool can_propagate_error = false;
--                              foreach (DataType method_error_type in m.get_error_types ()) {
--                                      if (body_error_type.compatible (method_error_type)) {
--                                              can_propagate_error = true;
--                                      }
--                              }
--                              if (!can_propagate_error) {
--                                      Report.warning (body_error_type.source_reference, "unhandled error `%s'".printf (body_error_type.to_string()));
--                              }
--                      }
--              }
-+              m.check (this);
-       }
-       public override void visit_creation_method (CreationMethod m) {
--              m.process_attributes ();
--
--              if (m.type_name != null && m.type_name != current_symbol.name) {
--                      // type_name is null for constructors generated by GIdlParser
--                      Report.error (m.source_reference, "missing return type in method `%s.%s´".printf (current_symbol.get_full_name (), m.type_name));
--                      m.error = true;
--                      return;
--              }
--
--              current_symbol = m;
--              current_return_type = m.return_type;
--
--              m.accept_children (this);
--
--              current_symbol = current_symbol.parent_symbol;
--              current_return_type = null;
--
--              if (current_symbol.parent_symbol is Method) {
--                      /* lambda expressions produce nested methods */
--                      var up_method = (Method) current_symbol.parent_symbol;
--                      current_return_type = up_method.return_type;
--              }
--
--              if (m.is_abstract || m.is_virtual || m.overrides) {
--                      Report.error (m.source_reference, "The creation method `%s' cannot be marked as override, virtual, or abstract".printf (m.get_full_name ()));
--                      return;
--              }
-+              m.check (this);
-       }
-       public override void visit_formal_parameter (FormalParameter p) {
--              p.process_attributes ();
--
-               p.check (this);
-       }
-@@ -640,562 +204,71 @@
-       }
-       public override void visit_property (Property prop) {
--              prop.process_attributes ();
--
-               prop.check (this);
-       }
-       public override void visit_property_accessor (PropertyAccessor acc) {
--              acc.process_attributes ();
--
--              var old_return_type = current_return_type;
--              if (acc.readable) {
--                      current_return_type = acc.prop.property_type;
--              } else {
--                      // void
--                      current_return_type = new VoidType ();
--              }
--
--              if (!acc.prop.external_package) {
--                      if (acc.body == null && !acc.prop.interface_only && !acc.prop.is_abstract) {
--                              /* no accessor body specified, insert default body */
--
--                              if (acc.prop.parent_symbol is Interface) {
--                                      acc.error = true;
--                                      Report.error (acc.source_reference, "Automatic properties can't be used in interfaces");
--                                      return;
--                              }
--                              acc.automatic_body = true;
--                              acc.body = new Block (acc.source_reference);
--                              var ma = new MemberAccess.simple ("_%s".printf (acc.prop.name), acc.source_reference);
--                              if (acc.readable) {
--                                      acc.body.add_statement (new ReturnStatement (ma, acc.source_reference));
--                              } else {
--                                      var assignment = new Assignment (ma, new MemberAccess.simple ("value", acc.source_reference), AssignmentOperator.SIMPLE, acc.source_reference);
--                                      acc.body.add_statement (new ExpressionStatement (assignment));
--                              }
--                      }
--
--                      if (acc.body != null && (acc.writable || acc.construction)) {
--                              var value_type = acc.prop.property_type.copy ();
--                              acc.value_parameter = new FormalParameter ("value", value_type, acc.source_reference);
--                              acc.body.scope.add (acc.value_parameter.name, acc.value_parameter);
--                      }
--              }
--
--              acc.accept_children (this);
--
--              current_return_type = old_return_type;
-+              acc.check (this);
-       }
-       public override void visit_signal (Signal sig) {
--              sig.process_attributes ();
--
--              sig.accept_children (this);
-+              sig.check (this);
-       }
-       public override void visit_constructor (Constructor c) {
--              c.this_parameter = new FormalParameter ("this", new ObjectType (current_class));
--              c.scope.add (c.this_parameter.name, c.this_parameter);
--
--              c.owner = current_symbol.scope;
--              current_symbol = c;
--
--              c.accept_children (this);
--
--              foreach (DataType body_error_type in c.body.get_error_types ()) {
--                      Report.warning (body_error_type.source_reference, "unhandled error `%s'".printf (body_error_type.to_string()));
--              }
--
--              current_symbol = current_symbol.parent_symbol;
-+              c.check (this);
-       }
-       public override void visit_destructor (Destructor d) {
--              d.owner = current_symbol.scope;
--              current_symbol = d;
--
--              d.accept_children (this);
--
--              current_symbol = current_symbol.parent_symbol;
-+              d.check (this);
-       }
-       public override void visit_block (Block b) {
--              b.owner = current_symbol.scope;
--              current_symbol = b;
--
--              b.accept_children (this);
--
--              foreach (LocalVariable local in b.get_local_variables ()) {
--                      local.active = false;
--              }
--
--              foreach (Statement stmt in b.get_statements()) {
--                      b.add_error_types (stmt.get_error_types ());
--              }
--
--              current_symbol = current_symbol.parent_symbol;
-+              b.check (this);
-       }
-       public override void visit_declaration_statement (DeclarationStatement stmt) {
--              var local = stmt.declaration as LocalVariable;
--              if (local != null && local.initializer != null) {
--                      foreach (DataType error_type in local.initializer.get_error_types ()) {
--                              // ensure we can trace back which expression may throw errors of this type
--                              var initializer_error_type = error_type.copy ();
--                              initializer_error_type.source_reference = local.initializer.source_reference;
--
--                              stmt.add_error_type (initializer_error_type);
--                      }
--              }
-+              stmt.check (this);
-       }
-       public override void visit_local_variable (LocalVariable local) {
--              if (local.initializer != null) {
--                      local.initializer.target_type = local.variable_type;
--              }
--
--              local.accept_children (this);
--
--              if (local.variable_type == null) {
--                      /* var type */
--
--                      if (local.initializer == null) {
--                              local.error = true;
--                              Report.error (local.source_reference, "var declaration not allowed without initializer");
--                              return;
--                      }
--                      if (local.initializer.value_type == null) {
--                              local.error = true;
--                              Report.error (local.source_reference, "var declaration not allowed with non-typed initializer");
--                              return;
--                      }
--
--                      local.variable_type = local.initializer.value_type.copy ();
--                      local.variable_type.value_owned = true;
--                      local.variable_type.floating_reference = false;
--
--                      local.initializer.target_type = local.variable_type;
--              }
--
--              if (local.initializer != null) {
--                      if (local.initializer.value_type == null) {
--                              if (!(local.initializer is MemberAccess) && !(local.initializer is LambdaExpression)) {
--                                      local.error = true;
--                                      Report.error (local.source_reference, "expression type not allowed as initializer");
--                                      return;
--                              }
--
--                              if (local.initializer.symbol_reference is Method &&
--                                  local.variable_type is DelegateType) {
--                                      var m = (Method) local.initializer.symbol_reference;
--                                      var dt = (DelegateType) local.variable_type;
--                                      var cb = dt.delegate_symbol;
--
--                                      /* check whether method matches callback type */
--                                      if (!cb.matches_method (m)) {
--                                              local.error = true;
--                                              Report.error (local.source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.get_full_name (), cb.get_full_name ()));
--                                              return;
--                                      }
--
--                                      local.initializer.value_type = local.variable_type;
--                              } else {
--                                      local.error = true;
--                                      Report.error (local.source_reference, "expression type not allowed as initializer");
--                                      return;
--                              }
--                      }
--
--                      if (!local.initializer.value_type.compatible (local.variable_type)) {
--                              local.error = true;
--                              Report.error (local.source_reference, "Assignment: Cannot convert from `%s' to `%s'".printf (local.initializer.value_type.to_string (), local.variable_type.to_string ()));
--                              return;
--                      }
--
--                      if (local.initializer.value_type.is_disposable ()) {
--                              /* rhs transfers ownership of the expression */
--                              if (!(local.variable_type is PointerType) && !local.variable_type.value_owned) {
--                                      /* lhs doesn't own the value */
--                                      local.error = true;
--                                      Report.error (local.source_reference, "Invalid assignment from owned expression to unowned variable");
--                                      return;
--                              }
--                      }
--              }
--
--              current_source_file.add_type_dependency (local.variable_type, SourceFileDependencyType.SOURCE);
--
--              current_symbol.scope.add (local.name, local);
--
--              var block = (Block) current_symbol;
--              block.add_local_variable (local);
--
--              local.active = true;
-+              local.check (this);
-       }
--      /**
--       * Visit operation called for initializer lists
--       *
--       * @param list an initializer list
--       */
-       public override void visit_initializer_list (InitializerList list) {
--              if (list.target_type == null) {
--                      list.error = true;
--                      Report.error (list.source_reference, "initializer list used for unknown type");
--                      return;
--              } else if (list.target_type is ArrayType) {
--                      /* initializer is used as array initializer */
--                      var array_type = (ArrayType) list.target_type;
--
--                      foreach (Expression e in list.get_initializers ()) {
--                              e.target_type = array_type.element_type.copy ();
--                      }
--              } else if (list.target_type.data_type is Struct) {
--                      /* initializer is used as struct initializer */
--                      var st = (Struct) list.target_type.data_type;
--
--                      var field_it = st.get_fields ().iterator ();
--                      foreach (Expression e in list.get_initializers ()) {
--                              Field field = null;
--                              while (field == null) {
--                                      if (!field_it.next ()) {
--                                              list.error = true;
--                                              Report.error (e.source_reference, "too many expressions in initializer list for `%s'".printf (list.target_type.to_string ()));
--                                              return;
--                                      }
--                                      field = field_it.get ();
--                                      if (field.binding != MemberBinding.INSTANCE) {
--                                              // we only initialize instance fields
--                                              field = null;
--                                      }
--                              }
--
--                              e.target_type = field.field_type.copy ();
--                              if (!list.target_type.value_owned) {
--                                      e.target_type.value_owned = false;
--                              }
--                      }
--              } else {
--                      list.error = true;
--                      Report.error (list.source_reference, "initializer list used for `%s', which is neither array nor struct".printf (list.target_type.to_string ()));
--                      return;
--              }
--
--              list.accept_children (this);
--
--              bool error = false;
--              foreach (Expression e in list.get_initializers ()) {
--                      if (e.value_type == null) {
--                              error = true;
--                              continue;
--                      }
--
--                      var unary = e as UnaryExpression;
--                      if (unary != null && (unary.operator == UnaryOperator.REF || unary.operator == UnaryOperator.OUT)) {
--                              // TODO check type for ref and out expressions
--                      } else if (!e.value_type.compatible (e.target_type)) {
--                              error = true;
--                              e.error = true;
--                              Report.error (e.source_reference, "Expected initializer of type `%s' but got `%s'".printf (e.target_type.to_string (), e.value_type.to_string ()));
--                      }
--              }
--
--              if (!error) {
--                      /* everything seems to be correct */
--                      list.value_type = list.target_type;
--              }
-+              list.check (this);
-       }
-       public override void visit_expression_statement (ExpressionStatement stmt) {
--              if (stmt.expression.error) {
--                      // ignore inner error
--                      stmt.error = true;
--                      return;
--              }
--
--              stmt.add_error_types (stmt.expression.get_error_types ());
-+              stmt.check (this);
-       }
-       public override void visit_if_statement (IfStatement stmt) {
--              stmt.accept_children (this);
--
--              if (stmt.condition.error) {
--                      /* if there was an error in the condition, skip this check */
--                      stmt.error = true;
--                      return;
--              }
--
--              if (!stmt.condition.value_type.compatible (bool_type)) {
--                      stmt.error = true;
--                      Report.error (stmt.condition.source_reference, "Condition must be boolean");
--                      return;
--              }
--
--              stmt.add_error_types (stmt.condition.get_error_types ());
--              stmt.add_error_types (stmt.true_statement.get_error_types ());
--
--              if (stmt.false_statement != null) {
--                      stmt.add_error_types (stmt.false_statement.get_error_types ());
--              }
-+              stmt.check (this);
-       }
-       public override void visit_switch_section (SwitchSection section) {
--              foreach (SwitchLabel label in section.get_labels ()) {
--                      label.accept (this);
--              }
--
--              section.owner = current_symbol.scope;
--              current_symbol = section;
--
--              foreach (Statement st in section.get_statements ()) {
--                      st.accept (this);
--              }
--
--              foreach (LocalVariable local in section.get_local_variables ()) {
--                      local.active = false;
--              }
--
--              current_symbol = current_symbol.parent_symbol;
-+              section.check (this);
-       }
-       public override void visit_while_statement (WhileStatement stmt) {
--              stmt.accept_children (this);
--
--              if (stmt.condition.error) {
--                      /* if there was an error in the condition, skip this check */
--                      stmt.error = true;
--                      return;
--              }
--
--              if (!stmt.condition.value_type.compatible (bool_type)) {
--                      stmt.error = true;
--                      Report.error (stmt.condition.source_reference, "Condition must be boolean");
--                      return;
--              }
--
--              stmt.add_error_types (stmt.condition.get_error_types ());
--              stmt.add_error_types (stmt.body.get_error_types ());
-+              stmt.check (this);
-       }
-       public override void visit_do_statement (DoStatement stmt) {
--              stmt.accept_children (this);
--
--              if (stmt.condition.error) {
--                      /* if there was an error in the condition, skip this check */
--                      stmt.error = true;
--                      return;
--              }
--
--              if (!stmt.condition.value_type.compatible (bool_type)) {
--                      stmt.error = true;
--                      Report.error (stmt.condition.source_reference, "Condition must be boolean");
--                      return;
--              }
--
--              stmt.add_error_types (stmt.condition.get_error_types ());
--              stmt.add_error_types (stmt.body.get_error_types ());
-+              stmt.check (this);
-       }
-       public override void visit_for_statement (ForStatement stmt) {
--              stmt.accept_children (this);
--
--              if (stmt.condition != null && stmt.condition.error) {
--                      /* if there was an error in the condition, skip this check */
--                      stmt.error = true;
--                      return;
--              }
--
--              if (stmt.condition != null && !stmt.condition.value_type.compatible (bool_type)) {
--                      stmt.error = true;
--                      Report.error (stmt.condition.source_reference, "Condition must be boolean");
--                      return;
--              }
--
--              if (stmt.condition != null) {
--                      stmt.add_error_types (stmt.condition.get_error_types ());
--              }
--
--              stmt.add_error_types (stmt.body.get_error_types ());
--              foreach (Expression exp in stmt.get_initializer ()) {
--                      stmt.add_error_types (exp.get_error_types ());
--              }
--              foreach (Expression exp in stmt.get_iterator ()) {
--                      stmt.add_error_types (exp.get_error_types ());
--              }
-+              stmt.check (this);
-       }
-       public override void visit_foreach_statement (ForeachStatement stmt) {
--              // analyze collection expression first, used for type inference
--              stmt.collection.accept (this);
--
--              if (stmt.collection.error) {
--                      // ignore inner error
--                      stmt.error = true;
--                      return;
--              } else if (stmt.collection.value_type == null) {
--                      Report.error (stmt.collection.source_reference, "invalid collection expression");
--                      stmt.error = true;
--                      return;
--              }
--
--              var collection_type = stmt.collection.value_type.copy ();
--              stmt.collection.target_type = collection_type.copy ();
--              
--              DataType element_data_type = null;
--              bool element_owned = false;
--
--              if (collection_type.is_array ()) {
--                      var array_type = (ArrayType) collection_type;
--                      element_data_type = array_type.element_type;
--              } else if (collection_type.compatible (glist_type) || collection_type.compatible (gslist_type)) {
--                      if (collection_type.get_type_arguments ().size > 0) {
--                              element_data_type = (DataType) collection_type.get_type_arguments ().get (0);
--                      }
--              } else if (iterable_type != null && collection_type.compatible (iterable_type)) {
--                      element_owned = true;
--
--                      if (list_type == null || !collection_type.compatible (new ObjectType (list_type))) {
--                              // don't use iterator objects for lists for performance reasons
--                              var foreach_iterator_type = new ObjectType (iterator_type);
--                              foreach_iterator_type.value_owned = true;
--                              foreach_iterator_type.add_type_argument (stmt.type_reference);
--                              stmt.iterator_variable = new LocalVariable (foreach_iterator_type, "%s_it".printf (stmt.variable_name));
--
--                              stmt.add_local_variable (stmt.iterator_variable);
--                              stmt.iterator_variable.active = true;
--                      }
--
--                      var it_method = (Method) iterable_type.data_type.scope.lookup ("iterator");
--                      if (it_method.return_type.get_type_arguments ().size > 0) {
--                              var type_arg = it_method.return_type.get_type_arguments ().get (0);
--                              if (type_arg.type_parameter != null) {
--                                      element_data_type = SemanticAnalyzer.get_actual_type (collection_type, it_method, type_arg, stmt);
--                              } else {
--                                      element_data_type = type_arg;
--                              }
--                      }
--              } else {
--                      stmt.error = true;
--                      Report.error (stmt.source_reference, "Gee.List not iterable");
--                      return;
--              }
--
--              if (element_data_type == null) {
--                      stmt.error = true;
--                      Report.error (stmt.collection.source_reference, "missing type argument for collection");
--                      return;
--              }
--
--              // analyze element type
--              if (stmt.type_reference == null) {
--                      // var type
--                      stmt.type_reference = element_data_type.copy ();
--              } else if (!element_data_type.compatible (stmt.type_reference)) {
--                      stmt.error = true;
--                      Report.error (stmt.source_reference, "Foreach: Cannot convert from `%s' to `%s'".printf (element_data_type.to_string (), stmt.type_reference.to_string ()));
--                      return;
--              } else if (element_data_type.is_disposable () && element_owned && !stmt.type_reference.value_owned) {
--                      stmt.error = true;
--                      Report.error (stmt.source_reference, "Foreach: Invalid assignment from owned expression to unowned variable");
--                      return;
--              }
--              
--              current_source_file.add_type_dependency (stmt.type_reference, SourceFileDependencyType.SOURCE);
--
--              stmt.element_variable = new LocalVariable (stmt.type_reference, stmt.variable_name);
--
--              stmt.body.scope.add (stmt.variable_name, stmt.element_variable);
--
--              stmt.body.add_local_variable (stmt.element_variable);
--              stmt.element_variable.active = true;
--
--              // analyze body
--              stmt.owner = current_symbol.scope;
--              current_symbol = stmt;
--
--              stmt.body.accept (this);
--
--              foreach (LocalVariable local in stmt.get_local_variables ()) {
--                      local.active = false;
--              }
--
--              current_symbol = current_symbol.parent_symbol;
--
--              stmt.collection_variable = new LocalVariable (collection_type, "%s_collection".printf (stmt.variable_name));
--
--              stmt.add_local_variable (stmt.collection_variable);
--              stmt.collection_variable.active = true;
--
--
--              stmt.add_error_types (stmt.collection.get_error_types ());
--              stmt.add_error_types (stmt.body.get_error_types ());
-+              stmt.check (this);
-       }
-       public override void visit_return_statement (ReturnStatement stmt) {
--              if (stmt.return_expression != null) {
--                      stmt.return_expression.target_type = current_return_type;
--              }
--
--              stmt.accept_children (this);
--
--              if (stmt.return_expression != null && stmt.return_expression.error) {
--                      // ignore inner error
--                      stmt.error = true;
--                      return;
--              }
--
--              if (current_return_type == null) {
--                      stmt.error = true;
--                      Report.error (stmt.source_reference, "Return not allowed in this context");
--                      return;
--              }
--
--              if (stmt.return_expression == null) {
--                      if (current_return_type is VoidType) {
--                              return;
--                      } else {
--                              stmt.error = true;
--                              Report.error (stmt.source_reference, "Return without value in non-void function");
--                              return;
--                      }
--              }
--
--              if (current_return_type is VoidType) {
--                      Report.error (stmt.source_reference, "Return with value in void function");
--                      return;
--              }
--
--              if (stmt.return_expression.value_type == null) {
--                      stmt.error = true;
--                      Report.error (stmt.source_reference, "Invalid expression in return value");
--                      return;
--              }
--
--              if (!stmt.return_expression.value_type.compatible (current_return_type)) {
--                      stmt.error = true;
--                      Report.error (stmt.source_reference, "Return: Cannot convert from `%s' to `%s'".printf (stmt.return_expression.value_type.to_string (), current_return_type.to_string ()));
--                      return;
--              }
--
--              if (stmt.return_expression.value_type.is_disposable () &&
--                  !current_return_type.value_owned) {
--                      stmt.error = true;
--                      Report.error (stmt.source_reference, "Return value transfers ownership but method return type hasn't been declared to transfer ownership");
--                      return;
--              }
--
--              if (stmt.return_expression.symbol_reference is LocalVariable &&
--                  stmt.return_expression.value_type.is_disposable () &&
--                  !current_return_type.value_owned) {
--                      Report.warning (stmt.source_reference, "Local variable with strong reference used as return value and method return type hasn't been declared to transfer ownership");
--              }
--
--              if (context.non_null && stmt.return_expression is NullLiteral
--                  && !current_return_type.nullable) {
--                      Report.warning (stmt.source_reference, "`null' incompatible with return type `%s`".printf (current_return_type.to_string ()));
--              }
--
--              stmt.add_error_types (stmt.return_expression.get_error_types ());
-+              stmt.check (this);
-       }
-       public override void visit_yield_statement (YieldStatement stmt) {
-@@ -1203,178 +276,27 @@
-       }
-       public override void visit_throw_statement (ThrowStatement stmt) {
--              stmt.error_expression.target_type = new ErrorType (null, null, stmt.source_reference);
--              stmt.error_expression.target_type.value_owned = true;
--
--              stmt.accept_children (this);
--
--              var error_type = stmt.error_expression.value_type.copy ();
--              error_type.source_reference = stmt.source_reference;
--
--              stmt.add_error_type (error_type);
-+              stmt.check (this);
-       }
-       public override void visit_try_statement (TryStatement stmt) {
--              stmt.accept_children (this);
-+              stmt.check (this);
-       }
-       public override void visit_catch_clause (CatchClause clause) {
--              if (clause.error_type != null) {
--                      current_source_file.add_type_dependency (clause.error_type, SourceFileDependencyType.SOURCE);
--
--                      clause.error_variable = new LocalVariable (clause.error_type.copy (), clause.variable_name);
--
--                      clause.body.scope.add (clause.variable_name, clause.error_variable);
--                      clause.body.add_local_variable (clause.error_variable);
--              } else {
--                      clause.error_type = new ErrorType (null, null, clause.source_reference);
--              }
--
--              clause.accept_children (this);
-+              clause.check (this);
-       }
-       public override void visit_lock_statement (LockStatement stmt) {
--              /* resource must be a member access and denote a Lockable */
--              if (!(stmt.resource is MemberAccess && stmt.resource.symbol_reference is Lockable)) {
--                      stmt.error = true;
--                      stmt.resource.error = true;
--                      Report.error (stmt.resource.source_reference, "Expression is either not a member access or does not denote a lockable member");
--                      return;
--              }
--
--              /* parent symbol must be the current class */
--              if (stmt.resource.symbol_reference.parent_symbol != current_class) {
--                      stmt.error = true;
--                      stmt.resource.error = true;
--                      Report.error (stmt.resource.source_reference, "Only members of the current class are lockable");
--              }
--
--              ((Lockable) stmt.resource.symbol_reference).set_lock_used (true);
-+              stmt.check (this);
-       }
-       public override void visit_delete_statement (DeleteStatement stmt) {
--              stmt.accept_children (this);
--
--              if (stmt.expression.error) {
--                      // if there was an error in the inner expression, skip this check
--                      return;
--              }
--
--              if (!(stmt.expression.value_type is PointerType)) {
--                      stmt.error = true;
--                      Report.error (stmt.source_reference, "delete operator not supported for `%s'".printf (stmt.expression.value_type.to_string ()));
--              }
-+              stmt.check (this);
-       }
--      private int create_sizes_from_initializer_list (InitializerList il, int rank, Gee.List<Literal> sl) {
--              var init = new IntegerLiteral (il.size.to_string (), il.source_reference);
--              init.accept (this);
--              sl.add (init);
--
--              int subsize = -1;
--              foreach (Expression e in il.get_initializers ()) {
--                      if (e is InitializerList) {
--                              if (rank == 1) {
--                                      il.error = true;
--                                      e.error = true;
--                                      Report.error (e.source_reference, "Expected array element, got array initializer list");
--                                      return -1;
--                              }
--                              int size = create_sizes_from_initializer_list ((InitializerList)e, rank - 1, sl);
--                              if (size == -1) {
--                                      return -1;
--                              }
--                              if (subsize >= 0 && subsize != size) {
--                                      il.error = true;
--                                      Report.error (il.source_reference, "Expected initializer list of size %d, got size %d".printf (subsize, size));
--                                      return -1;
--                              } else {
--                                      subsize = size;
--                              }
--                      } else {
--                              if (rank != 1) {
--                                      il.error = true;
--                                      e.error = true;
--                                      Report.error (e.source_reference, "Expected array initializer list, got array element");
--                                      return -1;
--                              }
--                      }
--              }
--              return il.size;
--      }
--
--      /**
--       * Visit operations called for array creation expresions.
--       *
--       * @param expr an array creation expression
--       */
-       public override void visit_array_creation_expression (ArrayCreationExpression expr) {
--              Gee.List<Expression> size = expr.get_sizes ();
--              var initlist = expr.initializer_list;
--
--              if (expr.element_type != null) {
--                      expr.element_type.accept (this);
--              }
--
--              foreach (Expression e in size) {
--                      e.accept (this);
--              }
--
--              var calc_sizes = new ArrayList<Literal> ();
--              if (initlist != null) {
--                      initlist.target_type = new ArrayType (expr.element_type, expr.rank, expr.source_reference);
--
--                      initlist.accept (this);
--
--                      var ret = create_sizes_from_initializer_list (initlist, expr.rank, calc_sizes);
--                      if (ret == -1) {
--                              expr.error = true;
--                      }
--              }
--
--              if (size.size > 0) {
--                      /* check for errors in the size list */
--                      foreach (Expression e in size) {
--                              if (e.value_type == null) {
--                                      /* return on previous error */
--                                      return;
--                              } else if (!(e.value_type.data_type is Struct) || !((Struct) e.value_type.data_type).is_integer_type ()) {
--                                      expr.error = true;
--                                      Report.error (e.source_reference, "Expression of integer type expected");
--                              }
--                      }
--              } else {
--                      if (initlist == null) {
--                              expr.error = true;
--                              /* this is an internal error because it is already handeld by the parser */
--                              Report.error (expr.source_reference, "internal error: initializer list expected");
--                      } else {
--                              foreach (Expression size in calc_sizes) {
--                                      expr.append_size (size);
--                              }
--                      }
--              }
--
--              if (expr.error) {
--                      return;
--              }
--
--              /* check for wrong elements inside the initializer */
--              if (expr.initializer_list != null && expr.initializer_list.value_type == null) {
--                      return;
--              }
--
--              /* try to construct the type of the array */
--              if (expr.element_type == null) {
--                      expr.error = true;
--                      Report.error (expr.source_reference, "Cannot determine the element type of the created array");
--                      return;
--              }
--
--              expr.element_type.value_owned = true;
--
--              expr.value_type = new ArrayType (expr.element_type, expr.rank, expr.source_reference);
--              expr.value_type.value_owned = true;
-+              expr.check (this);
-       }
-       public override void visit_boolean_literal (BooleanLiteral expr) {
-@@ -1401,7 +323,7 @@
-               expr.value_type = new NullType (expr.source_reference);
-       }
--      private DataType? get_value_type_for_symbol (Symbol sym, bool lvalue) {
-+      public DataType? get_value_type_for_symbol (Symbol sym, bool lvalue) {
-               if (sym is Field) {
-                       var f = (Field) sym;
-                       var type = f.field_type.copy ();
-@@ -1525,346 +447,7 @@
-       }
-       
-       public override void visit_member_access (MemberAccess expr) {
--              Symbol base_symbol = null;
--              FormalParameter this_parameter = null;
--              bool may_access_instance_members = false;
--
--              expr.symbol_reference = null;
--
--              if (expr.qualified) {
--                      base_symbol = root_symbol;
--                      expr.symbol_reference = root_symbol.scope.lookup (expr.member_name);
--              } else if (expr.inner == null) {
--                      if (expr.member_name == "this") {
--                              if (!is_in_instance_method ()) {
--                                      expr.error = true;
--                                      Report.error (expr.source_reference, "This access invalid outside of instance methods");
--                                      return;
--                              }
--                      }
--
--                      base_symbol = current_symbol;
--
--                      var sym = current_symbol;
--                      while (sym != null && expr.symbol_reference == null) {
--                              if (this_parameter == null) {
--                                      if (sym is CreationMethod) {
--                                              var cm = (CreationMethod) sym;
--                                              this_parameter = cm.this_parameter;
--                                              may_access_instance_members = true;
--                                      } else if (sym is Property) {
--                                              var prop = (Property) sym;
--                                              this_parameter = prop.this_parameter;
--                                              may_access_instance_members = true;
--                                      } else if (sym is Constructor) {
--                                              var c = (Constructor) sym;
--                                              this_parameter = c.this_parameter;
--                                              may_access_instance_members = true;
--                                      } else if (sym is Destructor) {
--                                              var d = (Destructor) sym;
--                                              this_parameter = d.this_parameter;
--                                              may_access_instance_members = true;
--                                      } else if (sym is Method) {
--                                              var m = (Method) sym;
--                                              this_parameter = m.this_parameter;
--                                              may_access_instance_members = (m.binding == MemberBinding.INSTANCE);
--                                      }
--                              }
--
--                              expr.symbol_reference = symbol_lookup_inherited (sym, expr.member_name);
--                              sym = sym.parent_symbol;
--                      }
--
--                      if (expr.symbol_reference == null) {
--                              foreach (UsingDirective ns in current_using_directives) {
--                                      var local_sym = ns.namespace_symbol.scope.lookup (expr.member_name);
--                                      if (local_sym != null) {
--                                              if (expr.symbol_reference != null) {
--                                                      expr.error = true;
--                                                      Report.error (expr.source_reference, "`%s' is an ambiguous reference between `%s' and `%s'".printf (expr.member_name, expr.symbol_reference.get_full_name (), local_sym.get_full_name ()));
--                                                      return;
--                                              }
--                                              expr.symbol_reference = local_sym;
--                                      }
--                              }
--                      }
--              } else {
--                      if (expr.inner.error) {
--                              /* if there was an error in the inner expression, skip this check */
--                              expr.error = true;
--                              return;
--                      }
--
--                      if (expr.pointer_member_access) {
--                              var pointer_type = expr.inner.value_type as PointerType;
--                              if (pointer_type != null && pointer_type.base_type is ValueType) {
--                                      // transform foo->bar to (*foo).bar
--                                      expr.inner = new PointerIndirection (expr.inner, expr.source_reference);
--                                      expr.inner.accept (this);
--                                      expr.pointer_member_access = false;
--                              }
--                      }
--
--                      if (expr.inner is MemberAccess) {
--                              var ma = (MemberAccess) expr.inner;
--                              if (ma.prototype_access) {
--                                      expr.error = true;
--                                      Report.error (expr.source_reference, "Access to instance member `%s' denied".printf (expr.inner.symbol_reference.get_full_name ()));
--                                      return;
--                              }
--                      }
--
--                      if (expr.inner is MemberAccess || expr.inner is BaseAccess) {
--                              base_symbol = expr.inner.symbol_reference;
--
--                              if (expr.symbol_reference == null && (base_symbol is Namespace || base_symbol is TypeSymbol)) {
--                                      expr.symbol_reference = base_symbol.scope.lookup (expr.member_name);
--                                      if (expr.inner is BaseAccess) {
--                                              // inner expression is base access
--                                              // access to instance members of the base type possible
--                                              may_access_instance_members = true;
--                                      }
--                              }
--                      }
--
--                      if (expr.symbol_reference == null && expr.inner.value_type != null) {
--                              if (expr.pointer_member_access) {
--                                      expr.symbol_reference = expr.inner.value_type.get_pointer_member (expr.member_name);
--                              } else {
--                                      if (expr.inner.value_type.data_type != null) {
--                                              base_symbol = expr.inner.value_type.data_type;
--                                      }
--                                      expr.symbol_reference = expr.inner.value_type.get_member (expr.member_name);
--                              }
--                              if (expr.symbol_reference != null) {
--                                      // inner expression is variable, field, or parameter
--                                      // access to instance members of the corresponding type possible
--                                      may_access_instance_members = true;
--                              }
--                      }
--
--                      if (expr.symbol_reference == null && expr.inner.value_type != null && expr.inner.value_type.is_dynamic) {
--                              // allow late bound members for dynamic types
--                              var dynamic_object_type = (ObjectType) expr.inner.value_type;
--                              if (expr.parent_node is InvocationExpression) {
--                                      var invoc = (InvocationExpression) expr.parent_node;
--                                      if (invoc.call == expr) {
--                                              // dynamic method
--                                              DataType ret_type;
--                                              if (invoc.target_type != null) {
--                                                      ret_type = invoc.target_type.copy ();
--                                                      ret_type.value_owned = true;
--                                              } else if (invoc.parent_node is ExpressionStatement) {
--                                                      ret_type = new VoidType ();
--                                              } else {
--                                                      // expect dynamic object of the same type
--                                                      ret_type = expr.inner.value_type.copy ();
--                                              }
--                                              var m = new DynamicMethod (expr.inner.value_type, expr.member_name, ret_type, expr.source_reference);
--                                              m.invocation = invoc;
--                                              m.add_error_type (new ErrorType (null, null));
--                                              m.access = SymbolAccessibility.PUBLIC;
--                                              m.add_parameter (new FormalParameter.with_ellipsis ());
--                                              dynamic_object_type.type_symbol.scope.add (null, m);
--                                              expr.symbol_reference = m;
--                                      }
--                              } else if (expr.parent_node is Assignment) {
--                                      var a = (Assignment) expr.parent_node;
--                                      if (a.left == expr
--                                          && (a.operator == AssignmentOperator.ADD
--                                              || a.operator == AssignmentOperator.SUB)) {
--                                              // dynamic signal
--                                              var s = new DynamicSignal (expr.inner.value_type, expr.member_name, new VoidType (), expr.source_reference);
--                                              s.handler = a.right;
--                                              s.access = SymbolAccessibility.PUBLIC;
--                                              dynamic_object_type.type_symbol.scope.add (null, s);
--                                              expr.symbol_reference = s;
--                                      } else if (a.left == expr) {
--                                              // dynamic property assignment
--                                              var prop = new DynamicProperty (expr.inner.value_type, expr.member_name, expr.source_reference);
--                                              prop.access = SymbolAccessibility.PUBLIC;
--                                              prop.set_accessor = new PropertyAccessor (false, true, false, null, null);
--                                              prop.set_accessor.access = SymbolAccessibility.PUBLIC;
--                                              prop.owner = expr.inner.value_type.data_type.scope;
--                                              dynamic_object_type.type_symbol.scope.add (null, prop);
--                                              expr.symbol_reference = prop;
--                                      }
--                              }
--                              if (expr.symbol_reference == null) {
--                                      // dynamic property read access
--                                      var prop = new DynamicProperty (expr.inner.value_type, expr.member_name, expr.source_reference);
--                                      if (expr.target_type != null) {
--                                              prop.property_type = expr.target_type;
--                                      } else {
--                                              // expect dynamic object of the same type
--                                              prop.property_type = expr.inner.value_type.copy ();
--                                      }
--                                      prop.access = SymbolAccessibility.PUBLIC;
--                                      prop.get_accessor = new PropertyAccessor (true, false, false, null, null);
--                                      prop.get_accessor.access = SymbolAccessibility.PUBLIC;
--                                      prop.owner = expr.inner.value_type.data_type.scope;
--                                      dynamic_object_type.type_symbol.scope.add (null, prop);
--                                      expr.symbol_reference = prop;
--                              }
--                              if (expr.symbol_reference != null) {
--                                      may_access_instance_members = true;
--                              }
--                      }
--              }
--
--              if (expr.symbol_reference == null) {
--                      expr.error = true;
--
--                      string base_type_name = "(null)";
--                      if (expr.inner != null && expr.inner.value_type != null) {
--                              base_type_name = expr.inner.value_type.to_string ();
--                      } else if (base_symbol != null) {
--                              base_type_name = base_symbol.get_full_name ();
--                      }
--
--                      Report.error (expr.source_reference, "The name `%s' does not exist in the context of `%s'".printf (expr.member_name, base_type_name));
--                      return;
--              }
--
--              var member = expr.symbol_reference;
--              var access = SymbolAccessibility.PUBLIC;
--              bool instance = false;
--              bool klass = false;
--              if (member is Field) {
--                      var f = (Field) member;
--                      access = f.access;
--                      instance = (f.binding == MemberBinding.INSTANCE);
--                      klass = (f.binding == MemberBinding.CLASS);
--              } else if (member is Method) {
--                      var m = (Method) member;
--                      access = m.access;
--                      if (!(m is CreationMethod)) {
--                              instance = (m.binding == MemberBinding.INSTANCE);
--                      }
--                      klass = (m.binding == MemberBinding.CLASS);
--              } else if (member is Property) {
--                      var prop = (Property) member;
--                      if (!prop.check (this)) {
--                              expr.error = true;
--                              return;
--                      }
--                      access = prop.access;
--                      if (expr.lvalue) {
--                              if (prop.set_accessor == null) {
--                                      expr.error = true;
--                                      Report.error (expr.source_reference, "Property `%s' is read-only".printf (prop.get_full_name ()));
--                                      return;
--                              }
--                              if (prop.access == SymbolAccessibility.PUBLIC) {
--                                      access = prop.set_accessor.access;
--                              } else if (prop.access == SymbolAccessibility.PROTECTED
--                                         && prop.set_accessor.access != SymbolAccessibility.PUBLIC) {
--                                      access = prop.set_accessor.access;
--                              }
--                      } else {
--                              if (prop.get_accessor == null) {
--                                      expr.error = true;
--                                      Report.error (expr.source_reference, "Property `%s' is write-only".printf (prop.get_full_name ()));
--                                      return;
--                              }
--                              if (prop.access == SymbolAccessibility.PUBLIC) {
--                                      access = prop.get_accessor.access;
--                              } else if (prop.access == SymbolAccessibility.PROTECTED
--                                         && prop.get_accessor.access != SymbolAccessibility.PUBLIC) {
--                                      access = prop.get_accessor.access;
--                              }
--                      }
--                      instance = (prop.binding == MemberBinding.INSTANCE);
--              } else if (member is Signal) {
--                      instance = true;
--              }
--
--              if (access == SymbolAccessibility.PRIVATE) {
--                      var target_type = member.parent_symbol;
--
--                      bool in_target_type = false;
--                      for (Symbol this_symbol = current_symbol; this_symbol != null; this_symbol = this_symbol.parent_symbol) {
--                              if (target_type == this_symbol) {
--                                      in_target_type = true;
--                                      break;
--                              }
--                      }
--
--                      if (!in_target_type) {
--                              expr.error = true;
--                              Report.error (expr.source_reference, "Access to private member `%s' denied".printf (member.get_full_name ()));
--                              return;
--                      }
--              }
--              if ((instance || klass) && !may_access_instance_members) {
--                      expr.prototype_access = true;
--
--                      if (expr.symbol_reference is Method) {
--                              // also set static type for prototype access
--                              // required when using instance methods as delegates in constants
--                              // TODO replace by MethodPrototype
--                              expr.value_type = get_value_type_for_symbol (expr.symbol_reference, expr.lvalue);
--                      } else if (expr.symbol_reference is Field) {
--                              expr.value_type = new FieldPrototype ((Field) expr.symbol_reference);
--                      }
--              } else {
--                      // implicit this access
--                      if (instance && expr.inner == null) {
--                              expr.inner = new MemberAccess (null, "this", expr.source_reference);
--                              expr.inner.value_type = this_parameter.parameter_type.copy ();
--                              expr.inner.symbol_reference = this_parameter;
--                      }
--
--                      expr.value_type = get_value_type_for_symbol (expr.symbol_reference, expr.lvalue);
--
--                      // resolve generic return values
--                      if (expr.value_type != null && expr.value_type.type_parameter != null) {
--                              if (expr.inner != null) {
--                                      expr.value_type = get_actual_type (expr.inner.value_type, expr.symbol_reference, expr.value_type, expr);
--                                      if (expr.value_type == null) {
--                                              return;
--                                      }
--                              }
--                      }
--
--                      if (expr.symbol_reference is Method) {
--                              var m = (Method) expr.symbol_reference;
--
--                              Method base_method;
--                              if (m.base_method != null) {
--                                      base_method = m.base_method;
--                              } else if (m.base_interface_method != null) {
--                                      base_method = m.base_interface_method;
--                              } else {
--                                      base_method = m;
--                              }
--
--                              if (instance && base_method.parent_symbol != null) {
--                                      expr.inner.target_type = get_data_type_for_symbol ((TypeSymbol) base_method.parent_symbol);
--                              }
--                      } else if (expr.symbol_reference is Property) {
--                              var prop = (Property) expr.symbol_reference;
--
--                              Property base_property;
--                              if (prop.base_property != null) {
--                                      base_property = prop.base_property;
--                              } else if (prop.base_interface_property != null) {
--                                      base_property = prop.base_interface_property;
--                              } else {
--                                      base_property = prop;
--                              }
--
--                              if (instance && base_property.parent_symbol != null) {
--                                      expr.inner.target_type = get_data_type_for_symbol ((TypeSymbol) base_property.parent_symbol);
--                              }
--                      } else if ((expr.symbol_reference is Field
--                                  || expr.symbol_reference is Signal)
--                                 && instance && expr.symbol_reference.parent_symbol != null) {
--                              expr.inner.target_type = get_data_type_for_symbol ((TypeSymbol) expr.symbol_reference.parent_symbol);
--                      }
--              }
--
--              current_source_file.add_symbol_dependency (expr.symbol_reference, SourceFileDependencyType.SOURCE);
-+              expr.check (this);
-       }
-       public static DataType get_data_type_for_symbol (TypeSymbol sym) {
-@@ -1889,300 +472,10 @@
-       }
-       public override void visit_invocation_expression (InvocationExpression expr) {
--              expr.call.accept (this);
--
--              if (expr.call.error) {
--                      /* if method resolving didn't succeed, skip this check */
--                      expr.error = true;
--                      return;
--              }
--
--              if (expr.call is MemberAccess) {
--                      var ma = (MemberAccess) expr.call;
--                      if (ma.prototype_access) {
--                              expr.error = true;
--                              Report.error (expr.source_reference, "Access to instance member `%s' denied".printf (expr.call.symbol_reference.get_full_name ()));
--                              return;
--                      }
--              }
--
--              var mtype = expr.call.value_type;
--
--              if (mtype is ObjectType) {
--                      // constructor chain-up
--                      var cm = find_current_method () as CreationMethod;
--                      assert (cm != null);
--                      if (cm.chain_up) {
--                              expr.error = true;
--                              Report.error (expr.source_reference, "Multiple constructor calls in the same constructor are not permitted");
--                              return;
--                      }
--                      cm.chain_up = true;
--              }
--
--              // check for struct construction
--              if (expr.call is MemberAccess &&
--                  ((expr.call.symbol_reference is CreationMethod
--                    && expr.call.symbol_reference.parent_symbol is Struct)
--                   || expr.call.symbol_reference is Struct)) {
--                      var struct_creation_expression = new ObjectCreationExpression ((MemberAccess) expr.call, expr.source_reference);
--                      struct_creation_expression.struct_creation = true;
--                      foreach (Expression arg in expr.get_argument_list ()) {
--                              struct_creation_expression.add_argument (arg);
--                      }
--                      struct_creation_expression.target_type = expr.target_type;
--                      replaced_nodes.add (expr);
--                      expr.parent_node.replace_expression (expr, struct_creation_expression);
--                      struct_creation_expression.accept (this);
--                      return;
--              } else if (expr.call is MemberAccess
--                         && expr.call.symbol_reference is CreationMethod) {
--                      // constructor chain-up
--                      var cm = find_current_method () as CreationMethod;
--                      assert (cm != null);
--                      if (cm.chain_up) {
--                              expr.error = true;
--                              Report.error (expr.source_reference, "Multiple constructor calls in the same constructor are not permitted");
--                              return;
--                      }
--                      cm.chain_up = true;
--              }
--
--              Gee.List<FormalParameter> params;
--
--              if (mtype != null && mtype.is_invokable ()) {
--                      params = mtype.get_parameters ();
--              } else {
--                      expr.error = true;
--                      Report.error (expr.source_reference, "invocation not supported in this context");
--                      return;
--              }
--
--              Expression last_arg = null;
--
--              var args = expr.get_argument_list ();
--              Iterator<Expression> arg_it = args.iterator ();
--              foreach (FormalParameter param in params) {
--                      if (param.ellipsis) {
--                              break;
--                      }
--
--                      if (arg_it.next ()) {
--                              Expression arg = arg_it.get ();
--
--                              /* store expected type for callback parameters */
--                              arg.target_type = param.parameter_type;
--
--                              // resolve generic type parameters
--                              var ma = expr.call as MemberAccess;
--                              if (arg.target_type.type_parameter != null) {
--                                      if (ma != null && ma.inner != null) {
--                                              arg.target_type = get_actual_type (ma.inner.value_type, ma.symbol_reference, arg.target_type, arg);
--                                              assert (arg.target_type != null);
--                                      }
--                              }
--
--                              last_arg = arg;
--                      }
--              }
--
--              // printf arguments
--              if (mtype is MethodType && ((MethodType) mtype).method_symbol.printf_format) {
--                      StringLiteral format_literal = null;
--                      if (last_arg != null) {
--                              // use last argument as format string
--                              format_literal = last_arg as StringLiteral;
--                      } else {
--                              // use instance as format string for string.printf (...)
--                              var ma = expr.call as MemberAccess;
--                              if (ma != null) {
--                                      format_literal = ma.inner as StringLiteral;
--                              }
--                      }
--                      if (format_literal != null) {
--                              string format = format_literal.eval ();
--
--                              bool unsupported_format = false;
--
--                              weak string format_it = format;
--                              unichar c = format_it.get_char ();
--                              while (c != '\0') {
--                                      if (c != '%') {
--                                              format_it = format_it.next_char ();
--                                              c = format_it.get_char ();
--                                              continue;
--                                      }
--
--                                      format_it = format_it.next_char ();
--                                      c = format_it.get_char ();
--                                      // flags
--                                      while (c == '#' || c == '0' || c == '-' || c == ' ' || c == '+') {
--                                              format_it = format_it.next_char ();
--                                              c = format_it.get_char ();
--                                      }
--                                      // field width
--                                      while (c >= '0' && c <= '9') {
--                                              format_it = format_it.next_char ();
--                                              c = format_it.get_char ();
--                                      }
--                                      // precision
--                                      if (c == '.') {
--                                              format_it = format_it.next_char ();
--                                              c = format_it.get_char ();
--                                              while (c >= '0' && c <= '9') {
--                                                      format_it = format_it.next_char ();
--                                                      c = format_it.get_char ();
--                                              }
--                                      }
--                                      // length modifier
--                                      int length = 0;
--                                      if (c == 'h') {
--                                              length = -1;
--                                              format_it = format_it.next_char ();
--                                              c = format_it.get_char ();
--                                              if (c == 'h') {
--                                                      length = -2;
--                                                      format_it = format_it.next_char ();
--                                                      c = format_it.get_char ();
--                                              }
--                                      } else if (c == 'l') {
--                                              length = 1;
--                                              format_it = format_it.next_char ();
--                                              c = format_it.get_char ();
--                                      } else if (c == 'z') {
--                                              length = 2;
--                                              format_it = format_it.next_char ();
--                                              c = format_it.get_char ();
--                                      }
--                                      // conversion specifier
--                                      DataType param_type = null;
--                                      if (c == 'd' || c == 'i' || c == 'c') {
--                                              // integer
--                                              if (length == -2) {
--                                                      param_type = int8_type;
--                                              } else if (length == -1) {
--                                                      param_type = short_type;
--                                              } else if (length == 0) {
--                                                      param_type = int_type;
--                                              } else if (length == 1) {
--                                                      param_type = long_type;
--                                              } else if (length == 2) {
--                                                      param_type = ssize_t_type;
--                                              }
--                                      } else if (c == 'o' || c == 'u' || c == 'x' || c == 'X') {
--                                              // unsigned integer
--                                              if (length == -2) {
--                                                      param_type = uchar_type;
--                                              } else if (length == -1) {
--                                                      param_type = ushort_type;
--                                              } else if (length == 0) {
--                                                      param_type = uint_type;
--                                              } else if (length == 1) {
--                                                      param_type = ulong_type;
--                                              } else if (length == 2) {
--                                                      param_type = size_t_type;
--                                              }
--                                      } else if (c == 'e' || c == 'E' || c == 'f' || c == 'F'
--                                                 || c == 'g' || c == 'G' || c == 'a' || c == 'A') {
--                                              // double
--                                              param_type = double_type;
--                                      } else if (c == 's') {
--                                              // string
--                                              param_type = string_type;
--                                      } else if (c == 'p') {
--                                              // pointer
--                                              param_type = new PointerType (new VoidType ());
--                                      } else if (c == '%') {
--                                              // literal %
--                                      } else {
--                                              unsupported_format = true;
--                                              break;
--                                      }
--                                      if (c != '\0') {
--                                              format_it = format_it.next_char ();
--                                              c = format_it.get_char ();
--                                      }
--                                      if (param_type != null) {
--                                              if (arg_it.next ()) {
--                                                      Expression arg = arg_it.get ();
--
--                                                      arg.target_type = param_type;
--                                              } else {
--                                                      Report.error (expr.source_reference, "Too few arguments for specified format");
--                                                      return;
--                                              }
--                                      }
--                              }
--                              if (!unsupported_format && arg_it.next ()) {
--                                      Report.error (expr.source_reference, "Too many arguments for specified format");
--                                      return;
--                              }
--                      }
--              }
--
--              foreach (Expression arg in expr.get_argument_list ()) {
--                      arg.accept (this);
--              }
--
--              DataType ret_type;
--
--              ret_type = mtype.get_return_type ();
--              params = mtype.get_parameters ();
--
--              if (ret_type is VoidType) {
--                      // void return type
--                      if (!(expr.parent_node is ExpressionStatement)
--                          && !(expr.parent_node is ForStatement)
--                          && !(expr.parent_node is YieldStatement)) {
--                              // A void method invocation can be in the initializer or
--                              // iterator of a for statement
--                              expr.error = true;
--                              Report.error (expr.source_reference, "invocation of void method not allowed as expression");
--                              return;
--                      }
--              }
--
--              // resolve generic return values
--              var ma = expr.call as MemberAccess;
--              if (ret_type.type_parameter != null) {
--                      if (ma != null && ma.inner != null) {
--                              ret_type = get_actual_type (ma.inner.value_type, ma.symbol_reference, ret_type, expr);
--                              if (ret_type == null) {
--                                      return;
--                              }
--                      }
--              }
--              Gee.List<DataType> resolved_type_args = new ArrayList<DataType> ();
--              foreach (DataType type_arg in ret_type.get_type_arguments ()) {
--                      if (type_arg.type_parameter != null && ma != null && ma.inner != null) {
--                              resolved_type_args.add (get_actual_type (ma.inner.value_type, ma.symbol_reference, type_arg, expr));
--                      } else {
--                              resolved_type_args.add (type_arg);
--                      }
--              }
--              ret_type = ret_type.copy ();
--              ret_type.remove_all_type_arguments ();
--              foreach (DataType resolved_type_arg in resolved_type_args) {
--                      ret_type.add_type_argument (resolved_type_arg);
--              }
--
--              if (mtype is MethodType) {
--                      var m = ((MethodType) mtype).method_symbol;
--                      foreach (DataType error_type in m.get_error_types ()) {
--                              // ensure we can trace back which expression may throw errors of this type
--                              var call_error_type = error_type.copy ();
--                              call_error_type.source_reference = expr.source_reference;
--
--                              expr.add_error_type (call_error_type);
--                      }
--              }
--
--              expr.value_type = ret_type;
--
--              check_arguments (expr, mtype, params, expr.get_argument_list ());
-+              expr.check (this);
-       }
--      private bool check_arguments (Expression expr, DataType mtype, Gee.List<FormalParameter> params, Gee.List<Expression> args) {
-+      public bool check_arguments (Expression expr, DataType mtype, Gee.List<FormalParameter> params, Gee.List<Expression> args) {
-               Expression prev_arg = null;
-               Iterator<Expression> arg_it = args.iterator ();
-@@ -2480,121 +773,10 @@
-       }
-       public override void visit_element_access (ElementAccess expr) {
--              expr.container.accept (this);
--
--              if (expr.container.value_type == null) {
--                      /* don't proceed if a child expression failed */
--                      expr.error = true;
--                      return;
--              }
--
--              var container_type = expr.container.value_type.data_type;
--
--              if (expr.container is MemberAccess && expr.container.symbol_reference is Signal) {
--                      // signal detail access
--                      if (expr.get_indices ().size != 1) {
--                              expr.error = true;
--                              Report.error (expr.source_reference, "Element access with more than one dimension is not supported for signals");
--                              return;
--                      }
--                      expr.get_indices ().get (0).target_type = string_type.copy ();
--              }
--
--              foreach (Expression index in expr.get_indices ()) {
--                      index.accept (this);
--              }
--
--              bool index_int_type_check = true;
--
--              var pointer_type = expr.container.value_type as PointerType;
--
--              /* assign a value_type when possible */
--              if (expr.container.value_type is ArrayType) {
--                      var array_type = (ArrayType) expr.container.value_type;
--                      expr.value_type = array_type.element_type.copy ();
--                      if (!expr.lvalue) {
--                              expr.value_type.value_owned = false;
--                      }
--              } else if (pointer_type != null && !pointer_type.base_type.is_reference_type_or_type_parameter ()) {
--                      expr.value_type = pointer_type.base_type.copy ();
--              } else if (container_type == string_type.data_type) {
--                      if (expr.get_indices ().size != 1) {
--                              expr.error = true;
--                              Report.error (expr.source_reference, "Element access with more than one dimension is not supported for strings");
--                              return;
--                      }
--
--                      expr.value_type = unichar_type;
--              } else if (container_type != null && list_type != null && map_type != null &&
--                         (container_type.is_subtype_of (list_type) || container_type.is_subtype_of (map_type))) {
--                      Gee.List<Expression> indices = expr.get_indices ();
--                      if (indices.size != 1) {
--                              expr.error = true;
--                              Report.error (expr.source_reference, "Element access with more than one dimension is not supported for the specified type");
--                              return;
--                      }
--                      Iterator<Expression> indices_it = indices.iterator ();
--                      indices_it.next ();
--                      var index = indices_it.get ();
--                      index_int_type_check = false;
--
--                      // lookup symbol in interface instead of class as implemented interface methods are not in VAPI files
--                      Symbol get_sym = null;
--                      if (container_type.is_subtype_of (list_type)) {
--                              get_sym = list_type.scope.lookup ("get");
--                      } else if (container_type.is_subtype_of (map_type)) {
--                              get_sym = map_type.scope.lookup ("get");
--                      }
--                      var get_method = (Method) get_sym;
--                      Gee.List<FormalParameter> get_params = get_method.get_parameters ();
--                      Iterator<FormalParameter> get_params_it = get_params.iterator ();
--                      get_params_it.next ();
--                      var get_param = get_params_it.get ();
--
--                      var index_type = get_param.parameter_type;
--                      if (index_type.type_parameter != null) {
--                              index_type = get_actual_type (expr.container.value_type, get_method, get_param.parameter_type, expr);
--                      }
--
--                      if (!index.value_type.compatible (index_type)) {
--                              expr.error = true;
--                              Report.error (expr.source_reference, "index expression: Cannot convert from `%s' to `%s'".printf (index.value_type.to_string (), index_type.to_string ()));
--                              return;
--                      }
--
--                      expr.value_type = get_actual_type (expr.container.value_type, get_method, get_method.return_type, expr).copy ();
--                      if (expr.lvalue) {
--                              // get () returns owned value, set () accepts unowned value
--                              expr.value_type.value_owned = false;
--                      }
--              } else if (expr.container is MemberAccess && expr.container.symbol_reference is Signal) {
--                      index_int_type_check = false;
--
--                      expr.symbol_reference = expr.container.symbol_reference;
--                      expr.value_type = expr.container.value_type;
--              } else {
--                      expr.error = true;
--                      Report.error (expr.source_reference, "The expression `%s' does not denote an Array".printf (expr.container.value_type.to_string ()));
--              }
--
--              if (index_int_type_check) {
--                      /* check if the index is of type integer */
--                      foreach (Expression e in expr.get_indices ()) {
--                              /* don't proceed if a child expression failed */
--                              if (e.value_type == null) {
--                                      return;
--                              }
--
--                              /* check if the index is of type integer */
--                              if (!(e.value_type.data_type is Struct) || !((Struct) e.value_type.data_type).is_integer_type ()) {
--                                      expr.error = true;
--                                      Report.error (e.source_reference, "Expression of integer type expected");
--                              }
--                      }
--              }
-+              expr.check (this);
-       }
--      private bool is_in_instance_method () {
-+      public bool is_in_instance_method () {
-               var sym = current_symbol;
-               while (sym != null) {
-                       if (sym is CreationMethod) {
-@@ -2652,195 +834,10 @@
-       }
-       public override void visit_object_creation_expression (ObjectCreationExpression expr) {
--              if (expr.member_name != null) {
--                      expr.member_name.accept (this);
--              }
--
--              TypeSymbol type = null;
--
--              if (expr.type_reference == null) {
--                      if (expr.member_name == null) {
--                              expr.error = true;
--                              Report.error (expr.source_reference, "Incomplete object creation expression");
--                              return;
--                      }
--
--                      if (expr.member_name.symbol_reference == null) {
--                              expr.error = true;
--                              return;
--                      }
--
--                      var constructor_sym = expr.member_name.symbol_reference;
--                      var type_sym = expr.member_name.symbol_reference;
--
--                      var type_args = expr.member_name.get_type_arguments ();
--
--                      if (constructor_sym is Method) {
--                              type_sym = constructor_sym.parent_symbol;
--
--                              var constructor = (Method) constructor_sym;
--                              if (!(constructor_sym is CreationMethod)) {
--                                      expr.error = true;
--                                      Report.error (expr.source_reference, "`%s' is not a creation method".printf (constructor.get_full_name ()));
--                                      return;
--                              }
--
--                              expr.symbol_reference = constructor;
--
--                              // inner expression can also be base access when chaining constructors
--                              var ma = expr.member_name.inner as MemberAccess;
--                              if (ma != null) {
--                                      type_args = ma.get_type_arguments ();
--                              }
--                      }
--
--                      if (type_sym is Class) {
--                              type = (TypeSymbol) type_sym;
--                              expr.type_reference = new ObjectType ((Class) type);
--                      } else if (type_sym is Struct) {
--                              type = (TypeSymbol) type_sym;
--                              expr.type_reference = new ValueType (type);
--                      } else if (type_sym is ErrorCode) {
--                              expr.type_reference = new ErrorType ((ErrorDomain) type_sym.parent_symbol, (ErrorCode) type_sym, expr.source_reference);
--                              expr.symbol_reference = type_sym;
--                      } else {
--                              expr.error = true;
--                              Report.error (expr.source_reference, "`%s' is not a class, struct, or error code".printf (type_sym.get_full_name ()));
--                              return;
--                      }
--
--                      foreach (DataType type_arg in type_args) {
--                              expr.type_reference.add_type_argument (type_arg);
--
--                              current_source_file.add_type_dependency (type_arg, SourceFileDependencyType.SOURCE);
--                      }
--              } else {
--                      type = expr.type_reference.data_type;
--              }
--
--              current_source_file.add_symbol_dependency (type, SourceFileDependencyType.SOURCE);
--
--              expr.value_type = expr.type_reference.copy ();
--              expr.value_type.value_owned = true;
--
--              int given_num_type_args = expr.type_reference.get_type_arguments ().size;
--              int expected_num_type_args = 0;
--
--              if (type is Class) {
--                      var cl = (Class) type;
--
--                      expected_num_type_args = cl.get_type_parameters ().size;
--
--                      if (expr.struct_creation) {
--                              expr.error = true;
--                              Report.error (expr.source_reference, "syntax error, use `new' to create new objects");
--                              return;
--                      }
--
--                      if (cl.is_abstract) {
--                              expr.value_type = null;
--                              expr.error = true;
--                              Report.error (expr.source_reference, "Can't create instance of abstract class `%s'".printf (cl.get_full_name ()));
--                              return;
--                      }
--
--                      if (expr.symbol_reference == null) {
--                              expr.symbol_reference = cl.default_construction_method;
--                      }
--
--                      while (cl != null) {
--                              if (cl == initially_unowned_type) {
--                                      expr.value_type.floating_reference = true;
--                                      break;
--                              }
--
--                              cl = cl.base_class;
--                      }
--              } else if (type is Struct) {
--                      var st = (Struct) type;
--
--                      expected_num_type_args = st.get_type_parameters ().size;
--
--                      if (!expr.struct_creation) {
--                              Report.warning (expr.source_reference, "deprecated syntax, don't use `new' to initialize structs");
--                      }
--
--                      if (expr.symbol_reference == null) {
--                              expr.symbol_reference = st.default_construction_method;
--                      }
--              }
--
--              if (expected_num_type_args > given_num_type_args) {
--                      expr.error = true;
--                      Report.error (expr.source_reference, "too few type arguments");
--                      return;
--              } else if (expected_num_type_args < given_num_type_args) {
--                      expr.error = true;
--                      Report.error (expr.source_reference, "too many type arguments");
--                      return;
--              }
--
--              if (expr.symbol_reference == null && expr.get_argument_list ().size != 0) {
--                      expr.value_type = null;
--                      expr.error = true;
--                      Report.error (expr.source_reference, "No arguments allowed when constructing type `%s'".printf (type.get_full_name ()));
--                      return;
--              }
--
--              if (expr.symbol_reference is Method) {
--                      var m = (Method) expr.symbol_reference;
--
--                      var args = expr.get_argument_list ();
--                      Iterator<Expression> arg_it = args.iterator ();
--                      foreach (FormalParameter param in m.get_parameters ()) {
--                              if (param.ellipsis) {
--                                      break;
--                              }
--
--                              if (arg_it.next ()) {
--                                      Expression arg = arg_it.get ();
--
--                                      /* store expected type for callback parameters */
--                                      arg.target_type = param.parameter_type;
--                              }
--                      }
--
--                      foreach (Expression arg in args) {
--                              arg.accept (this);
--                      }
--
--                      check_arguments (expr, new MethodType (m), m.get_parameters (), args);
--
--                      foreach (DataType error_type in m.get_error_types ()) {
--                              // ensure we can trace back which expression may throw errors of this type
--                              var call_error_type = error_type.copy ();
--                              call_error_type.source_reference = expr.source_reference;
--
--                              expr.add_error_type (call_error_type);
--                      }
--              } else if (expr.type_reference is ErrorType) {
--                      expr.accept_children (this);
--
--                      if (expr.get_argument_list ().size == 0) {
--                              expr.error = true;
--                              Report.error (expr.source_reference, "Too few arguments, errors need at least 1 argument");
--                      } else {
--                              Iterator<Expression> arg_it = expr.get_argument_list ().iterator ();
--                              arg_it.next ();
--                              var ex = arg_it.get ();
--                              if (ex.value_type == null || !ex.value_type.compatible (string_type)) {
--                                      expr.error = true;
--                                      Report.error (expr.source_reference, "Invalid type for argument 1");
--                              }
--                      }
--              }
--
--              foreach (MemberInitializer init in expr.get_object_initializer ()) {
--                      visit_member_initializer (init, expr.type_reference);
--              }
-+              expr.check (this);
-       }
--      void visit_member_initializer (MemberInitializer init, DataType type) {
-+      public void visit_member_initializer (MemberInitializer init, DataType type) {
-               init.accept (this);
-               init.symbol_reference = symbol_lookup_inherited (type.data_type, init.name);
-@@ -3084,7 +1081,7 @@
-               expr.value_type.value_owned = true;
-       }
--      private DataType? get_arithmetic_result_type (DataType left_type, DataType right_type) {
-+      public DataType? get_arithmetic_result_type (DataType left_type, DataType right_type) {
-                if (!(left_type.data_type is Struct) || !(right_type.data_type is Struct)) {
-                       // at least one operand not struct
-                       return null;
-@@ -3117,158 +1114,7 @@
-       }
-       public override void visit_binary_expression (BinaryExpression expr) {
--              if (expr.left.error || expr.right.error) {
--                      /* if there were any errors in inner expressions, skip type check */
--                      expr.error = true;
--                      return;
--              }
--
--              if (expr.left.value_type == null) {
--                      Report.error (expr.left.source_reference, "invalid left operand");
--                      expr.error = true;
--                      return;
--              }
--
--              if (expr.operator != BinaryOperator.IN && expr.right.value_type == null) {
--                      Report.error (expr.right.source_reference, "invalid right operand");
--                      expr.error = true;
--                      return;
--              }
--
--              if (expr.left.value_type.data_type == string_type.data_type
--                  && expr.operator == BinaryOperator.PLUS) {
--                      // string concatenation
--
--                      if (expr.right.value_type == null || expr.right.value_type.data_type != string_type.data_type) {
--                              expr.error = true;
--                              Report.error (expr.source_reference, "Operands must be strings");
--                              return;
--                      }
--
--                      expr.value_type = string_type.copy ();
--                      if (expr.left.is_constant () && expr.right.is_constant ()) {
--                              expr.value_type.value_owned = false;
--                      } else {
--                              expr.value_type.value_owned = true;
--                      }
--              } else if (expr.operator == BinaryOperator.PLUS
--                         || expr.operator == BinaryOperator.MINUS
--                         || expr.operator == BinaryOperator.MUL
--                         || expr.operator == BinaryOperator.DIV) {
--                      // check for pointer arithmetic
--                      if (expr.left.value_type is PointerType) {
--                              var offset_type = expr.right.value_type.data_type as Struct;
--                              if (offset_type != null && offset_type.is_integer_type ()) {
--                                      if (expr.operator == BinaryOperator.PLUS
--                                          || expr.operator == BinaryOperator.MINUS) {
--                                              // pointer arithmetic: pointer +/- offset
--                                              expr.value_type = expr.left.value_type.copy ();
--                                      }
--                              } else if (expr.right.value_type is PointerType) {
--                                      // pointer arithmetic: pointer - pointer
--                                      expr.value_type = size_t_type;
--                              }
--                      }
--
--                      if (expr.value_type == null) {
--                              expr.value_type = get_arithmetic_result_type (expr.left.value_type, expr.right.value_type);
--                      }
--
--                      if (expr.value_type == null) {
--                              expr.error = true;
--                              Report.error (expr.source_reference, "Arithmetic operation not supported for types `%s' and `%s'".printf (expr.left.value_type.to_string (), expr.right.value_type.to_string ()));
--                              return;
--                      }
--              } else if (expr.operator == BinaryOperator.MOD
--                         || expr.operator == BinaryOperator.SHIFT_LEFT
--                         || expr.operator == BinaryOperator.SHIFT_RIGHT
--                         || expr.operator == BinaryOperator.BITWISE_XOR) {
--                      expr.value_type = get_arithmetic_result_type (expr.left.value_type, expr.right.value_type);
--
--                      if (expr.value_type == null) {
--                              expr.error = true;
--                              Report.error (expr.source_reference, "Arithmetic operation not supported for types `%s' and `%s'".printf (expr.left.value_type.to_string (), expr.right.value_type.to_string ()));
--                              return;
--                      }
--              } else if (expr.operator == BinaryOperator.LESS_THAN
--                         || expr.operator == BinaryOperator.GREATER_THAN
--                         || expr.operator == BinaryOperator.LESS_THAN_OR_EQUAL
--                         || expr.operator == BinaryOperator.GREATER_THAN_OR_EQUAL) {
--                      if (expr.left.value_type.compatible (string_type)
--                          && expr.right.value_type.compatible (string_type)) {
--                              // string comparison
--                              } else if (expr.left.value_type is PointerType && expr.right.value_type is PointerType) {
--                                      // pointer arithmetic
--                      } else {
--                              var resulting_type = get_arithmetic_result_type (expr.left.value_type, expr.right.value_type);
--
--                              if (resulting_type == null) {
--                                      expr.error = true;
--                                      Report.error (expr.source_reference, "Relational operation not supported for types `%s' and `%s'".printf (expr.left.value_type.to_string (), expr.right.value_type.to_string ()));
--                                      return;
--                              }
--                      }
--
--                      expr.value_type = bool_type;
--              } else if (expr.operator == BinaryOperator.EQUALITY
--                         || expr.operator == BinaryOperator.INEQUALITY) {
--                      /* relational operation */
--
--                      if (!expr.right.value_type.compatible (expr.left.value_type)
--                          && !expr.left.value_type.compatible (expr.right.value_type)) {
--                              Report.error (expr.source_reference, "Equality operation: `%s' and `%s' are incompatible".printf (expr.right.value_type.to_string (), expr.left.value_type.to_string ()));
--                              expr.error = true;
--                              return;
--                      }
--
--                      if (expr.left.value_type.compatible (string_type)
--                          && expr.right.value_type.compatible (string_type)) {
--                              // string comparison
--                      }
--
--                      expr.value_type = bool_type;
--              } else if (expr.operator == BinaryOperator.BITWISE_AND
--                         || expr.operator == BinaryOperator.BITWISE_OR) {
--                      // integer type or flags type
--
--                      expr.value_type = expr.left.value_type;
--              } else if (expr.operator == BinaryOperator.AND
--                         || expr.operator == BinaryOperator.OR) {
--                      if (!expr.left.value_type.compatible (bool_type) || !expr.right.value_type.compatible (bool_type)) {
--                              expr.error = true;
--                              Report.error (expr.source_reference, "Operands must be boolean");
--                      }
--
--                      expr.value_type = bool_type;
--              } else if (expr.operator == BinaryOperator.IN) {
--                      // integer type or flags type or collection/map
--
--                      /* handle collections and maps */
--                      var container_type = expr.right.value_type.data_type;
--                      
--                      if ((collection_type != null && container_type.is_subtype_of (collection_type))
--                          || (map_type != null && container_type.is_subtype_of (map_type))) {
--                              Symbol contains_sym = null;
--                              if (container_type.is_subtype_of (collection_type)) {
--                                      contains_sym = collection_type.scope.lookup ("contains");
--                              } else if (container_type.is_subtype_of (map_type)) {
--                                      contains_sym = map_type.scope.lookup ("contains");
--                              }
--                              var contains_method = (Method) contains_sym;
--                              Gee.List<FormalParameter> contains_params = contains_method.get_parameters ();
--                              Iterator<FormalParameter> contains_params_it = contains_params.iterator ();
--                              contains_params_it.next ();
--                              var contains_param = contains_params_it.get ();
--
--                              var key_type = get_actual_type (expr.right.value_type, contains_method, contains_param.parameter_type, expr);
--                              expr.left.target_type = key_type;
--                      }
--                      
--                      expr.value_type = bool_type;
--                      
--              } else {
--                      assert_not_reached ();
--              }
-+              expr.check (this);
-       }
-       public override void visit_type_check (TypeCheck expr) {
-@@ -3314,7 +1160,7 @@
-               return result;
-       }
--      private Method? find_current_method () {
-+      public Method? find_current_method () {
-               var sym = current_symbol;
-               while (sym != null) {
-                       if (sym is Method) {
-@@ -3325,7 +1171,7 @@
-               return null;
-       }
--      private bool is_in_constructor () {
-+      public bool is_in_constructor () {
-               var sym = current_symbol;
-               while (sym != null) {
-                       if (sym is Constructor) {
-@@ -3405,277 +1251,6 @@
-       }
-       public override void visit_assignment (Assignment a) {
--              a.left.lvalue = true;
--
--              a.left.accept (this);
--
--              if (a.left.error) {
--                      // skip on error in inner expression
--                      a.error = true;
--                      return;
--              }
--
--              if (a.left is MemberAccess) {
--                      var ma = (MemberAccess) a.left;
--
--                      if (!(ma.symbol_reference is Signal || ma.symbol_reference is DynamicProperty) && ma.value_type == null) {
--                              a.error = true;
--                              Report.error (a.source_reference, "unsupported lvalue in assignment");
--                              return;
--                      }
--                      if (ma.prototype_access) {
--                              a.error = true;
--                              Report.error (a.source_reference, "Access to instance member `%s' denied".printf (ma.symbol_reference.get_full_name ()));
--                              return;
--                      }
--
--                      if (ma.error || ma.symbol_reference == null) {
--                              a.error = true;
--                              /* if no symbol found, skip this check */
--                              return;
--                      }
--
--                      if (ma.symbol_reference is DynamicSignal) {
--                              // target_type not available for dynamic signals
--                      } else if (ma.symbol_reference is Signal) {
--                              var sig = (Signal) ma.symbol_reference;
--                              a.right.target_type = new DelegateType (sig.get_delegate (ma.inner.value_type));
--                      } else {
--                              a.right.target_type = ma.value_type;
--                      }
--              } else if (a.left is ElementAccess) {
--                      var ea = (ElementAccess) a.left;
--
--                      if (ea.container is MemberAccess && ea.container.symbol_reference is Signal) {
--                              var ma = (MemberAccess) ea.container;
--                              var sig = (Signal) ea.container.symbol_reference;
--                              a.right.target_type = new DelegateType (sig.get_delegate (ma.inner.value_type));
--                      } else {
--                              a.right.target_type = a.left.value_type;
--                      }
--              } else if (a.left is PointerIndirection) {
--                      a.right.target_type = a.left.value_type;
--              } else {
--                      a.error = true;
--                      Report.error (a.source_reference, "unsupported lvalue in assignment");
--                      return;
--              }
--
--              a.right.accept (this);
--
--              if (a.right.error) {
--                      // skip on error in inner expression
--                      a.error = true;
--                      return;
--              }
--
--              if (a.operator != AssignmentOperator.SIMPLE && a.left is MemberAccess) {
--                      // transform into simple assignment
--                      // FIXME: only do this if the backend doesn't support
--                      // the assignment natively
--
--                      var ma = (MemberAccess) a.left;
--
--                      if (!(ma.symbol_reference is Signal)) {
--                              var old_value = new MemberAccess (ma.inner, ma.member_name);
--
--                              var bin = new BinaryExpression (BinaryOperator.PLUS, old_value, new ParenthesizedExpression (a.right, a.right.source_reference));
--                              bin.target_type = a.right.target_type;
--                              a.right.target_type = a.right.target_type.copy ();
--                              a.right.target_type.value_owned = false;
--
--                              if (a.operator == AssignmentOperator.BITWISE_OR) {
--                                      bin.operator = BinaryOperator.BITWISE_OR;
--                              } else if (a.operator == AssignmentOperator.BITWISE_AND) {
--                                      bin.operator = BinaryOperator.BITWISE_AND;
--                              } else if (a.operator == AssignmentOperator.BITWISE_XOR) {
--                                      bin.operator = BinaryOperator.BITWISE_XOR;
--                              } else if (a.operator == AssignmentOperator.ADD) {
--                                      bin.operator = BinaryOperator.PLUS;
--                              } else if (a.operator == AssignmentOperator.SUB) {
--                                      bin.operator = BinaryOperator.MINUS;
--                              } else if (a.operator == AssignmentOperator.MUL) {
--                                      bin.operator = BinaryOperator.MUL;
--                              } else if (a.operator == AssignmentOperator.DIV) {
--                                      bin.operator = BinaryOperator.DIV;
--                              } else if (a.operator == AssignmentOperator.PERCENT) {
--                                      bin.operator = BinaryOperator.MOD;
--                              } else if (a.operator == AssignmentOperator.SHIFT_LEFT) {
--                                      bin.operator = BinaryOperator.SHIFT_LEFT;
--                              } else if (a.operator == AssignmentOperator.SHIFT_RIGHT) {
--                                      bin.operator = BinaryOperator.SHIFT_RIGHT;
--                              }
--
--                              a.right = bin;
--                              a.right.accept (this);
--
--                              a.operator = AssignmentOperator.SIMPLE;
--                      }
--              }
--
--              if (a.left.symbol_reference is Signal) {
--                      var sig = (Signal) a.left.symbol_reference;
--
--                      var m = a.right.symbol_reference as Method;
--
--                      if (m == null) {
--                              a.error = true;
--                              Report.error (a.right.source_reference, "unsupported expression for signal handler");
--                              return;
--                      }
--
--                      var dynamic_sig = sig as DynamicSignal;
--                      if (dynamic_sig != null) {
--                              bool first = true;
--                              foreach (FormalParameter param in dynamic_sig.handler.value_type.get_parameters ()) {
--                                      if (first) {
--                                              // skip sender parameter
--                                              first = false;
--                                      } else {
--                                              dynamic_sig.add_parameter (param.copy ());
--                                      }
--                              }
--                              a.right.target_type = new DelegateType (sig.get_delegate (new ObjectType ((ObjectTypeSymbol) sig.parent_symbol)));
--                      } else if (!a.right.value_type.compatible (a.right.target_type)) {
--                              var delegate_type = (DelegateType) a.right.target_type;
--
--                              a.error = true;
--                              Report.error (a.right.source_reference, "method `%s' is incompatible with signal `%s', expected `%s'".printf (a.right.value_type.to_string (), a.right.target_type.to_string (), delegate_type.delegate_symbol.get_prototype_string (m.name)));
--                              return;
--                      }
--              } else if (a.left is MemberAccess) {
--                      var ma = (MemberAccess) a.left;
--
--                      if (ma.symbol_reference is Property) {
--                              var prop = (Property) ma.symbol_reference;
--
--                              var dynamic_prop = prop as DynamicProperty;
--                              if (dynamic_prop != null) {
--                                      dynamic_prop.property_type = a.right.value_type.copy ();
--                                      a.left.value_type = dynamic_prop.property_type.copy ();
--                              }
--
--                              if (prop.set_accessor == null
--                                  || (!prop.set_accessor.writable && !(find_current_method () is CreationMethod || is_in_constructor ()))) {
--                                      ma.error = true;
--                                      Report.error (ma.source_reference, "Property `%s' is read-only".printf (prop.get_full_name ()));
--                                      return;
--                              }
--                      } else if (ma.symbol_reference is LocalVariable && a.right.value_type == null) {
--                              var local = (LocalVariable) ma.symbol_reference;
--
--                              if (a.right.symbol_reference is Method &&
--                                  local.variable_type is DelegateType) {
--                                      var m = (Method) a.right.symbol_reference;
--                                      var dt = (DelegateType) local.variable_type;
--                                      var cb = dt.delegate_symbol;
--
--                                      /* check whether method matches callback type */
--                                      if (!cb.matches_method (m)) {
--                                              a.error = true;
--                                              Report.error (a.source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.get_full_name (), cb.get_full_name ()));
--                                              return;
--                                      }
--
--                                      a.right.value_type = local.variable_type;
--                              } else {
--                                      a.error = true;
--                                      Report.error (a.source_reference, "Assignment: Invalid callback assignment attempt");
--                                      return;
--                              }
--                      } else if (ma.symbol_reference is Field && a.right.value_type == null) {
--                              var f = (Field) ma.symbol_reference;
--
--                              if (a.right.symbol_reference is Method &&
--                                  f.field_type is DelegateType) {
--                                      var m = (Method) a.right.symbol_reference;
--                                      var dt = (DelegateType) f.field_type;
--                                      var cb = dt.delegate_symbol;
--
--                                      /* check whether method matches callback type */
--                                      if (!cb.matches_method (m)) {
--                                              f.error = true;
--                                              Report.error (a.source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.get_full_name (), cb.get_full_name ()));
--                                              return;
--                                      }
--
--                                      a.right.value_type = f.field_type;
--                              } else {
--                                      a.error = true;
--                                      Report.error (a.source_reference, "Assignment: Invalid callback assignment attempt");
--                                      return;
--                              }
--                      } else if (a.left.value_type != null && a.right.value_type != null) {
--                              /* if there was an error on either side,
--                               * i.e. a.{left|right}.value_type == null, skip type check */
--
--                              if (!a.right.value_type.compatible (a.left.value_type)) {
--                                      a.error = true;
--                                      Report.error (a.source_reference, "Assignment: Cannot convert from `%s' to `%s'".printf (a.right.value_type.to_string (), a.left.value_type.to_string ()));
--                                      return;
--                              }
--
--                              if (a.right.value_type.is_disposable ()) {
--                                      /* rhs transfers ownership of the expression */
--                                      if (!(a.left.value_type is PointerType) && !a.left.value_type.value_owned) {
--                                              /* lhs doesn't own the value */
--                                              a.error = true;
--                                              Report.error (a.source_reference, "Invalid assignment from owned expression to unowned variable");
--                                      }
--                              } else if (a.left.value_type.value_owned) {
--                                      /* lhs wants to own the value
--                                       * rhs doesn't transfer the ownership
--                                       * code generator needs to add reference
--                                       * increment calls */
--                              }
--                      }
--              } else if (a.left is ElementAccess) {
--                      var ea = (ElementAccess) a.left;
--
--                      if (!a.right.value_type.compatible (a.left.value_type)) {
--                              a.error = true;
--                              Report.error (a.source_reference, "Assignment: Cannot convert from `%s' to `%s'".printf (a.right.value_type.to_string (), a.left.value_type.to_string ()));
--                              return;
--                      }
--
--                      if (a.right.value_type.is_disposable ()) {
--                              /* rhs transfers ownership of the expression */
--
--                              DataType element_type;
--
--                              if (ea.container.value_type is ArrayType) {
--                                      var array_type = (ArrayType) ea.container.value_type;
--                                      element_type = array_type.element_type;
--                              } else {
--                                      var args = ea.container.value_type.get_type_arguments ();
--                                      assert (args.size == 1);
--                                      element_type = args.get (0);
--                              }
--
--                              if (!(element_type is PointerType) && !element_type.value_owned) {
--                                      /* lhs doesn't own the value */
--                                      a.error = true;
--                                      Report.error (a.source_reference, "Invalid assignment from owned expression to unowned variable");
--                                      return;
--                              }
--                      } else if (a.left.value_type.value_owned) {
--                              /* lhs wants to own the value
--                               * rhs doesn't transfer the ownership
--                               * code generator needs to add reference
--                               * increment calls */
--                      }
--              } else {
--                      return;
--              }
--
--              if (a.left.value_type != null) {
--                      a.value_type = a.left.value_type.copy ();
--                      a.value_type.value_owned = false;
--              } else {
--                      a.value_type = null;
--              }
--
--              a.add_error_types (a.left.get_error_types ());
--              a.add_error_types (a.right.get_error_types ());
-+              a.check (this);
-       }
- }
-Index: vala/valasignal.vala
-===================================================================
---- vala/valasignal.vala       (revision 1971)
-+++ vala/valasignal.vala       (revision 2004)
-@@ -218,5 +218,19 @@
-               
-               return generated_method;
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              process_attributes ();
-+
-+              accept_children (analyzer);
-+
-+              return !error;
-+      }
- }
-Index: vala/valaexpressionstatement.vala
-===================================================================
---- vala/valaexpressionstatement.vala  (revision 1971)
-+++ vala/valaexpressionstatement.vala  (revision 2004)
-@@ -1,6 +1,6 @@
- /* valaexpressionstatement.vala
-  *
-- * Copyright (C) 2006-2007  Jürg Billeter
-+ * Copyright (C) 2006-2008  Jürg Billeter
-  *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Lesser General Public
-@@ -85,4 +85,22 @@
-               return null;
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              if (expression.error) {
-+                      // ignore inner error
-+                      error = true;
-+                      return false;
-+              }
-+
-+              add_error_types (expression.get_error_types ());
-+
-+              return !error;
-+      }
- }
-Index: vala/valainvocationexpression.vala
-===================================================================
---- vala/valainvocationexpression.vala (revision 1971)
-+++ vala/valainvocationexpression.vala (revision 2004)
-@@ -120,4 +120,306 @@
-       public override bool is_pure () {
-               return false;
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              call.accept (analyzer);
-+
-+              if (call.error) {
-+                      /* if method resolving didn't succeed, skip this check */
-+                      error = true;
-+                      return false;
-+              }
-+
-+              if (call is MemberAccess) {
-+                      var ma = (MemberAccess) call;
-+                      if (ma.prototype_access) {
-+                              error = true;
-+                              Report.error (source_reference, "Access to instance member `%s' denied".printf (call.symbol_reference.get_full_name ()));
-+                              return false;
-+                      }
-+              }
-+
-+              var mtype = call.value_type;
-+
-+              if (mtype is ObjectType) {
-+                      // constructor chain-up
-+                      var cm = analyzer.find_current_method () as CreationMethod;
-+                      assert (cm != null);
-+                      if (cm.chain_up) {
-+                              error = true;
-+                              Report.error (source_reference, "Multiple constructor calls in the same constructor are not permitted");
-+                              return false;
-+                      }
-+                      cm.chain_up = true;
-+              }
-+
-+              // check for struct construction
-+              if (call is MemberAccess &&
-+                  ((call.symbol_reference is CreationMethod
-+                    && call.symbol_reference.parent_symbol is Struct)
-+                   || call.symbol_reference is Struct)) {
-+                      var struct_creation_expression = new ObjectCreationExpression ((MemberAccess) call, source_reference);
-+                      struct_creation_expression.struct_creation = true;
-+                      foreach (Expression arg in get_argument_list ()) {
-+                              struct_creation_expression.add_argument (arg);
-+                      }
-+                      struct_creation_expression.target_type = target_type;
-+                      analyzer.replaced_nodes.add (this);
-+                      parent_node.replace_expression (this, struct_creation_expression);
-+                      struct_creation_expression.accept (analyzer);
-+                      return false;
-+              } else if (call is MemberAccess
-+                         && call.symbol_reference is CreationMethod) {
-+                      // constructor chain-up
-+                      var cm = analyzer.find_current_method () as CreationMethod;
-+                      assert (cm != null);
-+                      if (cm.chain_up) {
-+                              error = true;
-+                              Report.error (source_reference, "Multiple constructor calls in the same constructor are not permitted");
-+                              return false;
-+                      }
-+                      cm.chain_up = true;
-+              }
-+
-+              Gee.List<FormalParameter> params;
-+
-+              if (mtype != null && mtype.is_invokable ()) {
-+                      params = mtype.get_parameters ();
-+              } else {
-+                      error = true;
-+                      Report.error (source_reference, "invocation not supported in this context");
-+                      return false;
-+              }
-+
-+              Expression last_arg = null;
-+
-+              var args = get_argument_list ();
-+              Iterator<Expression> arg_it = args.iterator ();
-+              foreach (FormalParameter param in params) {
-+                      if (param.ellipsis) {
-+                              break;
-+                      }
-+
-+                      if (arg_it.next ()) {
-+                              Expression arg = arg_it.get ();
-+
-+                              /* store expected type for callback parameters */
-+                              arg.target_type = param.parameter_type;
-+
-+                              // resolve generic type parameters
-+                              var ma = call as MemberAccess;
-+                              if (arg.target_type.type_parameter != null) {
-+                                      if (ma != null && ma.inner != null) {
-+                                              arg.target_type = analyzer.get_actual_type (ma.inner.value_type, ma.symbol_reference, arg.target_type, arg);
-+                                              assert (arg.target_type != null);
-+                                      }
-+                              }
-+
-+                              last_arg = arg;
-+                      }
-+              }
-+
-+              // printf arguments
-+              if (mtype is MethodType && ((MethodType) mtype).method_symbol.printf_format) {
-+                      StringLiteral format_literal = null;
-+                      if (last_arg != null) {
-+                              // use last argument as format string
-+                              format_literal = last_arg as StringLiteral;
-+                      } else {
-+                              // use instance as format string for string.printf (...)
-+                              var ma = call as MemberAccess;
-+                              if (ma != null) {
-+                                      format_literal = ma.inner as StringLiteral;
-+                              }
-+                      }
-+                      if (format_literal != null) {
-+                              string format = format_literal.eval ();
-+
-+                              bool unsupported_format = false;
-+
-+                              weak string format_it = format;
-+                              unichar c = format_it.get_char ();
-+                              while (c != '\0') {
-+                                      if (c != '%') {
-+                                              format_it = format_it.next_char ();
-+                                              c = format_it.get_char ();
-+                                              continue;
-+                                      }
-+
-+                                      format_it = format_it.next_char ();
-+                                      c = format_it.get_char ();
-+                                      // flags
-+                                      while (c == '#' || c == '0' || c == '-' || c == ' ' || c == '+') {
-+                                              format_it = format_it.next_char ();
-+                                              c = format_it.get_char ();
-+                                      }
-+                                      // field width
-+                                      while (c >= '0' && c <= '9') {
-+                                              format_it = format_it.next_char ();
-+                                              c = format_it.get_char ();
-+                                      }
-+                                      // precision
-+                                      if (c == '.') {
-+                                              format_it = format_it.next_char ();
-+                                              c = format_it.get_char ();
-+                                              while (c >= '0' && c <= '9') {
-+                                                      format_it = format_it.next_char ();
-+                                                      c = format_it.get_char ();
-+                                              }
-+                                      }
-+                                      // length modifier
-+                                      int length = 0;
-+                                      if (c == 'h') {
-+                                              length = -1;
-+                                              format_it = format_it.next_char ();
-+                                              c = format_it.get_char ();
-+                                              if (c == 'h') {
-+                                                      length = -2;
-+                                                      format_it = format_it.next_char ();
-+                                                      c = format_it.get_char ();
-+                                              }
-+                                      } else if (c == 'l') {
-+                                              length = 1;
-+                                              format_it = format_it.next_char ();
-+                                              c = format_it.get_char ();
-+                                      } else if (c == 'z') {
-+                                              length = 2;
-+                                              format_it = format_it.next_char ();
-+                                              c = format_it.get_char ();
-+                                      }
-+                                      // conversion specifier
-+                                      DataType param_type = null;
-+                                      if (c == 'd' || c == 'i' || c == 'c') {
-+                                              // integer
-+                                              if (length == -2) {
-+                                                      param_type = analyzer.int8_type;
-+                                              } else if (length == -1) {
-+                                                      param_type = analyzer.short_type;
-+                                              } else if (length == 0) {
-+                                                      param_type = analyzer.int_type;
-+                                              } else if (length == 1) {
-+                                                      param_type = analyzer.long_type;
-+                                              } else if (length == 2) {
-+                                                      param_type = analyzer.ssize_t_type;
-+                                              }
-+                                      } else if (c == 'o' || c == 'u' || c == 'x' || c == 'X') {
-+                                              // unsigned integer
-+                                              if (length == -2) {
-+                                                      param_type = analyzer.uchar_type;
-+                                              } else if (length == -1) {
-+                                                      param_type = analyzer.ushort_type;
-+                                              } else if (length == 0) {
-+                                                      param_type = analyzer.uint_type;
-+                                              } else if (length == 1) {
-+                                                      param_type = analyzer.ulong_type;
-+                                              } else if (length == 2) {
-+                                                      param_type = analyzer.size_t_type;
-+                                              }
-+                                      } else if (c == 'e' || c == 'E' || c == 'f' || c == 'F'
-+                                                 || c == 'g' || c == 'G' || c == 'a' || c == 'A') {
-+                                              // double
-+                                              param_type = analyzer.double_type;
-+                                      } else if (c == 's') {
-+                                              // string
-+                                              param_type = analyzer.string_type;
-+                                      } else if (c == 'p') {
-+                                              // pointer
-+                                              param_type = new PointerType (new VoidType ());
-+                                      } else if (c == '%') {
-+                                              // literal %
-+                                      } else {
-+                                              unsupported_format = true;
-+                                              break;
-+                                      }
-+                                      if (c != '\0') {
-+                                              format_it = format_it.next_char ();
-+                                              c = format_it.get_char ();
-+                                      }
-+                                      if (param_type != null) {
-+                                              if (arg_it.next ()) {
-+                                                      Expression arg = arg_it.get ();
-+
-+                                                      arg.target_type = param_type;
-+                                              } else {
-+                                                      Report.error (source_reference, "Too few arguments for specified format");
-+                                                      return false;
-+                                              }
-+                                      }
-+                              }
-+                              if (!unsupported_format && arg_it.next ()) {
-+                                      Report.error (source_reference, "Too many arguments for specified format");
-+                                      return false;
-+                              }
-+                      }
-+              }
-+
-+              foreach (Expression arg in get_argument_list ()) {
-+                      arg.accept (analyzer);
-+              }
-+
-+              DataType ret_type;
-+
-+              ret_type = mtype.get_return_type ();
-+              params = mtype.get_parameters ();
-+
-+              if (ret_type is VoidType) {
-+                      // void return type
-+                      if (!(parent_node is ExpressionStatement)
-+                          && !(parent_node is ForStatement)
-+                          && !(parent_node is YieldStatement)) {
-+                              // A void method invocation can be in the initializer or
-+                              // iterator of a for statement
-+                              error = true;
-+                              Report.error (source_reference, "invocation of void method not allowed as expression");
-+                              return false;
-+                      }
-+              }
-+
-+              // resolve generic return values
-+              var ma = call as MemberAccess;
-+              if (ret_type.type_parameter != null) {
-+                      if (ma != null && ma.inner != null) {
-+                              ret_type = analyzer.get_actual_type (ma.inner.value_type, ma.symbol_reference, ret_type, this);
-+                              if (ret_type == null) {
-+                                      return false;
-+                              }
-+                      }
-+              }
-+              Gee.List<DataType> resolved_type_args = new ArrayList<DataType> ();
-+              foreach (DataType type_arg in ret_type.get_type_arguments ()) {
-+                      if (type_arg.type_parameter != null && ma != null && ma.inner != null) {
-+                              resolved_type_args.add (analyzer.get_actual_type (ma.inner.value_type, ma.symbol_reference, type_arg, this));
-+                      } else {
-+                              resolved_type_args.add (type_arg);
-+                      }
-+              }
-+              ret_type = ret_type.copy ();
-+              ret_type.remove_all_type_arguments ();
-+              foreach (DataType resolved_type_arg in resolved_type_args) {
-+                      ret_type.add_type_argument (resolved_type_arg);
-+              }
-+
-+              if (mtype is MethodType) {
-+                      var m = ((MethodType) mtype).method_symbol;
-+                      foreach (DataType error_type in m.get_error_types ()) {
-+                              // ensure we can trace back which expression may throw errors of this type
-+                              var call_error_type = error_type.copy ();
-+                              call_error_type.source_reference = source_reference;
-+
-+                              add_error_type (call_error_type);
-+                      }
-+              }
-+
-+              value_type = ret_type;
-+
-+              analyzer.check_arguments (this, mtype, params, get_argument_list ());
-+
-+              return !error;
-+      }
- }
-Index: vala/valatrystatement.vala
-===================================================================
---- vala/valatrystatement.vala (revision 1971)
-+++ vala/valatrystatement.vala (revision 2004)
-@@ -86,4 +86,16 @@
-                       finally_body.accept (visitor);
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              accept_children (analyzer);
-+
-+              return !error;
-+      }
- }
-Index: vala/valareturnstatement.vala
-===================================================================
---- vala/valareturnstatement.vala      (revision 1971)
-+++ vala/valareturnstatement.vala      (revision 2004)
-@@ -70,4 +70,77 @@
-                       return_expression = new_node;
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              if (return_expression != null) {
-+                      return_expression.target_type = analyzer.current_return_type;
-+              }
-+
-+              accept_children (analyzer);
-+
-+              if (return_expression != null && return_expression.error) {
-+                      // ignore inner error
-+                      error = true;
-+                      return false;
-+              }
-+
-+              if (analyzer.current_return_type == null) {
-+                      error = true;
-+                      Report.error (source_reference, "Return not allowed in this context");
-+                      return false;
-+              }
-+
-+              if (return_expression == null) {
-+                      if (!(analyzer.current_return_type is VoidType)) {
-+                              error = true;
-+                              Report.error (source_reference, "Return without value in non-void function");
-+                      }
-+                      return !error;
-+              }
-+
-+              if (analyzer.current_return_type is VoidType) {
-+                      Report.error (source_reference, "Return with value in void function");
-+                      return false;
-+              }
-+
-+              if (return_expression.value_type == null) {
-+                      error = true;
-+                      Report.error (source_reference, "Invalid expression in return value");
-+                      return false;
-+              }
-+
-+              if (!return_expression.value_type.compatible (analyzer.current_return_type)) {
-+                      error = true;
-+                      Report.error (source_reference, "Return: Cannot convert from `%s' to `%s'".printf (return_expression.value_type.to_string (), analyzer.current_return_type.to_string ()));
-+                      return false;
-+              }
-+
-+              if (return_expression.value_type.is_disposable () &&
-+                  !analyzer.current_return_type.value_owned) {
-+                      error = true;
-+                      Report.error (source_reference, "Return value transfers ownership but method return type hasn't been declared to transfer ownership");
-+                      return false;
-+              }
-+
-+              if (return_expression.symbol_reference is LocalVariable &&
-+                  return_expression.value_type.is_disposable () &&
-+                  !analyzer.current_return_type.value_owned) {
-+                      Report.warning (source_reference, "Local variable with strong reference used as return value and method return type hasn't been declared to transfer ownership");
-+              }
-+
-+              if (analyzer.context.non_null && return_expression is NullLiteral
-+                  && !analyzer.current_return_type.nullable) {
-+                      Report.warning (source_reference, "`null' incompatible with return type `%s`".printf (analyzer.current_return_type.to_string ()));
-+              }
-+
-+              add_error_types (return_expression.get_error_types ());
-+
-+              return !error;
-+      }
- }
-Index: vala/valaclass.vala
-===================================================================
---- vala/valaclass.vala        (revision 1971)
-+++ vala/valaclass.vala        (revision 2004)
-@@ -814,5 +814,202 @@
-                       }
-               }
-       }
-+
-+      private void get_all_prerequisites (Interface iface, Gee.List<TypeSymbol> list) {
-+              foreach (DataType prereq in iface.get_prerequisites ()) {
-+                      TypeSymbol type = prereq.data_type;
-+                      /* skip on previous errors */
-+                      if (type == null) {
-+                              continue;
-+                      }
-+
-+                      list.add (type);
-+                      if (type is Interface) {
-+                              get_all_prerequisites ((Interface) type, list);
-+
-+                      }
-+              }
-+      }
-+
-+      private bool class_is_a (Class cl, TypeSymbol t) {
-+              if (cl == t) {
-+                      return true;
-+              }
-+
-+              foreach (DataType base_type in cl.get_base_types ()) {
-+                      if (base_type.data_type is Class) {
-+                              if (class_is_a ((Class) base_type.data_type, t)) {
-+                                      return true;
-+                              }
-+                      } else if (base_type.data_type == t) {
-+                              return true;
-+                      }
-+              }
-+
-+              return false;
-+      }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              process_attributes ();
-+
-+              var old_source_file = analyzer.current_source_file;
-+              var old_symbol = analyzer.current_symbol;
-+              var old_class = analyzer.current_class;
-+
-+              if (source_reference != null) {
-+                      analyzer.current_source_file = source_reference.file;
-+              }
-+              analyzer.current_symbol = this;
-+              analyzer.current_class = this;
-+
-+              foreach (DataType base_type_reference in get_base_types ()) {
-+                      if (!base_type_reference.check (analyzer)) {
-+                              error = true;
-+                              return false;
-+                      }
-+
-+                      // check whether base type is at least as accessible as the class
-+                      if (!analyzer.is_type_accessible (this, base_type_reference)) {
-+                              error = true;
-+                              Report.error (source_reference, "base type `%s` is less accessible than class `%s`".printf (base_type_reference.to_string (), get_full_name ()));
-+                              return false;
-+                      }
-+
-+                      analyzer.current_source_file.add_type_dependency (base_type_reference, SourceFileDependencyType.HEADER_FULL);
-+              }
-+
-+              accept_children (analyzer);
-+
-+              /* compact classes cannot implement interfaces */
-+              if (is_compact) {
-+                      foreach (DataType base_type in get_base_types ()) {
-+                              if (base_type.data_type is Interface) {
-+                                      error = true;
-+                                      Report.error (source_reference, "compact classes `%s` may not implement interfaces".printf (get_full_name ()));
-+                              }
-+                      }
-+              }
-+
-+              /* gather all prerequisites */
-+              Gee.List<TypeSymbol> prerequisites = new ArrayList<TypeSymbol> ();
-+              foreach (DataType base_type in get_base_types ()) {
-+                      if (base_type.data_type is Interface) {
-+                              get_all_prerequisites ((Interface) base_type.data_type, prerequisites);
-+                      }
-+              }
-+              /* check whether all prerequisites are met */
-+              Gee.List<string> missing_prereqs = new ArrayList<string> ();
-+              foreach (TypeSymbol prereq in prerequisites) {
-+                      if (!class_is_a (this, prereq)) {
-+                              missing_prereqs.insert (0, prereq.get_full_name ());
-+                      }
-+              }
-+              /* report any missing prerequisites */
-+              if (missing_prereqs.size > 0) {
-+                      error = true;
-+
-+                      string error_string = "%s: some prerequisites (".printf (get_full_name ());
-+                      bool first = true;
-+                      foreach (string s in missing_prereqs) {
-+                              if (first) {
-+                                      error_string = "%s`%s'".printf (error_string, s);
-+                                      first = false;
-+                              } else {
-+                                      error_string = "%s, `%s'".printf (error_string, s);
-+                              }
-+                      }
-+                      error_string += ") are not met";
-+                      Report.error (source_reference, error_string);
-+              }
-+
-+              /* VAPI classes don't have to specify overridden methods */
-+              if (!external_package) {
-+                      /* all abstract symbols defined in base types have to be at least defined (or implemented) also in this type */
-+                      foreach (DataType base_type in get_base_types ()) {
-+                              if (base_type.data_type is Interface) {
-+                                      Interface iface = (Interface) base_type.data_type;
-+
-+                                      if (base_class != null && base_class.is_subtype_of (iface)) {
-+                                              // reimplementation of interface, class is not required to reimplement all methods
-+                                              break;
-+                                      }
-+
-+                                      /* We do not need to do expensive equality checking here since this is done
-+                                       * already. We only need to guarantee the symbols are present.
-+                                       */
-+
-+                                      /* check methods */
-+                                      foreach (Method m in iface.get_methods ()) {
-+                                              if (m.is_abstract) {
-+                                                      Symbol sym = null;
-+                                                      var base_class = this;
-+                                                      while (base_class != null && !(sym is Method)) {
-+                                                              sym = base_class.scope.lookup (m.name);
-+                                                              base_class = base_class.base_class;
-+                                                      }
-+                                                      if (!(sym is Method)) {
-+                                                              error = true;
-+                                                              Report.error (source_reference, "`%s' does not implement interface method `%s'".printf (get_full_name (), m.get_full_name ()));
-+                                                      }
-+                                              }
-+                                      }
-+
-+                                      /* check properties */
-+                                      foreach (Property prop in iface.get_properties ()) {
-+                                              if (prop.is_abstract) {
-+                                                      Symbol sym = null;
-+                                                      var base_class = this;
-+                                                      while (base_class != null && !(sym is Property)) {
-+                                                              sym = base_class.scope.lookup (prop.name);
-+                                                              base_class = base_class.base_class;
-+                                                      }
-+                                                      if (!(sym is Property)) {
-+                                                              error = true;
-+                                                              Report.error (source_reference, "`%s' does not implement interface property `%s'".printf (get_full_name (), prop.get_full_name ()));
-+                                                      }
-+                                              }
-+                                      }
-+                              }
-+                      }
-+
-+                      /* all abstract symbols defined in base classes have to be implemented in non-abstract classes */
-+                      if (!is_abstract) {
-+                              var base_class = base_class;
-+                              while (base_class != null && base_class.is_abstract) {
-+                                      foreach (Method base_method in base_class.get_methods ()) {
-+                                              if (base_method.is_abstract) {
-+                                                      var override_method = analyzer.symbol_lookup_inherited (this, base_method.name) as Method;
-+                                                      if (override_method == null || !override_method.overrides) {
-+                                                              error = true;
-+                                                              Report.error (source_reference, "`%s' does not implement abstract method `%s'".printf (get_full_name (), base_method.get_full_name ()));
-+                                                      }
-+                                              }
-+                                      }
-+                                      foreach (Property base_property in base_class.get_properties ()) {
-+                                              if (base_property.is_abstract) {
-+                                                      var override_property = analyzer.symbol_lookup_inherited (this, base_property.name) as Property;
-+                                                      if (override_property == null || !override_property.overrides) {
-+                                                              error = true;
-+                                                              Report.error (source_reference, "`%s' does not implement abstract property `%s'".printf (get_full_name (), base_property.get_full_name ()));
-+                                                      }
-+                                              }
-+                                      }
-+                                      base_class = base_class.base_class;
-+                              }
-+                      }
-+              }
-+
-+              analyzer.current_source_file = old_source_file;
-+              analyzer.current_symbol = old_symbol;
-+              analyzer.current_class = old_class;
-+
-+              return !error;
-+      }
- }
-Index: vala/valaforstatement.vala
-===================================================================
---- vala/valaforstatement.vala (revision 1971)
-+++ vala/valaforstatement.vala (revision 2004)
-@@ -156,4 +156,40 @@
-                       }
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              accept_children (analyzer);
-+
-+              if (condition != null && condition.error) {
-+                      /* if there was an error in the condition, skip this check */
-+                      error = true;
-+                      return false;
-+              }
-+
-+              if (condition != null && !condition.value_type.compatible (analyzer.bool_type)) {
-+                      error = true;
-+                      Report.error (condition.source_reference, "Condition must be boolean");
-+                      return false;
-+              }
-+
-+              if (condition != null) {
-+                      add_error_types (condition.get_error_types ());
-+              }
-+
-+              add_error_types (body.get_error_types ());
-+              foreach (Expression exp in get_initializer ()) {
-+                      add_error_types (exp.get_error_types ());
-+              }
-+              foreach (Expression exp in get_iterator ()) {
-+                      add_error_types (exp.get_error_types ());
-+              }
-+
-+              return !error;
-+      }
- }
-Index: vala/valaarraycreationexpression.vala
-===================================================================
---- vala/valaarraycreationexpression.vala      (revision 1971)
-+++ vala/valaarraycreationexpression.vala      (revision 2004)
-@@ -106,4 +106,118 @@
-                       element_type = new_type;
-               }
-       }
-+
-+      private int create_sizes_from_initializer_list (SemanticAnalyzer analyzer, InitializerList il, int rank, Gee.List<Literal> sl) {
-+              var init = new IntegerLiteral (il.size.to_string (), il.source_reference);
-+              init.accept (analyzer);
-+              sl.add (init);
-+
-+              int subsize = -1;
-+              foreach (Expression e in il.get_initializers ()) {
-+                      if (e is InitializerList) {
-+                              if (rank == 1) {
-+                                      il.error = true;
-+                                      e.error = true;
-+                                      Report.error (e.source_reference, "Expected array element, got array initializer list");
-+                                      return -1;
-+                              }
-+                              int size = create_sizes_from_initializer_list (analyzer, (InitializerList) e, rank - 1, sl);
-+                              if (size == -1) {
-+                                      return -1;
-+                              }
-+                              if (subsize >= 0 && subsize != size) {
-+                                      il.error = true;
-+                                      Report.error (il.source_reference, "Expected initializer list of size %d, got size %d".printf (subsize, size));
-+                                      return -1;
-+                              } else {
-+                                      subsize = size;
-+                              }
-+                      } else {
-+                              if (rank != 1) {
-+                                      il.error = true;
-+                                      e.error = true;
-+                                      Report.error (e.source_reference, "Expected array initializer list, got array element");
-+                                      return -1;
-+                              }
-+                      }
-+              }
-+              return il.size;
-+      }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              Gee.List<Expression> size = get_sizes ();
-+              var initlist = initializer_list;
-+
-+              if (element_type != null) {
-+                      element_type.accept (analyzer);
-+              }
-+
-+              foreach (Expression e in size) {
-+                      e.accept (analyzer);
-+              }
-+
-+              var calc_sizes = new ArrayList<Literal> ();
-+              if (initlist != null) {
-+                      initlist.target_type = new ArrayType (element_type, rank, source_reference);
-+
-+                      initlist.accept (analyzer);
-+
-+                      var ret = create_sizes_from_initializer_list (analyzer, initlist, rank, calc_sizes);
-+                      if (ret == -1) {
-+                              error = true;
-+                      }
-+              }
-+
-+              if (size.size > 0) {
-+                      /* check for errors in the size list */
-+                      foreach (Expression e in size) {
-+                              if (e.value_type == null) {
-+                                      /* return on previous error */
-+                                      return false;
-+                              } else if (!(e.value_type.data_type is Struct) || !((Struct) e.value_type.data_type).is_integer_type ()) {
-+                                      error = true;
-+                                      Report.error (e.source_reference, "Expression of integer type expected");
-+                              }
-+                      }
-+              } else {
-+                      if (initlist == null) {
-+                              error = true;
-+                              /* this is an internal error because it is already handeld by the parser */
-+                              Report.error (source_reference, "internal error: initializer list expected");
-+                      } else {
-+                              foreach (Expression size in calc_sizes) {
-+                                      append_size (size);
-+                              }
-+                      }
-+              }
-+
-+              if (error) {
-+                      return false;
-+              }
-+
-+              /* check for wrong elements inside the initializer */
-+              if (initializer_list != null && initializer_list.value_type == null) {
-+                      return false;
-+              }
-+
-+              /* try to construct the type of the array */
-+              if (element_type == null) {
-+                      error = true;
-+                      Report.error (source_reference, "Cannot determine the element type of the created array");
-+                      return false;
-+              }
-+
-+              element_type.value_owned = true;
-+
-+              value_type = new ArrayType (element_type, rank, source_reference);
-+              value_type.value_owned = true;
-+
-+              return !error;
-+      }
- }
-Index: vala/valastruct.vala
-===================================================================
---- vala/valastruct.vala       (revision 1971)
-+++ vala/valastruct.vala       (revision 2004)
-@@ -605,4 +605,28 @@
-               return false;
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              process_attributes ();
-+
-+              analyzer.current_symbol = this;
-+              analyzer.current_struct = this;
-+
-+              accept_children (analyzer);
-+
-+              if (!external && !external_package && get_base_types ().size == 0 && get_fields ().size == 0) {
-+                      Report.error (source_reference, "structs cannot be empty");
-+              }
-+
-+              analyzer.current_symbol = analyzer.current_symbol.parent_symbol;
-+              analyzer.current_struct = null;
-+
-+              return !error;
-+      }
- }
-Index: vala/valaconstructor.vala
-===================================================================
---- vala/valaconstructor.vala  (revision 1971)
-+++ vala/valaconstructor.vala  (revision 2004)
-@@ -60,4 +60,28 @@
-                       body.accept (visitor);
-               }
-       }
-+
-+      public override bool check (SemanticAnalyzer analyzer) {
-+              if (checked) {
-+                      return !error;
-+              }
-+
-+              checked = true;
-+
-+              this_parameter = new FormalParameter ("this", new ObjectType (analyzer.current_class));
-+              scope.add (this_parameter.name, this_parameter);
-+
-+              owner = analyzer.current_symbol.scope;
-+              analyzer.current_symbol = this;
-+
-+              accept_children (analyzer);
-+
-+              foreach (DataType body_error_type in body.get_error_types ()) {
-+                      Report.warning (body_error_type.source_reference, "unhandled error `%s'".printf (body_error_type.to_string()));
-+              }
-+
-+              analyzer.current_symbol = analyzer.current_symbol.parent_symbol;
-+
-+              return !error;
-+      }
- }
-Index: ChangeLog
-===================================================================
---- ChangeLog  (revision 1971)
-+++ ChangeLog  (revision 2004)
-@@ -1,5 +1,273 @@
-+2008-11-09  Jürg Billeter  <j@bitron.ch>
-+
-+      * vala/valaclass.vala:
-+      * vala/valainterface.vala:
-+      * vala/valamemberaccess.vala:
-+      * vala/valaobjecttype.vala:
-+      * vala/valasemanticanalyzer.vala:
-+
-+      Ensure attributes of base types are processed before querying
-+      C header filenames
-+
-+2008-11-07  Jürg Billeter  <j@bitron.ch>
-+
-+      * vala/valablock.vala:
-+      * vala/valacatchclause.vala:
-+      * vala/valadeclarationstatement.vala:
-+      * vala/valadeletestatement.vala:
-+      * vala/valadostatement.vala:
-+      * vala/valaexpressionstatement.vala:
-+      * vala/valaforstatement.vala:
-+      * vala/valaifstatement.vala:
-+      * vala/valainitializerlist.vala:
-+      * vala/valalocalvariable.vala:
-+      * vala/valalockstatement.vala:
-+      * vala/valasemanticanalyzer.vala:
-+      * vala/valaswitchsection.vala:
-+      * vala/valatrystatement.vala:
-+      * vala/valawhilestatement.vala:
-+
-+      Move statement checking to code nodes
-+
-+2008-11-07  Jürg Billeter  <j@bitron.ch>
-+
-+      * vapi/glib-2.0.vapi:
-+
-+      Add g_rmdir binding
-+
-+2008-11-07  Jürg Billeter  <j@bitron.ch>
-+
-+      * gobject/valadbusclientmodule.vala:
-+
-+      Fix D-Bus methods with out parameters but no return value
-+
-+2008-11-07  Jürg Billeter  <j@bitron.ch>
-+
-+      * vala/valaconstant.vala:
-+      * vala/valaconstructor.vala:
-+      * vala/valacreationmethod.vala:
-+      * vala/valadestructor.vala:
-+      * vala/valafield.vala:
-+      * vala/valaformalparameter.vala:
-+      * vala/valaproperty.vala:
-+      * vala/valapropertyaccessor.vala:
-+      * vala/valasemanticanalyzer.vala:
-+      * vala/valasignal.vala:
-+
-+      Move member checking to code nodes
-+
-+2008-11-07  Jürg Billeter  <j@bitron.ch>
-+
-+      * vala/valadelegate.vala:
-+      * vala/valaenum.vala:
-+      * vala/valaenumvalue.vala:
-+      * vala/valaerrorcode.vala:
-+      * vala/valaerrordomain.vala:
-+      * vala/valainterface.vala:
-+      * vala/valanamespace.vala:
-+      * vala/valasemanticanalyzer.vala:
-+      * vala/valastruct.vala:
-+
-+      Move type symbol checking to code nodes
-+
-+2008-11-07  Jürg Billeter  <j@bitron.ch>
-+
-+      * vala/valaarraycreationexpression.vala:
-+      * vala/valasemanticanalyzer.vala:
-+
-+      Move array creation expression checking to
-+      ArrayCreationExpression.check
-+
-+2008-11-07  Jürg Billeter  <j@bitron.ch>
-+
-+      * vala/valasemanticanalyzer.vala:
-+      * vala/valathrowstatement.vala:
-+
-+      Move throw statement checking to ThrowStatement.check
-+
-+2008-11-07  Jürg Billeter  <j@bitron.ch>
-+
-+      * vala/valareturnstatement.vala:
-+      * vala/valasemanticanalyzer.vala:
-+
-+      Move return statement checking to ReturnStatement.check
-+
-+2008-11-07  Jürg Billeter  <j@bitron.ch>
-+
-+      * vala/valaforeachstatement.vala:
-+      * vala/valasemanticanalyzer.vala:
-+
-+      Move foreach statement checking to ForeachStatement.check
-+
-+2008-11-07  Jürg Billeter  <j@bitron.ch>
-+
-+      * vala/valaelementaccess.vala:
-+      * vala/valasemanticanalyzer.vala:
-+
-+      Move element access checking to ElementAccess.check
-+
-+2008-11-07  Jürg Billeter  <j@bitron.ch>
-+
-+      * vapigen/valagirparser.vala:
-+
-+      Set source_reference in parsed nodes
-+
-+2008-11-06  Jürg Billeter  <j@bitron.ch>
-+
-+      * vala/valamethod.vala:
-+      * vala/valasemanticanalyzer.vala:
-+
-+      Move method checking to Method.check
-+
-+2008-11-06  Jürg Billeter  <j@bitron.ch>
-+
-+      * vala/valaclass.vala:
-+      * vala/valasemanticanalyzer.vala:
-+
-+      Move class checking to Class.check
-+
-+2008-11-06  Jürg Billeter  <j@bitron.ch>
-+
-+      * gobject/Makefile.am:
-+      * gobject/valaccodedynamicsignalmodule.vala:
-+      * gobject/valaccodegenerator.vala:
-+      * gobject/valadbusclientmodule.vala:
-+      * gobject/valagerrormodule.vala:
-+      * gobject/valagobjectmodule.vala:
-+
-+      Move dynamic signal generation to GObjectModule and
-+      DBusClientModule
-+
-+2008-11-06  Jürg Billeter  <j@bitron.ch>
-+
-+      * gobject/Makefile.am:
-+      * gobject/valaccodedynamicpropertymodule.vala:
-+      * gobject/valaccodedynamicsignalmodule.vala:
-+      * gobject/valaccodegenerator.vala:
-+      * gobject/valadbusclientmodule.vala:
-+      * gobject/valagobjectmodule.vala:
-+
-+      Move dynamic property generation to GObjectModule and
-+      DBusClientModule
-+
-+2008-11-06  Jürg Billeter  <j@bitron.ch>
-+
-+      * gobject/valaccodebasemodule.vala:
-+      * gobject/valagobjectmodule.vala:
-+
-+      Move constructor code generation to GObjectModule
-+
-+2008-11-05  Jürg Billeter  <j@bitron.ch>
-+
-+      * vala/valainvocationexpression.vala:
-+      * vala/valasemanticanalyzer.vala:
-+
-+      Move invocation expression checking to InvocationExpression.check
-+
-+2008-11-05  Jürg Billeter  <j@bitron.ch>
-+
-+      * vala/valamemberaccess.vala:
-+      * vala/valasemanticanalyzer.vala:
-+
-+      Move member access checking to MemberAccess.check
-+
-+2008-11-05  Jürg Billeter  <j@bitron.ch>
-+
-+      * vala/valabinaryexpression.vala:
-+      * vala/valaobjectcreationexpression.vala:
-+      * vala/valasemanticanalyzer.vala:
-+
-+      Move object creation expression checking to
-+      ObjectCreationExpression.check
-+
-+2008-11-05  Jürg Billeter  <j@bitron.ch>
-+
-+      * vala/valabinaryexpression.vala:
-+      * vala/valasemanticanalyzer.vala:
-+
-+      Move binary expression checking to BinaryExpression.check
-+
-+2008-11-05  Jürg Billeter  <j@bitron.ch>
-+
-+      * vala/valaassignment.vala:
-+      * vala/valasemanticanalyzer.vala:
-+
-+      Move assignment checking to Assignment.check
-+
-+2008-11-05  Jürg Billeter  <j@bitron.ch>
-+
-+      * vala/valaenum.vala:
-+      * gobject/valadbusclientmodule.vala:
-+      * gobject/valagsignalmodule.vala:
-+
-+      Support enums in D-Bus clients and servers, fixes bug 534105
-+
-+2008-11-05  Jürg Billeter  <j@bitron.ch>
-+
-+      * gobject/Makefile.am:
-+      * gobject/valaccodebasemodule.vala:
-+      * gobject/valaccodecontrolflowmodule.vala:
-+      * gobject/valaccodegenerator.vala:
-+      * gobject/valaccodememberaccessmodule.vala:
-+
-+      Add CCodeControlFlowModule
-+
-+2008-11-04  Jürg Billeter  <j@bitron.ch>
-+
-+      * vala/valadynamicproperty.vala:
-+      * vala/valaproperty.vala:
-+      * vala/valasemanticanalyzer.vala:
-+
-+      Fix crash when using dynamic properties, fixes bug 559304
-+
-+2008-11-04  Jürg Billeter  <j@bitron.ch>
-+
-+      * gobject/valaccodememberaccessmodule.vala:
-+      * gobject/valagsignalmodule.vala:
-+
-+      Move signal emission to GSignalModule
-+
-+2008-11-04  Jürg Billeter  <j@bitron.ch>
-+
-+      * gobject/valaccodebasemodule.vala:
-+      * gobject/valaccodedelegatemodule.vala:
-+
-+      Move delegate wrapper generation to CCodeDelegateModule
-+
-+2008-11-04  Jürg Billeter  <j@bitron.ch>
-+
-+      * gobject/valaccodearraymodule.vala:
-+      * gobject/valaccodebasemodule.vala:
-+
-+      Move array dup wrapper generation to CCodeArrayModule
-+
-+2008-11-04  Jürg Billeter  <j@bitron.ch>
-+
-+      * gobject/valaccodebasemodule.vala:
-+      * gobject/valagobjectmodule.vala:
-+
-+      Move construct property assignment to GObjectModule
-+
-+2008-11-04  Jürg Billeter  <j@bitron.ch>
-+
-+      * gobject/valaccodeassignmentmodule.vala:
-+      * gobject/valagsignalmodule.vala:
-+
-+      Move signal connection and disconnection to GSignalModule
-+
-+2008-11-04  Jürg Billeter  <j@bitron.ch>
-+
-+      * gobject/valaccodearraymodule.vala:
-+      * gobject/valagsignalmodule.vala:
-+
-+      Move detailed signal emission to GSignalModule
-+
- 2008-11-03  Jürg Billeter  <j@bitron.ch>
-+      * configure.ac: Post-release version bump
-+
-+2008-11-03  Jürg Billeter  <j@bitron.ch>
-+
-       * NEWS: update for 0.5.1 release
- 2008-11-03  Jürg Billeter  <j@bitron.ch>
-Index: vapigen/valagirparser.vala
-===================================================================
---- vapigen/valagirparser.vala (revision 1971)
-+++ vapigen/valagirparser.vala (revision 2004)
-@@ -153,7 +153,10 @@
-                       ns = new Namespace (namespace_name);
-                       new_namespace = true;
-               } else {
--                      ns.source_reference = new SourceReference (current_source_file);
-+                      if (ns.external_package) {
-+                              ns.attributes = null;
-+                              ns.source_reference = get_current_src ();
-+                      }
-               }
-               string cheader = get_attribute (ns.name, "c:header-filename");
-@@ -221,7 +224,7 @@
-       Struct parse_alias () {
-               start_element ("alias");
--              var st = new Struct (reader.get_attribute ("name"));
-+              var st = new Struct (reader.get_attribute ("name"), get_current_src ());
-               st.access = SymbolAccessibility.PUBLIC;
-               st.add_base_type (parse_type_from_name (reader.get_attribute ("target")));
-               next ();
-@@ -231,7 +234,7 @@
-       Enum parse_enumeration () {
-               start_element ("enumeration");
--              var en = new Enum (reader.get_attribute ("name"));
-+              var en = new Enum (reader.get_attribute ("name"), get_current_src ());
-               en.access = SymbolAccessibility.PUBLIC;
-               next ();
-@@ -274,7 +277,7 @@
-       Enum parse_bitfield () {
-               start_element ("bitfield");
--              var en = new Enum (reader.get_attribute ("name"));
-+              var en = new Enum (reader.get_attribute ("name"), get_current_src ());
-               en.access = SymbolAccessibility.PUBLIC;
-               next ();
-               while (current_token == MarkupTokenType.START_ELEMENT) {
-@@ -308,7 +311,7 @@
-               } else {
-                       return_type = new VoidType ();
-               }
--              var m = new Method (name, return_type);
-+              var m = new Method (name, return_type, get_current_src ());
-               m.access = SymbolAccessibility.PUBLIC;
-               m.binding = MemberBinding.STATIC;
-               var parameters = new ArrayList<FormalParameter> ();
-@@ -360,14 +363,14 @@
-               if (reader.name == "varargs") {
-                       start_element ("varargs");
-                       next ();
--                      param = new FormalParameter.with_ellipsis ();
-+                      param = new FormalParameter.with_ellipsis (get_current_src ());
-                       end_element ("varargs");
-               } else {
-                       var type = parse_type (out array_length_idx);
-                       if (transfer == "full") {
-                               type.value_owned = true;
-                       }
--                      param = new FormalParameter (name, type);
-+                      param = new FormalParameter (name, type, get_current_src ());
-                       if (direction == "out") {
-                               param.direction = ParameterDirection.OUT;
-                       } else if (direction == "inout") {
-@@ -455,7 +458,7 @@
-       Struct parse_record () {
-               start_element ("record");
--              var st = new Struct (reader.get_attribute ("name"));
-+              var st = new Struct (reader.get_attribute ("name"), get_current_src ());
-               st.access = SymbolAccessibility.PUBLIC;
-               next ();
-               while (current_token == MarkupTokenType.START_ELEMENT) {
-@@ -479,7 +482,7 @@
-       Class parse_class () {
-               start_element ("class");
--              var cl = new Class (reader.get_attribute ("name"));
-+              var cl = new Class (reader.get_attribute ("name"), get_current_src ());
-               cl.access = SymbolAccessibility.PUBLIC;
-               string parent = reader.get_attribute ("parent");
-@@ -575,7 +578,7 @@
-       Interface parse_interface () {
-               start_element ("interface");
--              var iface = new Interface (reader.get_attribute ("name"));
-+              var iface = new Interface (reader.get_attribute ("name"), get_current_src ());
-               iface.access = SymbolAccessibility.PUBLIC;
-               next ();
-               var methods = new ArrayList<Method> ();
-@@ -619,7 +622,7 @@
-               string name = reader.get_attribute ("name");
-               next ();
-               var type = parse_type ();
--              var field = new Field (name, type, null);
-+              var field = new Field (name, type, null, get_current_src ());
-               field.access = SymbolAccessibility.PUBLIC;
-               end_element ("field");
-               return field;
-@@ -630,7 +633,7 @@
-               string name = string.joinv ("_", reader.get_attribute ("name").split ("-"));
-               next ();
-               var type = parse_type ();
--              var prop = new Property (name, type, null, null);
-+              var prop = new Property (name, type, null, null, get_current_src ());
-               prop.access = SymbolAccessibility.PUBLIC;
-               prop.get_accessor = new PropertyAccessor (true, false, false, null, null);
-               prop.set_accessor = new PropertyAccessor (false, true, false, null, null);
-@@ -648,7 +651,7 @@
-               } else {
-                       return_type = new VoidType ();
-               }
--              var d = new Delegate (name, return_type);
-+              var d = new Delegate (name, return_type, get_current_src ());
-               d.access = SymbolAccessibility.PUBLIC;
-               if (current_token == MarkupTokenType.START_ELEMENT && reader.name == "parameters") {
-                       start_element ("parameters");
-@@ -669,7 +672,7 @@
-               var return_type = parse_return_value ();
--              var m = new CreationMethod (null, name);
-+              var m = new CreationMethod (null, name, get_current_src ());
-               m.access = SymbolAccessibility.PUBLIC;
-               m.has_construct_function = false;
-               if (m.name.has_prefix ("new_")) {
-@@ -698,7 +701,7 @@
-               } else {
-                       return_type = new VoidType ();
-               }
--              var m = new Method (name, return_type);
-+              var m = new Method (name, return_type, get_current_src ());
-               m.access = SymbolAccessibility.PUBLIC;
-               if (current_token == MarkupTokenType.START_ELEMENT && reader.name == "parameters") {
-                       start_element ("parameters");
-@@ -726,7 +729,7 @@
-               } else {
-                       return_type = new VoidType ();
-               }
--              var m = new Method (name, return_type);
-+              var m = new Method (name, return_type, get_current_src ());
-               m.access = SymbolAccessibility.PUBLIC;
-               m.is_virtual = true;
-               if (current_token == MarkupTokenType.START_ELEMENT && reader.name == "parameters") {
-@@ -828,7 +831,7 @@
-               string name = reader.get_attribute ("name");
-               next ();
-               var type = parse_type ();
--              var c = new Constant (name, type, null, null);
-+              var c = new Constant (name, type, null, get_current_src ());
-               c.access = SymbolAccessibility.PUBLIC;
-               end_element ("constant");
-               return c;
-Index: vapi/glib-2.0.vapi
-===================================================================
---- vapi/glib-2.0.vapi (revision 1971)
-+++ vapi/glib-2.0.vapi (revision 2004)
-@@ -2205,6 +2205,8 @@
-               public static int create_with_parents (string pathname, int mode);
-               [CCode (cname = "mkdtemp")]
-               public static weak string mkdtemp (string template);
-+              [CCode (cname = "g_rmdir")]
-+              public static int remove (string filename);
-       }
-       [Compact]
-Index: configure.ac
-===================================================================
---- configure.ac       (revision 1971)
-+++ configure.ac       (revision 2004)
-@@ -1,4 +1,4 @@
--AC_INIT([vala], [0.5.1], [j@bitron.ch], [vala])
-+AC_INIT([vala], [0.5.2], [j@bitron.ch], [vala])
- AC_CONFIG_SRCDIR([Makefile.am])
- AC_CONFIG_HEADERS(config.h)
- AM_INIT_AUTOMAKE([dist-bzip2])
-Index: gobject/valaccodedynamicpropertymodule.vala
-===================================================================
---- gobject/valaccodedynamicpropertymodule.vala        (revision 1971)
-+++ gobject/valaccodedynamicpropertymodule.vala        (revision 2004)
-@@ -1,238 +0,0 @@
--/* valaccodedynamicpropertymodule.vala
-- *
-- * Copyright (C) 2008  Jürg Billeter
-- *
-- * This library is free software; you can redistribute it and/or
-- * modify it under the terms of the GNU Lesser General Public
-- * License as published by the Free Software Foundation; either
-- * version 2.1 of the License, or (at your option) any later version.
--
-- * This library is distributed in the hope that it will be useful,
-- * but WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-- * Lesser General Public License for more details.
--
-- * You should have received a copy of the GNU Lesser General Public
-- * License along with this library; if not, write to the Free Software
-- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
-- *
-- * Author:
-- *    Jürg Billeter <j@bitron.ch>
-- */
--
--using GLib;
--using Gee;
--
--/**
-- * The link between a dynamic property and generated code.
-- */
--public class Vala.CCodeDynamicPropertyModule : CCodeDelegateModule {
--      int dynamic_property_id;
--
--      public CCodeDynamicPropertyModule (CCodeGenerator codegen, CCodeModule? next) {
--              base (codegen, next);
--      }
--
--      public override string get_dynamic_property_getter_cname (DynamicProperty node) {
--              string getter_cname = "_dynamic_get_%s%d".printf (node.name, dynamic_property_id++);
--
--              var dynamic_property = (DynamicProperty) node;
--
--              var func = new CCodeFunction (getter_cname, node.property_type.get_cname ());
--              func.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.INLINE;
--
--              func.add_parameter (new CCodeFormalParameter ("obj", dynamic_property.dynamic_type.get_cname ()));
--
--              var block = new CCodeBlock ();
--              if (dynamic_property.dynamic_type.data_type == dbus_object_type) {
--                      generate_dbus_property_getter_wrapper (node, block);
--              } else if (dynamic_property.dynamic_type.data_type != null
--                         && dynamic_property.dynamic_type.data_type.is_subtype_of (gobject_type)) {
--                      generate_gobject_property_getter_wrapper (node, block);
--              } else {
--                      Report.error (node.source_reference, "dynamic properties are not supported for `%s'".printf (dynamic_property.dynamic_type.to_string ()));
--              }
--
--              // append to C source file
--              source_type_member_declaration.append (func.copy ());
--
--              func.block = block;
--              source_type_member_definition.append (func);
--
--              return getter_cname;
--      }
--
--      public override string get_dynamic_property_setter_cname (DynamicProperty node) {
--              string setter_cname = "_dynamic_set_%s%d".printf (node.name, dynamic_property_id++);
--
--              var dynamic_property = (DynamicProperty) node;
--
--              var func = new CCodeFunction (setter_cname, "void");
--              func.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.INLINE;
--
--              func.add_parameter (new CCodeFormalParameter ("obj", dynamic_property.dynamic_type.get_cname ()));
--              func.add_parameter (new CCodeFormalParameter ("value", node.property_type.get_cname ()));
--
--              var block = new CCodeBlock ();
--              if (dynamic_property.dynamic_type.data_type == dbus_object_type) {
--                      generate_dbus_property_setter_wrapper (node, block);
--              } else if (dynamic_property.dynamic_type.data_type != null
--                         && dynamic_property.dynamic_type.data_type.is_subtype_of (gobject_type)) {
--                      generate_gobject_property_setter_wrapper (node, block);
--              } else {
--                      Report.error (node.source_reference, "dynamic properties are not supported for `%s'".printf (dynamic_property.dynamic_type.to_string ()));
--              }
--
--              // append to C source file
--              source_type_member_declaration.append (func.copy ());
--
--              func.block = block;
--              source_type_member_definition.append (func);
--
--              return setter_cname;
--      }
--
--      void generate_gobject_property_getter_wrapper (DynamicProperty node, CCodeBlock block) {
--              var cdecl = new CCodeDeclaration (node.property_type.get_cname ());
--              cdecl.add_declarator (new CCodeVariableDeclarator ("result"));
--              block.add_statement (cdecl);
--
--              var call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get"));
--              call.add_argument (new CCodeIdentifier ("obj"));
--              call.add_argument (node.get_canonical_cconstant ());
--              call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result")));
--              call.add_argument (new CCodeConstant ("NULL"));
--
--              block.add_statement (new CCodeExpressionStatement (call));
--
--              block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
--      }
--
--      void generate_gobject_property_setter_wrapper (DynamicProperty node, CCodeBlock block) {
--              var call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_set"));
--              call.add_argument (new CCodeIdentifier ("obj"));
--              call.add_argument (node.get_canonical_cconstant ());
--              call.add_argument (new CCodeIdentifier ("value"));
--              call.add_argument (new CCodeConstant ("NULL"));
--
--              block.add_statement (new CCodeExpressionStatement (call));
--      }
--
--      void create_dbus_property_proxy (DynamicProperty node, CCodeBlock block) {
--              var prop_proxy_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_new_from_proxy"));
--              prop_proxy_call.add_argument (new CCodeIdentifier ("obj"));
--              prop_proxy_call.add_argument (new CCodeConstant ("DBUS_INTERFACE_PROPERTIES"));
--              prop_proxy_call.add_argument (new CCodeConstant ("NULL"));
--
--              var prop_proxy_decl = new CCodeDeclaration ("DBusGProxy*");
--              prop_proxy_decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("property_proxy", prop_proxy_call));
--              block.add_statement (prop_proxy_decl);
--      }
--
--      void generate_dbus_property_getter_wrapper (DynamicProperty node, CCodeBlock block) {
--              create_dbus_property_proxy (node, block);
--
--              // initialize GValue
--              var cvalinit = new CCodeInitializerList ();
--              cvalinit.append (new CCodeConstant ("0"));
--
--              var cval_decl = new CCodeDeclaration ("GValue");
--              cval_decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("gvalue", cvalinit));
--              block.add_statement (cval_decl);
--
--              var val_ptr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("gvalue"));
--
--              // call Get method on property proxy
--              var cdecl = new CCodeDeclaration (node.property_type.get_cname ());
--              cdecl.add_declarator (new CCodeVariableDeclarator ("result"));
--              block.add_statement (cdecl);
--
--              var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_call"));
--              ccall.add_argument (new CCodeIdentifier ("property_proxy"));
--              ccall.add_argument (new CCodeConstant ("\"Get\""));
--              ccall.add_argument (new CCodeConstant ("NULL"));
--
--              ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING"));
--              var get_iface = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_interface"));
--              get_iface.add_argument (new CCodeIdentifier ("obj"));
--              ccall.add_argument (get_iface);
--
--              ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING"));
--              ccall.add_argument (new CCodeConstant ("\"%s\"".printf (Symbol.lower_case_to_camel_case (node.name))));
--
--              ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
--
--              ccall.add_argument (new CCodeIdentifier ("G_TYPE_VALUE"));
--              ccall.add_argument (val_ptr);
--
--              ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
--
--              block.add_statement (new CCodeExpressionStatement (ccall));
--
--              // unref property proxy
--              var prop_proxy_unref = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
--              prop_proxy_unref.add_argument (new CCodeIdentifier ("property_proxy"));
--              block.add_statement (new CCodeExpressionStatement (prop_proxy_unref));
--
--              // assign value to result variable
--              var cget_call = new CCodeFunctionCall (new CCodeIdentifier (node.property_type.data_type.get_get_value_function ()));
--              cget_call.add_argument (val_ptr);
--              var assign = new CCodeAssignment (new CCodeIdentifier ("result"), cget_call);
--              block.add_statement (new CCodeExpressionStatement (assign));
--
--              // return result
--              block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
--      }
--
--      void generate_dbus_property_setter_wrapper (DynamicProperty node, CCodeBlock block) {
--              create_dbus_property_proxy (node, block);
--
--              // initialize GValue
--              var cvalinit = new CCodeInitializerList ();
--              cvalinit.append (new CCodeConstant ("0"));
--
--              var cval_decl = new CCodeDeclaration ("GValue");
--              cval_decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("gvalue", cvalinit));
--              block.add_statement (cval_decl);
--
--              var val_ptr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("gvalue"));
--
--              var cinit_call = new CCodeFunctionCall (new CCodeIdentifier ("g_value_init"));
--              cinit_call.add_argument (val_ptr);
--              cinit_call.add_argument (new CCodeIdentifier (node.property_type.data_type.get_type_id ()));
--              block.add_statement (new CCodeExpressionStatement (cinit_call));
--
--              var cset_call = new CCodeFunctionCall (new CCodeIdentifier (node.property_type.data_type.get_set_value_function ()));
--              cset_call.add_argument (val_ptr);
--              cset_call.add_argument (new CCodeIdentifier ("value"));
--              block.add_statement (new CCodeExpressionStatement (cset_call));
--
--              // call Set method on property proxy
--              var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_call"));
--              ccall.add_argument (new CCodeIdentifier ("property_proxy"));
--              ccall.add_argument (new CCodeConstant ("\"Set\""));
--              ccall.add_argument (new CCodeConstant ("NULL"));
--
--              ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING"));
--              var get_iface = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_interface"));
--              get_iface.add_argument (new CCodeIdentifier ("obj"));
--              ccall.add_argument (get_iface);
--
--              ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING"));
--              ccall.add_argument (new CCodeConstant ("\"%s\"".printf (Symbol.lower_case_to_camel_case (node.name))));
--
--              ccall.add_argument (new CCodeIdentifier ("G_TYPE_VALUE"));
--              ccall.add_argument (val_ptr);
--
--              ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
--
--              ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
--
--              block.add_statement (new CCodeExpressionStatement (ccall));
--
--              // unref property proxy
--              var prop_proxy_unref = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
--              prop_proxy_unref.add_argument (new CCodeIdentifier ("property_proxy"));
--              block.add_statement (new CCodeExpressionStatement (prop_proxy_unref));
--      }
--}
-Index: gobject/valaccodedynamicsignalmodule.vala
-===================================================================
---- gobject/valaccodedynamicsignalmodule.vala  (revision 1971)
-+++ gobject/valaccodedynamicsignalmodule.vala  (revision 2004)
-@@ -1,195 +0,0 @@
--/* valaccodedynamicsignalmodule.vala
-- *
-- * Copyright (C) 2007-2008  Jürg Billeter
-- *
-- * This library is free software; you can redistribute it and/or
-- * modify it under the terms of the GNU Lesser General Public
-- * License as published by the Free Software Foundation; either
-- * version 2.1 of the License, or (at your option) any later version.
--
-- * This library is distributed in the hope that it will be useful,
-- * but WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-- * Lesser General Public License for more details.
--
-- * You should have received a copy of the GNU Lesser General Public
-- * License along with this library; if not, write to the Free Software
-- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
-- *
-- * Author:
-- *    Jürg Billeter <j@bitron.ch>
-- */
--
--using GLib;
--using Gee;
--
--/**
-- * The link between a dynamic signal and generated code.
-- */
--public class Vala.CCodeDynamicSignalModule : CCodeDynamicPropertyModule {
--      public CCodeDynamicSignalModule (CCodeGenerator codegen, CCodeModule? next) {
--              base (codegen, next);
--      }
--
--      int signal_wrapper_id;
--
--      public override string get_dynamic_signal_cname (DynamicSignal node) {
--              return "dynamic_%s%d_".printf (node.name, signal_wrapper_id++);
--      }
--
--      public override string get_dynamic_signal_connect_wrapper_name (DynamicSignal node) {
--              var dynamic_signal = (DynamicSignal) node;
--
--              string connect_wrapper_name = "_%sconnect".printf (get_dynamic_signal_cname (node));
--              var func = new CCodeFunction (connect_wrapper_name, "void");
--              func.add_parameter (new CCodeFormalParameter ("obj", "gpointer"));
--              func.add_parameter (new CCodeFormalParameter ("signal_name", "const char *"));
--              func.add_parameter (new CCodeFormalParameter ("handler", "GCallback"));
--              func.add_parameter (new CCodeFormalParameter ("data", "gpointer"));
--              var block = new CCodeBlock ();
--              if (dynamic_signal.dynamic_type.data_type == dbus_object_type) {
--                      generate_dbus_connect_wrapper (node, block);
--              } else if (dynamic_signal.dynamic_type.data_type != null
--                         && dynamic_signal.dynamic_type.data_type.is_subtype_of (gobject_type)) {
--                      generate_gobject_connect_wrapper (node, block);
--              } else {
--                      Report.error (node.source_reference, "dynamic signals are not supported for `%s'".printf (dynamic_signal.dynamic_type.to_string ()));
--              }
--
--              // append to C source file
--              source_type_member_declaration.append (func.copy ());
--
--              func.block = block;
--              source_type_member_definition.append (func);
--
--              return connect_wrapper_name;
--      }
--
--      public override string get_dynamic_signal_disconnect_wrapper_name (DynamicSignal node) {
--              var dynamic_signal = (DynamicSignal) node;
--
--              string disconnect_wrapper_name = "_%sdisconnect".printf (get_dynamic_signal_cname (node));
--              var func = new CCodeFunction (disconnect_wrapper_name, "void");
--              func.add_parameter (new CCodeFormalParameter ("obj", "gpointer"));
--              func.add_parameter (new CCodeFormalParameter ("signal_name", "const char *"));
--              func.add_parameter (new CCodeFormalParameter ("handler", "GCallback"));
--              func.add_parameter (new CCodeFormalParameter ("data", "gpointer"));
--              var block = new CCodeBlock ();
--              if (dynamic_signal.dynamic_type.data_type == dbus_object_type) {
--                      generate_dbus_disconnect_wrapper (node, block);
--              } else {
--                      Report.error (node.source_reference, "dynamic signals are not supported for `%s'".printf (dynamic_signal.dynamic_type.to_string ()));
--              }
--
--              // append to C source file
--              source_type_member_declaration.append (func.copy ());
--
--              func.block = block;
--              source_type_member_definition.append (func);
--
--              return disconnect_wrapper_name;
--      }
--
--      void generate_gobject_connect_wrapper (DynamicSignal node, CCodeBlock block) {
--              var dynamic_signal = (DynamicSignal) node;
--
--              var m = (Method) dynamic_signal.handler.symbol_reference;
--
--              node.accept (codegen);
--
--              string connect_func = "g_signal_connect_object";
--              if (m.binding != MemberBinding.INSTANCE) {
--                      connect_func = "g_signal_connect";
--              }
--
--              var call = new CCodeFunctionCall (new CCodeIdentifier (connect_func));
--              call.add_argument (new CCodeIdentifier ("obj"));
--              call.add_argument (new CCodeIdentifier ("signal_name"));
--              call.add_argument (new CCodeIdentifier ("handler"));
--              call.add_argument (new CCodeIdentifier ("data"));
--
--              if (m.binding == MemberBinding.INSTANCE) {
--                      call.add_argument (new CCodeConstant ("0"));
--              }
--
--              block.add_statement (new CCodeExpressionStatement (call));
--      }
--
--      void generate_dbus_connect_wrapper (DynamicSignal node, CCodeBlock block) {
--              var dynamic_signal = (DynamicSignal) node;
--
--              var m = (Method) dynamic_signal.handler.symbol_reference;
--
--              node.accept (codegen);
--
--              // FIXME should only be done once per marshaller
--              var register_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_object_register_marshaller"));
--              head.generate_marshaller (node.get_parameters (), node.return_type, true);
--              register_call.add_argument (new CCodeIdentifier (head.get_marshaller_function (node.get_parameters (), node.return_type, null, true)));
--              register_call.add_argument (new CCodeIdentifier ("G_TYPE_NONE"));
--
--              var add_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_add_signal"));
--              add_call.add_argument (new CCodeIdentifier ("obj"));
--              add_call.add_argument (new CCodeConstant ("\"%s\"".printf (Symbol.lower_case_to_camel_case (node.name))));
--
--              bool first = true;
--              foreach (FormalParameter param in m.get_parameters ()) {
--                      if (first) {
--                              // skip sender parameter
--                              first = false;
--                              continue;
--                      }
--
--                      var array_type = param.parameter_type as ArrayType;
--                      if (array_type != null) {
--                              if (array_type.element_type.data_type == string_type.data_type) {
--                                      register_call.add_argument (new CCodeIdentifier ("G_TYPE_STRV"));
--                                      add_call.add_argument (new CCodeIdentifier ("G_TYPE_STRV"));
--                              } else {
--                                      if (array_type.element_type.data_type.get_type_id () == null) {
--                                              Report.error (param.source_reference, "unsupported parameter type for D-Bus signals");
--                                              return;
--                                      }
--
--                                      var carray_type = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_type_get_collection"));
--                                      carray_type.add_argument (new CCodeConstant ("\"GArray\""));
--                                      carray_type.add_argument (new CCodeIdentifier (array_type.element_type.data_type.get_type_id ()));
--                                      register_call.add_argument (carray_type);
--                                      add_call.add_argument (carray_type);
--                              }
--                      } else {
--                              if (param.parameter_type.get_type_id () == null) {
--                                      Report.error (param.source_reference, "unsupported parameter type for D-Bus signals");
--                                      return;
--                              }
--
--                              register_call.add_argument (new CCodeIdentifier (param.parameter_type.get_type_id ()));
--                              add_call.add_argument (new CCodeIdentifier (param.parameter_type.get_type_id ()));
--                      }
--              }
--              register_call.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
--              add_call.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
--
--              block.add_statement (new CCodeExpressionStatement (register_call));
--              block.add_statement (new CCodeExpressionStatement (add_call));
--
--              var call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_connect_signal"));
--              call.add_argument (new CCodeIdentifier ("obj"));
--              call.add_argument (new CCodeIdentifier ("signal_name"));
--              call.add_argument (new CCodeIdentifier ("handler"));
--              call.add_argument (new CCodeIdentifier ("data"));
--              call.add_argument (new CCodeConstant ("NULL"));
--              block.add_statement (new CCodeExpressionStatement (call));
--      }
--
--      void generate_dbus_disconnect_wrapper (DynamicSignal node, CCodeBlock block) {
--              var dynamic_signal = (DynamicSignal) node;
--
--              var call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_disconnect_signal"));
--              call.add_argument (new CCodeIdentifier ("obj"));
--              call.add_argument (new CCodeIdentifier ("signal_name"));
--              call.add_argument (new CCodeIdentifier ("handler"));
--              call.add_argument (new CCodeIdentifier ("data"));
--              block.add_statement (new CCodeExpressionStatement (call));
--      }
--}
-Index: gobject/valagsignalmodule.vala
-===================================================================
---- gobject/valagsignalmodule.vala     (revision 1971)
-+++ gobject/valagsignalmodule.vala     (revision 2004)
-@@ -47,6 +47,17 @@
-                       return ("VOID");
-               } else if (dbus && t.get_type_signature ().has_prefix ("(")) {
-                       return ("BOXED");
-+              } else if (t.data_type is Enum) {
-+                      var en = (Enum) t.data_type;
-+                      if (dbus) {
-+                              if (en.is_flags) {
-+                                      return ("UINT");
-+                              } else {
-+                                      return ("INT");
-+                              }
-+                      } else {
-+                              return en.get_marshaller_type_name ();
-+                      }
-               } else {
-                       return t.data_type.get_marshaller_type_name ();
-               }
-@@ -266,6 +277,13 @@
-                               get_value_function = "g_value_get_pointer";
-                       } else if (dbus && p.parameter_type.get_type_signature ().has_prefix ("(")) {
-                               get_value_function = "g_value_get_boxed";
-+                      } else if (dbus && p.parameter_type.data_type is Enum) {
-+                              var en = (Enum) p.parameter_type.data_type;
-+                              if (en.is_flags) {
-+                                      get_value_function = "g_value_get_uint";
-+                              } else {
-+                                      get_value_function = "g_value_get_int";
-+                              }
-                       } else {
-                               get_value_function = p.parameter_type.data_type.get_get_value_function ();
-                       }
-@@ -306,6 +324,13 @@
-                               set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_take_object"));
-                       } else if (dbus && return_type.get_type_signature ().has_prefix ("(")) {
-                               set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_take_boxed"));
-+                      } else if (dbus && return_type.data_type is Enum) {
-+                              var en = (Enum) return_type.data_type;
-+                              if (en.is_flags) {
-+                                      set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_set_uint"));
-+                              } else {
-+                                      set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_set_int"));
-+                              }
-                       } else {
-                               set_fc = new CCodeFunctionCall (new CCodeIdentifier (return_type.data_type.get_set_value_function ()));
-                       }
-@@ -378,5 +403,228 @@
-               return csignew;
-       }
-+
-+      public override void visit_element_access (ElementAccess expr) {
-+              if (expr.container is MemberAccess && expr.container.symbol_reference is Signal) {
-+                      // detailed signal emission
-+                      var sig = (Signal) expr.symbol_reference;
-+                      var ma = (MemberAccess) expr.container;
-+
-+                      expr.accept_children (codegen);
-+
-+                      var detail_expr = expr.get_indices ().get (0) as StringLiteral;
-+                      string signal_detail = detail_expr.eval ();
-+                      
-+                      var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit_by_name"));
-+
-+                      // FIXME: use C cast if debugging disabled
-+                      var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT"));
-+                      ccast.add_argument ((CCodeExpression) ma.inner.ccodenode);
-+                      ccall.add_argument (ccast);
-+
-+                      ccall.add_argument (sig.get_canonical_cconstant (signal_detail));
-+                      
-+                      expr.ccodenode = ccall;
-+              } else {
-+                      base.visit_element_access (expr);
-+              }
-+      }
-+
-+      CCodeExpression? emit_signal_assignment (Assignment assignment) {
-+              var sig = (Signal) assignment.left.symbol_reference;
-+              
-+              var m = (Method) assignment.right.symbol_reference;
-+
-+              string connect_func;
-+              bool disconnect = false;
-+
-+              if (assignment.operator == AssignmentOperator.ADD) {
-+                      if (sig is DynamicSignal) {
-+                              connect_func = head.get_dynamic_signal_connect_wrapper_name ((DynamicSignal) sig);
-+                      } else {
-+                              connect_func = "g_signal_connect_object";
-+                              if (m.binding != MemberBinding.INSTANCE) {
-+                                      connect_func = "g_signal_connect";
-+                              }
-+                      }
-+              } else if (assignment.operator == AssignmentOperator.SUB) {
-+                      if (sig is DynamicSignal) {
-+                              connect_func = head.get_dynamic_signal_disconnect_wrapper_name ((DynamicSignal) sig);
-+                      } else {
-+                              connect_func = "g_signal_handlers_disconnect_matched";
-+                      }
-+                      disconnect = true;
-+              } else {
-+                      assignment.error = true;
-+                      Report.error (assignment.source_reference, "Specified compound assignment type for signals not supported.");
-+                      return null;
-+              }
-+
-+              var ccall = new CCodeFunctionCall (new CCodeIdentifier (connect_func));
-+
-+              string signal_detail = null;
-+
-+              // first argument: instance of sender
-+              MemberAccess ma;
-+              if (assignment.left is ElementAccess) {
-+                      var ea = (ElementAccess) assignment.left;
-+                      ma = (MemberAccess) ea.container;
-+                      var detail_expr = ea.get_indices ().get (0) as StringLiteral;
-+                      if (detail_expr == null) {
-+                              assignment.error = true;
-+                              Report.error (detail_expr.source_reference, "internal error: only literal string details supported");
-+                              return null;
-+                      }
-+                      signal_detail = detail_expr.eval ();
-+              } else {
-+                      ma = (MemberAccess) assignment.left;
-+              }
-+              if (ma.inner != null) {
-+                      ccall.add_argument ((CCodeExpression) get_ccodenode (ma.inner));
-+              } else {
-+                      ccall.add_argument (new CCodeIdentifier ("self"));
-+              }
-+
-+              if (sig is DynamicSignal) {
-+                      // dynamic_signal_connect or dynamic_signal_disconnect
-+
-+                      // second argument: signal name
-+                      ccall.add_argument (new CCodeConstant ("\"%s\"".printf (sig.name)));
-+              } else if (!disconnect) {
-+                      // g_signal_connect_object or g_signal_connect
-+
-+                      // second argument: signal name
-+                      ccall.add_argument (sig.get_canonical_cconstant (signal_detail));
-+              } else {
-+                      // g_signal_handlers_disconnect_matched
-+
-+                      // second argument: mask
-+                      if (signal_detail == null) {
-+                              ccall.add_argument (new CCodeConstant ("G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA"));
-+                      } else {
-+                              ccall.add_argument (new CCodeConstant ("G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA"));
-+                      }
-+
-+                      // get signal id
-+                      var ccomma = new CCodeCommaExpression ();
-+                      var temp_decl = get_temp_variable (uint_type);
-+                      temp_vars.insert (0, temp_decl);
-+                      var parse_call = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_parse_name"));
-+                      parse_call.add_argument (sig.get_canonical_cconstant (signal_detail));
-+                      var decl_type = (TypeSymbol) sig.parent_symbol;
-+                      parse_call.add_argument (new CCodeIdentifier (decl_type.get_type_id ()));
-+                      parse_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_decl.name)));
-+                      if (signal_detail == null) {
-+                              parse_call.add_argument (new CCodeConstant ("NULL"));
-+                      } else {
-+                              var detail_temp_decl = get_temp_variable (gquark_type);
-+                              temp_vars.insert (0, detail_temp_decl);
-+                              parse_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (detail_temp_decl.name)));
-+                      }
-+                      parse_call.add_argument (new CCodeConstant ("FALSE"));
-+                      ccomma.append_expression (parse_call);
-+                      ccomma.append_expression (new CCodeIdentifier (temp_decl.name));
-+
-+                      // third argument: signal_id
-+                      ccall.add_argument (ccomma);
-+
-+                      // fourth argument: detail
-+                      ccall.add_argument (new CCodeConstant ("0"));
-+                      // fifth argument: closure
-+                      ccall.add_argument (new CCodeConstant ("NULL"));
-+              }
-+              
-+              // third resp. sixth argument: handler
-+              ccall.add_argument (new CCodeCastExpression ((CCodeExpression) assignment.right.ccodenode, "GCallback"));
-+
-+              if (m.binding == MemberBinding.INSTANCE) {
-+                      // g_signal_connect_object or g_signal_handlers_disconnect_matched
-+                      // or dynamic_signal_connect or dynamic_signal_disconnect
-+
-+                      // fourth resp. seventh argument: object/user_data
-+                      if (assignment.right is MemberAccess) {
-+                              var right_ma = (MemberAccess) assignment.right;
-+                              if (right_ma.inner != null) {
-+                                      ccall.add_argument ((CCodeExpression) right_ma.inner.ccodenode);
-+                              } else {
-+                                      ccall.add_argument (new CCodeIdentifier ("self"));
-+                              }
-+                      } else if (assignment.right is LambdaExpression) {
-+                              ccall.add_argument (new CCodeIdentifier ("self"));
-+                      }
-+                      if (!disconnect && !(sig is DynamicSignal)) {
-+                              // g_signal_connect_object
-+
-+                              // fifth argument: connect_flags
-+                              ccall.add_argument (new CCodeConstant ("0"));
-+                      }
-+              } else {
-+                      // g_signal_connect or g_signal_handlers_disconnect_matched
-+                      // or dynamic_signal_connect or dynamic_signal_disconnect
-+
-+                      // fourth resp. seventh argument: user_data
-+                      ccall.add_argument (new CCodeConstant ("NULL"));
-+              }
-+              
-+              return ccall;
-+      }
-+
-+      public override void visit_assignment (Assignment assignment) {
-+              if (assignment.left.symbol_reference is Signal) {
-+                      assignment.right.accept (codegen);
-+
-+                      if (assignment.left.error || assignment.right.error) {
-+                              assignment.error = true;
-+                              return;
-+                      }
-+
-+                      assignment.ccodenode = emit_signal_assignment (assignment);
-+              } else {
-+                      base.visit_assignment (assignment);
-+              }
-+      }
-+
-+      public override void visit_member_access (MemberAccess expr) {
-+              CCodeExpression pub_inst = null;
-+      
-+              if (expr.inner != null) {
-+                      pub_inst = (CCodeExpression) expr.inner.ccodenode;
-+              }
-+
-+              if (expr.symbol_reference is Signal) {
-+                      var sig = (Signal) expr.symbol_reference;
-+                      var cl = (TypeSymbol) sig.parent_symbol;
-+                      
-+                      if (expr.inner is BaseAccess && sig.is_virtual) {
-+                              var m = sig.get_method_handler ();
-+                              var base_class = (Class) m.parent_symbol;
-+                              var vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (base_class.get_upper_case_cname (null))));
-+                              vcast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (current_class.get_lower_case_cname (null))));
-+                              
-+                              expr.ccodenode = new CCodeMemberAccess.pointer (vcast, m.name);
-+                              return;
-+                      }
-+
-+                      if (sig.has_emitter) {
-+                              var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_%s".printf (cl.get_lower_case_cname (null), sig.name)));
-+
-+                              ccall.add_argument (pub_inst);
-+                              expr.ccodenode = ccall;
-+                      } else {
-+                              var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit_by_name"));
-+
-+                              // FIXME: use C cast if debugging disabled
-+                              var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT"));
-+                              ccast.add_argument (pub_inst);
-+                              ccall.add_argument (ccast);
-+
-+                              ccall.add_argument (sig.get_canonical_cconstant ());
-+                              
-+                              expr.ccodenode = ccall;
-+                      }
-+              } else {
-+                      base.visit_member_access (expr);
-+              }
-+      }
- }
-Index: gobject/valaccodememberaccessmodule.vala
-===================================================================
---- gobject/valaccodememberaccessmodule.vala   (revision 1971)
-+++ gobject/valaccodememberaccessmodule.vala   (revision 2004)
-@@ -23,12 +23,23 @@
- using GLib;
--public class Vala.CCodeMemberAccessModule : CCodeMethodModule {
-+public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
-       public CCodeMemberAccessModule (CCodeGenerator codegen, CCodeModule? next) {
-               base (codegen, next);
-       }
--      private void process_cmember (MemberAccess expr, CCodeExpression? pub_inst, DataType? base_type) {
-+      public override void visit_member_access (MemberAccess expr) {
-+              CCodeExpression pub_inst = null;
-+              DataType base_type = null;
-+      
-+              if (expr.inner != null) {
-+                      pub_inst = (CCodeExpression) expr.inner.ccodenode;
-+
-+                      if (expr.inner.value_type != null) {
-+                              base_type = expr.inner.value_type;
-+                      }
-+              }
-+
-               if (expr.symbol_reference is Method) {
-                       var m = (Method) expr.symbol_reference;
-                       
-@@ -259,53 +270,7 @@
-                                       }
-                               }
-                       }
--              } else if (expr.symbol_reference is Signal) {
--                      var sig = (Signal) expr.symbol_reference;
--                      var cl = (TypeSymbol) sig.parent_symbol;
--                      
--                      if (expr.inner is BaseAccess && sig.is_virtual) {
--                              var m = sig.get_method_handler ();
--                              var base_class = (Class) m.parent_symbol;
--                              var vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (base_class.get_upper_case_cname (null))));
--                              vcast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (current_class.get_lower_case_cname (null))));
--                              
--                              expr.ccodenode = new CCodeMemberAccess.pointer (vcast, m.name);
--                              return;
--                      }
--
--                      if (sig.has_emitter) {
--                              var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_%s".printf (cl.get_lower_case_cname (null), sig.name)));
--
--                              ccall.add_argument (pub_inst);
--                              expr.ccodenode = ccall;
--                      } else {
--                              var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit_by_name"));
--
--                              // FIXME: use C cast if debugging disabled
--                              var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT"));
--                              ccast.add_argument (pub_inst);
--                              ccall.add_argument (ccast);
--
--                              ccall.add_argument (sig.get_canonical_cconstant ());
--                              
--                              expr.ccodenode = ccall;
--                      }
-               }
-       }
--
--      public override void visit_member_access (MemberAccess expr) {
--              CCodeExpression pub_inst = null;
--              DataType base_type = null;
--      
--              if (expr.inner != null) {
--                      pub_inst = (CCodeExpression) expr.inner.ccodenode;
--
--                      if (expr.inner.value_type != null) {
--                              base_type = expr.inner.value_type;
--                      }
--              }
--
--              process_cmember (expr, pub_inst, base_type);
--      }
- }
-Index: gobject/valadbusclientmodule.vala
-===================================================================
---- gobject/valadbusclientmodule.vala  (revision 1971)
-+++ gobject/valadbusclientmodule.vala  (revision 2004)
-@@ -29,6 +29,8 @@
-  * The link between a dynamic method and generated code.
-  */
- public class Vala.DBusClientModule : GAsyncModule {
-+      int dynamic_property_id;
-+
-       public DBusClientModule (CCodeGenerator codegen, CCodeModule? next) {
-               base (codegen, next);
-       }
-@@ -433,6 +435,10 @@
-                               block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
-                       }
-               } else {
-+                      if (found_out) {
-+                              ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
-+                      }
-+
-                       block.add_statement (new CCodeExpressionStatement (ccall));
-                       // don't access result when error occured
-@@ -460,6 +466,13 @@
-                       }
-                       carray_type.add_argument (get_dbus_g_type (array_type.element_type));
-                       return carray_type;
-+              } else if (data_type.data_type is Enum) {
-+                      var en = (Enum) data_type.data_type;
-+                      if (en.is_flags) {
-+                              return new CCodeIdentifier ("G_TYPE_UINT");
-+                      } else {
-+                              return new CCodeIdentifier ("G_TYPE_INT");
-+                      }
-               } else if (data_type.data_type == null) {
-                       critical ("Internal error during DBus type generation with: %s", data_type.to_string ());
-                       return new CCodeIdentifier ("G_TYPE_NONE");
-@@ -502,4 +515,291 @@
-                       return true;
-               }
-       }
-+
-+      public override string get_dynamic_property_getter_cname (DynamicProperty prop) {
-+              if (prop.dynamic_type.data_type != dbus_object_type) {
-+                      return base.get_dynamic_property_getter_cname (prop);
-+              }
-+
-+              string getter_cname = "_dynamic_get_%s%d".printf (prop.name, dynamic_property_id++);
-+
-+              var func = new CCodeFunction (getter_cname, prop.property_type.get_cname ());
-+              func.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.INLINE;
-+
-+              func.add_parameter (new CCodeFormalParameter ("obj", prop.dynamic_type.get_cname ()));
-+
-+              var block = new CCodeBlock ();
-+              generate_dbus_property_getter_wrapper (prop, block);
-+
-+              // append to C source file
-+              source_type_member_declaration.append (func.copy ());
-+
-+              func.block = block;
-+              source_type_member_definition.append (func);
-+
-+              return getter_cname;
-+      }
-+
-+      public override string get_dynamic_property_setter_cname (DynamicProperty prop) {
-+              if (prop.dynamic_type.data_type != dbus_object_type) {
-+                      return base.get_dynamic_property_setter_cname (prop);
-+              }
-+
-+              string setter_cname = "_dynamic_set_%s%d".printf (prop.name, dynamic_property_id++);
-+
-+              var func = new CCodeFunction (setter_cname, "void");
-+              func.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.INLINE;
-+
-+              func.add_parameter (new CCodeFormalParameter ("obj", prop.dynamic_type.get_cname ()));
-+              func.add_parameter (new CCodeFormalParameter ("value", prop.property_type.get_cname ()));
-+
-+              var block = new CCodeBlock ();
-+              generate_dbus_property_setter_wrapper (prop, block);
-+
-+              // append to C source file
-+              source_type_member_declaration.append (func.copy ());
-+
-+              func.block = block;
-+              source_type_member_definition.append (func);
-+
-+              return setter_cname;
-+      }
-+
-+      void create_dbus_property_proxy (DynamicProperty node, CCodeBlock block) {
-+              var prop_proxy_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_new_from_proxy"));
-+              prop_proxy_call.add_argument (new CCodeIdentifier ("obj"));
-+              prop_proxy_call.add_argument (new CCodeConstant ("DBUS_INTERFACE_PROPERTIES"));
-+              prop_proxy_call.add_argument (new CCodeConstant ("NULL"));
-+
-+              var prop_proxy_decl = new CCodeDeclaration ("DBusGProxy*");
-+              prop_proxy_decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("property_proxy", prop_proxy_call));
-+              block.add_statement (prop_proxy_decl);
-+      }
-+
-+      void generate_dbus_property_getter_wrapper (DynamicProperty node, CCodeBlock block) {
-+              create_dbus_property_proxy (node, block);
-+
-+              // initialize GValue
-+              var cvalinit = new CCodeInitializerList ();
-+              cvalinit.append (new CCodeConstant ("0"));
-+
-+              var cval_decl = new CCodeDeclaration ("GValue");
-+              cval_decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("gvalue", cvalinit));
-+              block.add_statement (cval_decl);
-+
-+              var val_ptr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("gvalue"));
-+
-+              // call Get method on property proxy
-+              var cdecl = new CCodeDeclaration (node.property_type.get_cname ());
-+              cdecl.add_declarator (new CCodeVariableDeclarator ("result"));
-+              block.add_statement (cdecl);
-+
-+              var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_call"));
-+              ccall.add_argument (new CCodeIdentifier ("property_proxy"));
-+              ccall.add_argument (new CCodeConstant ("\"Get\""));
-+              ccall.add_argument (new CCodeConstant ("NULL"));
-+
-+              ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING"));
-+              var get_iface = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_interface"));
-+              get_iface.add_argument (new CCodeIdentifier ("obj"));
-+              ccall.add_argument (get_iface);
-+
-+              ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING"));
-+              ccall.add_argument (new CCodeConstant ("\"%s\"".printf (Symbol.lower_case_to_camel_case (node.name))));
-+
-+              ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
-+
-+              ccall.add_argument (new CCodeIdentifier ("G_TYPE_VALUE"));
-+              ccall.add_argument (val_ptr);
-+
-+              ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
-+
-+              block.add_statement (new CCodeExpressionStatement (ccall));
-+
-+              // unref property proxy
-+              var prop_proxy_unref = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
-+              prop_proxy_unref.add_argument (new CCodeIdentifier ("property_proxy"));
-+              block.add_statement (new CCodeExpressionStatement (prop_proxy_unref));
-+
-+              // assign value to result variable
-+              var cget_call = new CCodeFunctionCall (new CCodeIdentifier (node.property_type.data_type.get_get_value_function ()));
-+              cget_call.add_argument (val_ptr);
-+              var assign = new CCodeAssignment (new CCodeIdentifier ("result"), cget_call);
-+              block.add_statement (new CCodeExpressionStatement (assign));
-+
-+              // return result
-+              block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
-+      }
-+
-+      void generate_dbus_property_setter_wrapper (DynamicProperty node, CCodeBlock block) {
-+              create_dbus_property_proxy (node, block);
-+
-+              // initialize GValue
-+              var cvalinit = new CCodeInitializerList ();
-+              cvalinit.append (new CCodeConstant ("0"));
-+
-+              var cval_decl = new CCodeDeclaration ("GValue");
-+              cval_decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("gvalue", cvalinit));
-+              block.add_statement (cval_decl);
-+
-+              var val_ptr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("gvalue"));
-+
-+              var cinit_call = new CCodeFunctionCall (new CCodeIdentifier ("g_value_init"));
-+              cinit_call.add_argument (val_ptr);
-+              cinit_call.add_argument (new CCodeIdentifier (node.property_type.data_type.get_type_id ()));
-+              block.add_statement (new CCodeExpressionStatement (cinit_call));
-+
-+              var cset_call = new CCodeFunctionCall (new CCodeIdentifier (node.property_type.data_type.get_set_value_function ()));
-+              cset_call.add_argument (val_ptr);
-+              cset_call.add_argument (new CCodeIdentifier ("value"));
-+              block.add_statement (new CCodeExpressionStatement (cset_call));
-+
-+              // call Set method on property proxy
-+              var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_call"));
-+              ccall.add_argument (new CCodeIdentifier ("property_proxy"));
-+              ccall.add_argument (new CCodeConstant ("\"Set\""));
-+              ccall.add_argument (new CCodeConstant ("NULL"));
-+
-+              ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING"));
-+              var get_iface = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_interface"));
-+              get_iface.add_argument (new CCodeIdentifier ("obj"));
-+              ccall.add_argument (get_iface);
-+
-+              ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING"));
-+              ccall.add_argument (new CCodeConstant ("\"%s\"".printf (Symbol.lower_case_to_camel_case (node.name))));
-+
-+              ccall.add_argument (new CCodeIdentifier ("G_TYPE_VALUE"));
-+              ccall.add_argument (val_ptr);
-+
-+              ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
-+
-+              ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
-+
-+              block.add_statement (new CCodeExpressionStatement (ccall));
-+
-+              // unref property proxy
-+              var prop_proxy_unref = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
-+              prop_proxy_unref.add_argument (new CCodeIdentifier ("property_proxy"));
-+              block.add_statement (new CCodeExpressionStatement (prop_proxy_unref));
-+      }
-+
-+      public override string get_dynamic_signal_connect_wrapper_name (DynamicSignal sig) {
-+              if (sig.dynamic_type.data_type != dbus_object_type) {
-+                      return base.get_dynamic_signal_connect_wrapper_name (sig);
-+              }
-+
-+              string connect_wrapper_name = "_%sconnect".printf (get_dynamic_signal_cname (sig));
-+              var func = new CCodeFunction (connect_wrapper_name, "void");
-+              func.add_parameter (new CCodeFormalParameter ("obj", "gpointer"));
-+              func.add_parameter (new CCodeFormalParameter ("signal_name", "const char *"));
-+              func.add_parameter (new CCodeFormalParameter ("handler", "GCallback"));
-+              func.add_parameter (new CCodeFormalParameter ("data", "gpointer"));
-+              var block = new CCodeBlock ();
-+              generate_dbus_connect_wrapper (sig, block);
-+
-+              // append to C source file
-+              source_type_member_declaration.append (func.copy ());
-+
-+              func.block = block;
-+              source_type_member_definition.append (func);
-+
-+              return connect_wrapper_name;
-+      }
-+
-+      public override string get_dynamic_signal_disconnect_wrapper_name (DynamicSignal sig) {
-+              if (sig.dynamic_type.data_type != dbus_object_type) {
-+                      return base.get_dynamic_signal_disconnect_wrapper_name (sig);
-+              }
-+
-+              string disconnect_wrapper_name = "_%sdisconnect".printf (get_dynamic_signal_cname (sig));
-+              var func = new CCodeFunction (disconnect_wrapper_name, "void");
-+              func.add_parameter (new CCodeFormalParameter ("obj", "gpointer"));
-+              func.add_parameter (new CCodeFormalParameter ("signal_name", "const char *"));
-+              func.add_parameter (new CCodeFormalParameter ("handler", "GCallback"));
-+              func.add_parameter (new CCodeFormalParameter ("data", "gpointer"));
-+              var block = new CCodeBlock ();
-+              generate_dbus_disconnect_wrapper (sig, block);
-+
-+              // append to C source file
-+              source_type_member_declaration.append (func.copy ());
-+
-+              func.block = block;
-+              source_type_member_definition.append (func);
-+
-+              return disconnect_wrapper_name;
-+      }
-+
-+      void generate_dbus_connect_wrapper (DynamicSignal sig, CCodeBlock block) {
-+              var m = (Method) sig.handler.symbol_reference;
-+
-+              sig.accept (codegen);
-+
-+              // FIXME should only be done once per marshaller
-+              var register_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_object_register_marshaller"));
-+              head.generate_marshaller (sig.get_parameters (), sig.return_type, true);
-+              register_call.add_argument (new CCodeIdentifier (head.get_marshaller_function (sig.get_parameters (), sig.return_type, null, true)));
-+              register_call.add_argument (new CCodeIdentifier ("G_TYPE_NONE"));
-+
-+              var add_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_add_signal"));
-+              add_call.add_argument (new CCodeIdentifier ("obj"));
-+              add_call.add_argument (new CCodeConstant ("\"%s\"".printf (Symbol.lower_case_to_camel_case (sig.name))));
-+
-+              bool first = true;
-+              foreach (FormalParameter param in m.get_parameters ()) {
-+                      if (first) {
-+                              // skip sender parameter
-+                              first = false;
-+                              continue;
-+                      }
-+
-+                      var array_type = param.parameter_type as ArrayType;
-+                      if (array_type != null) {
-+                              if (array_type.element_type.data_type == string_type.data_type) {
-+                                      register_call.add_argument (new CCodeIdentifier ("G_TYPE_STRV"));
-+                                      add_call.add_argument (new CCodeIdentifier ("G_TYPE_STRV"));
-+                              } else {
-+                                      if (array_type.element_type.data_type.get_type_id () == null) {
-+                                              Report.error (param.source_reference, "unsupported parameter type for D-Bus signals");
-+                                              return;
-+                                      }
-+
-+                                      var carray_type = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_type_get_collection"));
-+                                      carray_type.add_argument (new CCodeConstant ("\"GArray\""));
-+                                      carray_type.add_argument (new CCodeIdentifier (array_type.element_type.data_type.get_type_id ()));
-+                                      register_call.add_argument (carray_type);
-+                                      add_call.add_argument (carray_type);
-+                              }
-+                      } else {
-+                              if (param.parameter_type.get_type_id () == null) {
-+                                      Report.error (param.source_reference, "unsupported parameter type for D-Bus signals");
-+                                      return;
-+                              }
-+
-+                              register_call.add_argument (new CCodeIdentifier (param.parameter_type.get_type_id ()));
-+                              add_call.add_argument (new CCodeIdentifier (param.parameter_type.get_type_id ()));
-+                      }
-+              }
-+              register_call.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
-+              add_call.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
-+
-+              block.add_statement (new CCodeExpressionStatement (register_call));
-+              block.add_statement (new CCodeExpressionStatement (add_call));
-+
-+              var call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_connect_signal"));
-+              call.add_argument (new CCodeIdentifier ("obj"));
-+              call.add_argument (new CCodeIdentifier ("signal_name"));
-+              call.add_argument (new CCodeIdentifier ("handler"));
-+              call.add_argument (new CCodeIdentifier ("data"));
-+              call.add_argument (new CCodeConstant ("NULL"));
-+              block.add_statement (new CCodeExpressionStatement (call));
-+      }
-+
-+      void generate_dbus_disconnect_wrapper (DynamicSignal sig, CCodeBlock block) {
-+              var call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_disconnect_signal"));
-+              call.add_argument (new CCodeIdentifier ("obj"));
-+              call.add_argument (new CCodeIdentifier ("signal_name"));
-+              call.add_argument (new CCodeIdentifier ("handler"));
-+              call.add_argument (new CCodeIdentifier ("data"));
-+              block.add_statement (new CCodeExpressionStatement (call));
-+      }
- }
-Index: gobject/valagerrormodule.vala
-===================================================================
---- gobject/valagerrormodule.vala      (revision 1971)
-+++ gobject/valagerrormodule.vala      (revision 2004)
-@@ -23,7 +23,7 @@
- using GLib;
- using Gee;
--public class Vala.GErrorModule : CCodeDynamicSignalModule {
-+public class Vala.GErrorModule : CCodeDelegateModule {
-       private int current_try_id = 0;
-       private int next_try_id = 0;
-Index: gobject/valaccodeassignmentmodule.vala
-===================================================================
---- gobject/valaccodeassignmentmodule.vala     (revision 1971)
-+++ gobject/valaccodeassignmentmodule.vala     (revision 2004)
-@@ -89,145 +89,6 @@
-               }
-       }
--      CCodeExpression? emit_signal_assignment (Assignment assignment) {
--              var sig = (Signal) assignment.left.symbol_reference;
--              
--              var m = (Method) assignment.right.symbol_reference;
--
--              string connect_func;
--              bool disconnect = false;
--
--              if (assignment.operator == AssignmentOperator.ADD) {
--                      if (sig is DynamicSignal) {
--                              connect_func = head.get_dynamic_signal_connect_wrapper_name ((DynamicSignal) sig);
--                      } else {
--                              connect_func = "g_signal_connect_object";
--                              if (m.binding != MemberBinding.INSTANCE) {
--                                      connect_func = "g_signal_connect";
--                              }
--                      }
--              } else if (assignment.operator == AssignmentOperator.SUB) {
--                      if (sig is DynamicSignal) {
--                              connect_func = head.get_dynamic_signal_disconnect_wrapper_name ((DynamicSignal) sig);
--                      } else {
--                              connect_func = "g_signal_handlers_disconnect_matched";
--                      }
--                      disconnect = true;
--              } else {
--                      assignment.error = true;
--                      Report.error (assignment.source_reference, "Specified compound assignment type for signals not supported.");
--                      return null;
--              }
--
--              var ccall = new CCodeFunctionCall (new CCodeIdentifier (connect_func));
--
--              string signal_detail = null;
--
--              // first argument: instance of sender
--              MemberAccess ma;
--              if (assignment.left is ElementAccess) {
--                      var ea = (ElementAccess) assignment.left;
--                      ma = (MemberAccess) ea.container;
--                      var detail_expr = ea.get_indices ().get (0) as StringLiteral;
--                      if (detail_expr == null) {
--                              assignment.error = true;
--                              Report.error (detail_expr.source_reference, "internal error: only literal string details supported");
--                              return null;
--                      }
--                      signal_detail = detail_expr.eval ();
--              } else {
--                      ma = (MemberAccess) assignment.left;
--              }
--              if (ma.inner != null) {
--                      ccall.add_argument ((CCodeExpression) get_ccodenode (ma.inner));
--              } else {
--                      ccall.add_argument (new CCodeIdentifier ("self"));
--              }
--
--              if (sig is DynamicSignal) {
--                      // dynamic_signal_connect or dynamic_signal_disconnect
--
--                      // second argument: signal name
--                      ccall.add_argument (new CCodeConstant ("\"%s\"".printf (sig.name)));
--              } else if (!disconnect) {
--                      // g_signal_connect_object or g_signal_connect
--
--                      // second argument: signal name
--                      ccall.add_argument (sig.get_canonical_cconstant (signal_detail));
--              } else {
--                      // g_signal_handlers_disconnect_matched
--
--                      // second argument: mask
--                      if (signal_detail == null) {
--                              ccall.add_argument (new CCodeConstant ("G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA"));
--                      } else {
--                              ccall.add_argument (new CCodeConstant ("G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA"));
--                      }
--
--                      // get signal id
--                      var ccomma = new CCodeCommaExpression ();
--                      var temp_decl = get_temp_variable (uint_type);
--                      temp_vars.insert (0, temp_decl);
--                      var parse_call = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_parse_name"));
--                      parse_call.add_argument (sig.get_canonical_cconstant (signal_detail));
--                      var decl_type = (TypeSymbol) sig.parent_symbol;
--                      parse_call.add_argument (new CCodeIdentifier (decl_type.get_type_id ()));
--                      parse_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_decl.name)));
--                      if (signal_detail == null) {
--                              parse_call.add_argument (new CCodeConstant ("NULL"));
--                      } else {
--                              var detail_temp_decl = get_temp_variable (gquark_type);
--                              temp_vars.insert (0, detail_temp_decl);
--                              parse_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (detail_temp_decl.name)));
--                      }
--                      parse_call.add_argument (new CCodeConstant ("FALSE"));
--                      ccomma.append_expression (parse_call);
--                      ccomma.append_expression (new CCodeIdentifier (temp_decl.name));
--
--                      // third argument: signal_id
--                      ccall.add_argument (ccomma);
--
--                      // fourth argument: detail
--                      ccall.add_argument (new CCodeConstant ("0"));
--                      // fifth argument: closure
--                      ccall.add_argument (new CCodeConstant ("NULL"));
--              }
--              
--              // third resp. sixth argument: handler
--              ccall.add_argument (new CCodeCastExpression ((CCodeExpression) assignment.right.ccodenode, "GCallback"));
--
--              if (m.binding == MemberBinding.INSTANCE) {
--                      // g_signal_connect_object or g_signal_handlers_disconnect_matched
--                      // or dynamic_signal_connect or dynamic_signal_disconnect
--
--                      // fourth resp. seventh argument: object/user_data
--                      if (assignment.right is MemberAccess) {
--                              var right_ma = (MemberAccess) assignment.right;
--                              if (right_ma.inner != null) {
--                                      ccall.add_argument ((CCodeExpression) right_ma.inner.ccodenode);
--                              } else {
--                                      ccall.add_argument (new CCodeIdentifier ("self"));
--                              }
--                      } else if (assignment.right is LambdaExpression) {
--                              ccall.add_argument (new CCodeIdentifier ("self"));
--                      }
--                      if (!disconnect && !(sig is DynamicSignal)) {
--                              // g_signal_connect_object
--
--                              // fifth argument: connect_flags
--                              ccall.add_argument (new CCodeConstant ("0"));
--                      }
--              } else {
--                      // g_signal_connect or g_signal_handlers_disconnect_matched
--                      // or dynamic_signal_connect or dynamic_signal_disconnect
--
--                      // fourth resp. seventh argument: user_data
--                      ccall.add_argument (new CCodeConstant ("NULL"));
--              }
--              
--              return ccall;
--      }
--
-       private CCodeExpression? emit_non_array_element_access (Assignment assignment) {
-               // custom element access
-               CCodeExpression rhs = (CCodeExpression) assignment.right.ccodenode;
-@@ -373,8 +234,6 @@
-               if (assignment.left.symbol_reference is Property) {
-                       assignment.ccodenode = emit_property_assignment (assignment);
--              } else if (assignment.left.symbol_reference is Signal) {
--                      assignment.ccodenode = emit_signal_assignment (assignment);
-               } else if (assignment.left is ElementAccess
-                          && !(((ElementAccess) assignment.left).container.value_type is ArrayType)
-                          && !(((ElementAccess) assignment.left).container.value_type is PointerType)) {
-Index: gobject/valaccodecontrolflowmodule.vala
-===================================================================
---- gobject/valaccodecontrolflowmodule.vala    (revision 0)
-+++ gobject/valaccodecontrolflowmodule.vala    (revision 2004)
-@@ -0,0 +1,572 @@
-+/* valaccodecontrolflowmodule.vala
-+ *
-+ * Copyright (C) 2006-2008  Jürg Billeter, Raffaele Sandrini
-+ *
-+ * This library is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2.1 of the License, or (at your option) any later version.
-+
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * Lesser General Public License for more details.
-+
-+ * You should have received a copy of the GNU Lesser General Public
-+ * License along with this library; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
-+ *
-+ * Author:
-+ *    Jürg Billeter <j@bitron.ch>
-+ *    Raffaele Sandrini <raffaele@sandrini.ch>
-+ */
-+
-+using GLib;
-+using Gee;
-+
-+public class Vala.CCodeControlFlowModule : CCodeMethodModule {
-+      public CCodeControlFlowModule (CCodeGenerator codegen, CCodeModule? next) {
-+              base (codegen, next);
-+      }
-+
-+      public override void visit_if_statement (IfStatement stmt) {
-+              stmt.accept_children (codegen);
-+
-+              if (stmt.false_statement != null) {
-+                      stmt.ccodenode = new CCodeIfStatement ((CCodeExpression) stmt.condition.ccodenode, (CCodeStatement) stmt.true_statement.ccodenode, (CCodeStatement) stmt.false_statement.ccodenode);
-+              } else {
-+                      stmt.ccodenode = new CCodeIfStatement ((CCodeExpression) stmt.condition.ccodenode, (CCodeStatement) stmt.true_statement.ccodenode);
-+              }
-+              
-+              create_temp_decl (stmt, stmt.condition.temp_vars);
-+      }
-+
-+      void visit_string_switch_statement (SwitchStatement stmt) {
-+              // we need a temporary variable to save the property value
-+              var temp_var = get_temp_variable (stmt.expression.value_type, true, stmt);
-+              stmt.expression.temp_vars.insert (0, temp_var);
-+
-+              var ctemp = new CCodeIdentifier (temp_var.name);
-+              var cinit = new CCodeAssignment (ctemp, (CCodeExpression) stmt.expression.ccodenode);
-+              var czero = new CCodeConstant ("0");
-+
-+              var cswitchblock = new CCodeFragment ();
-+              stmt.ccodenode = cswitchblock;
-+
-+              var cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeConstant ("NULL"), ctemp);
-+              var cquark = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_string"));
-+              cquark.add_argument (ctemp);
-+
-+              var ccond = new CCodeConditionalExpression (cisnull, new CCodeConstant ("0"), cquark);
-+
-+              temp_var = get_temp_variable (gquark_type);
-+              stmt.expression.temp_vars.insert (0, temp_var);
-+
-+              int label_count = 0;
-+
-+              foreach (SwitchSection section in stmt.get_sections ()) {
-+                      if (section.has_default_label ()) {
-+                              continue;
-+                      }
-+
-+                      foreach (SwitchLabel label in section.get_labels ()) {
-+                              var cexpr = (CCodeExpression) label.expression.ccodenode;
-+
-+                              if (is_constant_ccode_expression (cexpr)) {
-+                                      var cname = "%s_label%d".printf (temp_var.name, label_count++);
-+                                      var cdecl = new CCodeDeclaration (gquark_type.get_cname ());
-+
-+                                      cdecl.modifiers = CCodeModifiers.STATIC;
-+                                      cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (cname, czero));
-+
-+                                      cswitchblock.append (cdecl);
-+                              }
-+                      }
-+              }
-+
-+              cswitchblock.append (new CCodeExpressionStatement (cinit));
-+
-+              ctemp = new CCodeIdentifier (temp_var.name);
-+              cinit = new CCodeAssignment (ctemp, ccond);
-+
-+              cswitchblock.append (new CCodeExpressionStatement (cinit));
-+              create_temp_decl (stmt, stmt.expression.temp_vars);
-+
-+              Gee.List<Statement> default_statements = null;
-+              label_count = 0;
-+
-+              // generate nested if statements                
-+              CCodeStatement ctopstmt = null;
-+              CCodeIfStatement coldif = null;
-+
-+              foreach (SwitchSection section in stmt.get_sections ()) {
-+                      if (section.has_default_label ()) {
-+                              default_statements = section.get_statements ();
-+                              continue;
-+                      }
-+
-+                      CCodeBinaryExpression cor = null;
-+                      foreach (SwitchLabel label in section.get_labels ()) {
-+                              var cexpr = (CCodeExpression) label.expression.ccodenode;
-+
-+                              if (is_constant_ccode_expression (cexpr)) {
-+                                      var cname = new CCodeIdentifier ("%s_label%d".printf (temp_var.name, label_count++));
-+                                      var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, czero, cname);
-+                                      var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_static_string"));
-+                                      var cinit = new CCodeParenthesizedExpression (new CCodeAssignment (cname, ccall));
-+
-+                                      ccall.add_argument (cexpr);
-+
-+                                      cexpr = new CCodeConditionalExpression (ccond, cname, cinit);
-+                              } else {
-+                                      var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_string"));
-+                                      ccall.add_argument (cexpr);
-+                                      cexpr = ccall;
-+                              }
-+
-+                              var ccmp = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ctemp, cexpr);
-+
-+                              if (cor == null) {
-+                                      cor = ccmp;
-+                              } else {
-+                                      cor = new CCodeBinaryExpression (CCodeBinaryOperator.OR, cor, ccmp);
-+                              }
-+                      }
-+
-+                      var cblock = new CCodeBlock ();
-+                      foreach (CodeNode body_stmt in section.get_statements ()) {
-+                              if (body_stmt.ccodenode is CCodeFragment) {
-+                                      foreach (CCodeNode cstmt in ((CCodeFragment) body_stmt.ccodenode).get_children ()) {
-+                                              cblock.add_statement (cstmt);
-+                                      }
-+                              } else {
-+                                      cblock.add_statement (body_stmt.ccodenode);
-+                              }
-+                      }
-+
-+                      var cdo = new CCodeDoStatement (cblock, new CCodeConstant ("0"));
-+                      var cif = new CCodeIfStatement (cor, cdo);
-+
-+                      if (coldif != null) {
-+                              coldif.false_statement = cif;
-+                      } else {
-+                              ctopstmt = cif;
-+                      }
-+
-+                      coldif = cif;
-+              }
-+      
-+              if (default_statements != null) {
-+                      var cblock = new CCodeBlock ();
-+                      foreach (CodeNode body_stmt in default_statements) {
-+                              cblock.add_statement (body_stmt.ccodenode);
-+                      }
-+              
-+                      var cdo = new CCodeDoStatement (cblock, new CCodeConstant ("0"));
-+
-+                      if (coldif == null) {
-+                              // there is only one section and that section
-+                              // contains a default label
-+                              ctopstmt = cdo;
-+                      } else {
-+                              coldif.false_statement = cdo;
-+                      }
-+              }
-+      
-+              cswitchblock.append (ctopstmt);
-+      }
-+
-+      public override void visit_switch_statement (SwitchStatement stmt) {
-+              if (stmt.expression.value_type.compatible (string_type)) {
-+                      visit_string_switch_statement (stmt);
-+                      return;
-+              }
-+
-+              var cswitch = new CCodeSwitchStatement ((CCodeExpression) stmt.expression.ccodenode);
-+              stmt.ccodenode = cswitch;
-+
-+              foreach (SwitchSection section in stmt.get_sections ()) {
-+                      if (section.has_default_label ()) {
-+                              cswitch.add_statement (new CCodeLabel ("default"));
-+                              var cdefaultblock = new CCodeBlock ();
-+                              cswitch.add_statement (cdefaultblock);
-+                              foreach (CodeNode default_stmt in section.get_statements ()) {
-+                                      cdefaultblock.add_statement (default_stmt.ccodenode);
-+                              }
-+                              continue;
-+                      }
-+
-+                      foreach (SwitchLabel label in section.get_labels ()) {
-+                              cswitch.add_statement (new CCodeCaseStatement ((CCodeExpression) label.expression.ccodenode));
-+                      }
-+
-+                      var cblock = new CCodeBlock ();
-+                      cswitch.add_statement (cblock);
-+                      foreach (CodeNode body_stmt in section.get_statements ()) {
-+                              cblock.add_statement (body_stmt.ccodenode);
-+                      }
-+              }
-+      }
-+
-+      public override void visit_switch_section (SwitchSection section) {
-+              visit_block (section);
-+      }
-+
-+      public override void visit_while_statement (WhileStatement stmt) {
-+              stmt.accept_children (codegen);
-+
-+              stmt.ccodenode = new CCodeWhileStatement ((CCodeExpression) stmt.condition.ccodenode, (CCodeStatement) stmt.body.ccodenode);
-+              
-+              create_temp_decl (stmt, stmt.condition.temp_vars);
-+      }
-+
-+      public override void visit_do_statement (DoStatement stmt) {
-+              stmt.accept_children (codegen);
-+
-+              stmt.ccodenode = new CCodeDoStatement ((CCodeStatement) stmt.body.ccodenode, (CCodeExpression) stmt.condition.ccodenode);
-+              
-+              create_temp_decl (stmt, stmt.condition.temp_vars);
-+      }
-+
-+      public override void visit_for_statement (ForStatement stmt) {
-+              stmt.accept_children (codegen);
-+
-+              CCodeExpression ccondition = null;
-+              if (stmt.condition != null) {
-+                      ccondition = (CCodeExpression) stmt.condition.ccodenode;
-+              }
-+
-+              var cfor = new CCodeForStatement (ccondition, (CCodeStatement) stmt.body.ccodenode);
-+              stmt.ccodenode = cfor;
-+              
-+              foreach (Expression init_expr in stmt.get_initializer ()) {
-+                      cfor.add_initializer ((CCodeExpression) init_expr.ccodenode);
-+                      create_temp_decl (stmt, init_expr.temp_vars);
-+              }
-+              
-+              foreach (Expression it_expr in stmt.get_iterator ()) {
-+                      cfor.add_iterator ((CCodeExpression) it_expr.ccodenode);
-+                      create_temp_decl (stmt, it_expr.temp_vars);
-+              }
-+
-+              if (stmt.condition != null) {
-+                      create_temp_decl (stmt, stmt.condition.temp_vars);
-+              }
-+      }
-+
-+      public override void visit_foreach_statement (ForeachStatement stmt) {
-+              stmt.element_variable.active = true;
-+              stmt.collection_variable.active = true;
-+              if (stmt.iterator_variable != null) {
-+                      stmt.iterator_variable.active = true;
-+              }
-+
-+              visit_block (stmt);
-+
-+              var cblock = new CCodeBlock ();
-+              // sets #line
-+              stmt.ccodenode = cblock;
-+
-+              var cfrag = new CCodeFragment ();
-+              append_temp_decl (cfrag, stmt.collection.temp_vars);
-+              cblock.add_statement (cfrag);
-+              
-+              var collection_backup = stmt.collection_variable;
-+              var collection_type = collection_backup.variable_type.copy ();
-+              var ccoldecl = new CCodeDeclaration (collection_type.get_cname ());
-+              var ccolvardecl = new CCodeVariableDeclarator.with_initializer (collection_backup.name, (CCodeExpression) stmt.collection.ccodenode);
-+              ccolvardecl.line = cblock.line;
-+              ccoldecl.add_declarator (ccolvardecl);
-+              cblock.add_statement (ccoldecl);
-+              
-+              if (stmt.tree_can_fail && stmt.collection.tree_can_fail) {
-+                      // exception handling
-+                      var cfrag = new CCodeFragment ();
-+                      head.add_simple_check (stmt.collection, cfrag);
-+                      cblock.add_statement (cfrag);
-+              }
-+
-+              if (stmt.collection.value_type is ArrayType) {
-+                      var array_type = (ArrayType) stmt.collection.value_type;
-+                      
-+                      var array_len = head.get_array_length_cexpression (stmt.collection);
-+
-+                      // store array length for use by _vala_array_free
-+                      var clendecl = new CCodeDeclaration ("int");
-+                      clendecl.add_declarator (new CCodeVariableDeclarator.with_initializer (head.get_array_length_cname (collection_backup.name, 1), array_len));
-+                      cblock.add_statement (clendecl);
-+
-+                      if (array_len is CCodeConstant) {
-+                              // the array has no length parameter i.e. it is NULL-terminated array
-+
-+                              var it_name = "%s_it".printf (stmt.variable_name);
-+                      
-+                              var citdecl = new CCodeDeclaration (collection_type.get_cname ());
-+                              citdecl.add_declarator (new CCodeVariableDeclarator (it_name));
-+                              cblock.add_statement (citdecl);
-+                              
-+                              var cbody = new CCodeBlock ();
-+
-+                              CCodeExpression element_expr = new CCodeIdentifier ("*%s".printf (it_name));
-+
-+                              var element_type = array_type.element_type.copy ();
-+                              element_type.value_owned = false;
-+                              element_expr = transform_expression (element_expr, element_type, stmt.type_reference);
-+
-+                              var cfrag = new CCodeFragment ();
-+                              append_temp_decl (cfrag, temp_vars);
-+                              cbody.add_statement (cfrag);
-+                              temp_vars.clear ();
-+
-+                              var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
-+                              cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr));
-+                              cbody.add_statement (cdecl);
-+
-+                              // add array length variable for stacked arrays
-+                              if (stmt.type_reference is ArrayType) {
-+                                      var inner_array_type = (ArrayType) stmt.type_reference;
-+                                      for (int dim = 1; dim <= inner_array_type.rank; dim++) {
-+                                              cdecl = new CCodeDeclaration ("int");
-+                                              cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (head.get_array_length_cname (stmt.variable_name, dim), new CCodeConstant ("-1")));
-+                                              cbody.add_statement (cdecl);
-+                                      }
-+                              }
-+
-+                              cbody.add_statement (stmt.body.ccodenode);
-+                              
-+                              var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("*%s".printf (it_name)), new CCodeConstant ("NULL"));
-+                              
-+                              var cfor = new CCodeForStatement (ccond, cbody);
-+
-+                              cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeIdentifier (collection_backup.name)));
-+              
-+                              cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier (it_name), new CCodeConstant ("1"))));
-+                              cblock.add_statement (cfor);
-+                      } else {
-+                              // the array has a length parameter
-+
-+                              var it_name = (stmt.variable_name + "_it");
-+                      
-+                              var citdecl = new CCodeDeclaration ("int");
-+                              citdecl.add_declarator (new CCodeVariableDeclarator (it_name));
-+                              cblock.add_statement (citdecl);
-+                              
-+                              var cbody = new CCodeBlock ();
-+
-+                              CCodeExpression element_expr = new CCodeElementAccess (new CCodeIdentifier (collection_backup.name), new CCodeIdentifier (it_name));
-+
-+                              var element_type = array_type.element_type.copy ();
-+                              element_type.value_owned = false;
-+                              element_expr = transform_expression (element_expr, element_type, stmt.type_reference);
-+
-+                              var cfrag = new CCodeFragment ();
-+                              append_temp_decl (cfrag, temp_vars);
-+                              cbody.add_statement (cfrag);
-+                              temp_vars.clear ();
-+
-+                              var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
-+                              cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr));
-+                              cbody.add_statement (cdecl);
-+
-+                              // add array length variable for stacked arrays
-+                              if (stmt.type_reference is ArrayType) {
-+                                      var inner_array_type = (ArrayType) stmt.type_reference;
-+                                      for (int dim = 1; dim <= inner_array_type.rank; dim++) {
-+                                              cdecl = new CCodeDeclaration ("int");
-+                                              cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (head.get_array_length_cname (stmt.variable_name, dim), new CCodeConstant ("-1")));
-+                                              cbody.add_statement (cdecl);
-+                                      }
-+                              }
-+
-+                              cbody.add_statement (stmt.body.ccodenode);
-+                              
-+                              var ccond_ind1 = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, array_len, new CCodeConstant ("-1"));
-+                              var ccond_ind2 = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier (it_name), array_len);
-+                              var ccond_ind = new CCodeBinaryExpression (CCodeBinaryOperator.AND, ccond_ind1, ccond_ind2);
-+                              
-+                              /* only check for null if the containers elements are of reference-type */
-+                              CCodeBinaryExpression ccond;
-+                              if (array_type.element_type.is_reference_type_or_type_parameter ()) {
-+                                      var ccond_term1 = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, array_len, new CCodeConstant ("-1"));
-+                                      var ccond_term2 = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeElementAccess (new CCodeIdentifier (collection_backup.name), new CCodeIdentifier (it_name)), new CCodeConstant ("NULL"));
-+                                      var ccond_term = new CCodeBinaryExpression (CCodeBinaryOperator.AND, ccond_term1, ccond_term2);
-+
-+                                      ccond = new CCodeBinaryExpression (CCodeBinaryOperator.OR, new CCodeParenthesizedExpression (ccond_ind), new CCodeParenthesizedExpression (ccond_term));
-+                              } else {
-+                                      /* assert when trying to iterate over value-type arrays of unknown length */
-+                                      var cassert = new CCodeFunctionCall (new CCodeIdentifier ("g_assert"));
-+                                      cassert.add_argument (ccond_ind1);
-+                                      cblock.add_statement (new CCodeExpressionStatement (cassert));
-+
-+                                      ccond = ccond_ind2;
-+                              }
-+                              
-+                              var cfor = new CCodeForStatement (ccond, cbody);
-+                              cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeConstant ("0")));
-+                              cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier (it_name), new CCodeConstant ("1"))));
-+                              cblock.add_statement (cfor);
-+                      }
-+              } else if (stmt.collection.value_type.compatible (new ObjectType (glist_type)) || stmt.collection.value_type.compatible (new ObjectType (gslist_type))) {
-+                      // iterating over a GList or GSList
-+
-+                      var it_name = "%s_it".printf (stmt.variable_name);
-+              
-+                      var citdecl = new CCodeDeclaration (collection_type.get_cname ());
-+                      var citvardecl = new CCodeVariableDeclarator (it_name);
-+                      citvardecl.line = cblock.line;
-+                      citdecl.add_declarator (citvardecl);
-+                      cblock.add_statement (citdecl);
-+                      
-+                      var cbody = new CCodeBlock ();
-+
-+                      CCodeExpression element_expr = new CCodeMemberAccess.pointer (new CCodeIdentifier (it_name), "data");
-+
-+                      if (collection_type.get_type_arguments ().size != 1) {
-+                              Report.error (stmt.source_reference, "internal error: missing generic type argument");
-+                              stmt.error = true;
-+                              return;
-+                      }
-+
-+                      var element_data_type = collection_type.get_type_arguments ().get (0).copy ();
-+                      element_data_type.value_owned = false;
-+                      element_data_type.is_type_argument = true;
-+                      element_expr = transform_expression (element_expr, element_data_type, stmt.type_reference);
-+
-+                      var cfrag = new CCodeFragment ();
-+                      append_temp_decl (cfrag, temp_vars);
-+                      cbody.add_statement (cfrag);
-+                      temp_vars.clear ();
-+
-+                      var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
-+                      var cvardecl = new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr);
-+                      cvardecl.line = cblock.line;
-+                      cdecl.add_declarator (cvardecl);
-+                      cbody.add_statement (cdecl);
-+                      
-+                      cbody.add_statement (stmt.body.ccodenode);
-+                      
-+                      var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier (it_name), new CCodeConstant ("NULL"));
-+                      
-+                      var cfor = new CCodeForStatement (ccond, cbody);
-+                      
-+                      cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeIdentifier (collection_backup.name)));
-+
-+                      cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeMemberAccess.pointer (new CCodeIdentifier (it_name), "next")));
-+                      cblock.add_statement (cfor);
-+              } else if (list_type != null && stmt.collection.value_type.compatible (new ObjectType (list_type))) {
-+                      // iterating over a Gee.List, use integer to avoid the cost of an iterator object
-+
-+                      var it_name = "%s_it".printf (stmt.variable_name);
-+
-+                      var citdecl = new CCodeDeclaration ("int");
-+                      citdecl.add_declarator (new CCodeVariableDeclarator (it_name));
-+                      cblock.add_statement (citdecl);
-+                      
-+                      var cbody = new CCodeBlock ();
-+
-+                      var get_method = (Method) list_type.scope.lookup ("get");
-+                      var get_ccall = new CCodeFunctionCall (new CCodeIdentifier (get_method.get_cname ()));
-+                      get_ccall.add_argument (new InstanceCast (new CCodeIdentifier (collection_backup.name), list_type));
-+                      get_ccall.add_argument (new CCodeIdentifier (it_name));
-+                      CCodeExpression element_expr = get_ccall;
-+
-+                      var element_type = SemanticAnalyzer.get_actual_type (stmt.collection.value_type, get_method, get_method.return_type, stmt);
-+
-+                      element_expr = transform_expression (element_expr, element_type, stmt.type_reference);
-+
-+                      var cfrag = new CCodeFragment ();
-+                      append_temp_decl (cfrag, temp_vars);
-+                      cbody.add_statement (cfrag);
-+                      temp_vars.clear ();
-+
-+                      var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
-+                      var cvardecl = new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr);
-+                      cvardecl.line = cblock.line;
-+                      cdecl.add_declarator (cvardecl);
-+                      cbody.add_statement (cdecl);
-+
-+                      cbody.add_statement (stmt.body.ccodenode);
-+
-+                      var list_len = new CCodeFunctionCall (new CCodeIdentifier ("gee_collection_get_size"));
-+                      list_len.add_argument (new InstanceCast (new CCodeIdentifier (collection_backup.name), this.collection_type));
-+
-+                      var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier (it_name), list_len);
-+
-+                      var cfor = new CCodeForStatement (ccond, cbody);
-+                      cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeConstant ("0")));
-+                      cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier (it_name), new CCodeConstant ("1"))));
-+                      cfor.line = cblock.line;
-+                      cblock.add_statement (cfor);
-+              } else if (iterable_type != null && stmt.collection.value_type.compatible (new ObjectType (iterable_type))) {
-+                      // iterating over a Gee.Iterable, use iterator
-+
-+                      var it_name = "%s_it".printf (stmt.variable_name);
-+
-+                      var citdecl = new CCodeDeclaration (iterator_type.get_cname () + "*");
-+                      var it_method = (Method) iterable_type.scope.lookup ("iterator");
-+                      var it_ccall = new CCodeFunctionCall (new CCodeIdentifier (it_method.get_cname ()));
-+                      it_ccall.add_argument (new InstanceCast (new CCodeIdentifier (collection_backup.name), iterable_type));
-+                      var citvardecl = new CCodeVariableDeclarator.with_initializer (it_name, it_ccall);
-+                      citvardecl.line = cblock.line;
-+                      citdecl.add_declarator (citvardecl);
-+                      cblock.add_statement (citdecl);
-+                      
-+                      var cbody = new CCodeBlock ();
-+
-+                      var get_method = (Method) iterator_type.scope.lookup ("get");
-+                      var get_ccall = new CCodeFunctionCall (new CCodeIdentifier (get_method.get_cname ()));
-+                      get_ccall.add_argument (new CCodeIdentifier (it_name));
-+                      CCodeExpression element_expr = get_ccall;
-+
-+                      Iterator<DataType> type_arg_it = it_method.return_type.get_type_arguments ().iterator ();
-+                      type_arg_it.next ();
-+                      var it_type = SemanticAnalyzer.get_actual_type (stmt.collection.value_type, it_method, type_arg_it.get (), stmt);
-+
-+                      element_expr = transform_expression (element_expr, it_type, stmt.type_reference);
-+
-+                      var cfrag = new CCodeFragment ();
-+                      append_temp_decl (cfrag, temp_vars);
-+                      cbody.add_statement (cfrag);
-+                      temp_vars.clear ();
-+
-+                      var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
-+                      var cvardecl = new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr);
-+                      cvardecl.line = cblock.line;
-+                      cdecl.add_declarator (cvardecl);
-+                      cbody.add_statement (cdecl);
-+                      
-+                      cbody.add_statement (stmt.body.ccodenode);
-+
-+                      var next_method = (Method) iterator_type.scope.lookup ("next");
-+                      var next_ccall = new CCodeFunctionCall (new CCodeIdentifier (next_method.get_cname ()));
-+                      next_ccall.add_argument (new CCodeIdentifier (it_name));
-+
-+                      var cwhile = new CCodeWhileStatement (next_ccall, cbody);
-+                      cwhile.line = cblock.line;
-+                      cblock.add_statement (cwhile);
-+              }
-+
-+              foreach (LocalVariable local in stmt.get_local_variables ()) {
-+                      if (requires_destroy (local.variable_type)) {
-+                              var ma = new MemberAccess.simple (local.name);
-+                              ma.symbol_reference = local;
-+                              var cunref = new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier (get_variable_cname (local.name)), local.variable_type, ma));
-+                              cunref.line = cblock.line;
-+                              cblock.add_statement (cunref);
-+                      }
-+              }
-+      }
-+
-+      public override void visit_break_statement (BreakStatement stmt) {
-+              stmt.ccodenode = new CCodeBreakStatement ();
-+
-+              create_local_free (stmt, true);
-+      }
-+
-+      public override void visit_continue_statement (ContinueStatement stmt) {
-+              stmt.ccodenode = new CCodeContinueStatement ();
-+
-+              create_local_free (stmt, true);
-+      }
-+}
-+
-Index: gobject/valaccodebasemodule.vala
-===================================================================
---- gobject/valaccodebasemodule.vala   (revision 1971)
-+++ gobject/valaccodebasemodule.vala   (revision 2004)
-@@ -78,7 +78,6 @@
-       public Gee.Set<string> c_keywords;
-       
-       public int next_temp_var_id = 0;
--      private int next_array_dup_id = 0;
-       public bool in_creation_method = false;
-       public bool in_constructor = false;
-       public bool in_static_or_class_ctor = false;
-@@ -213,36 +212,6 @@
-               }
-       }
--      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");
--              
--              var ccomma = new CCodeCommaExpression ();
--              // set name in array for current parameter
--              var cnamemember = new CCodeMemberAccess.pointer (cpointer, "name");
--              var cnameassign = new CCodeAssignment (cnamemember, canonical_cconstant);
--              ccomma.append_expression (cnameassign);
--              
--              var gvaluearg = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeMemberAccess.pointer (cpointer, "value"));
--              
--              // initialize GValue in array for current parameter
--              var cvalueinit = new CCodeFunctionCall (new CCodeIdentifier ("g_value_init"));
--              cvalueinit.add_argument (gvaluearg);
--              cvalueinit.add_argument (new CCodeIdentifier (property_type.get_type_id ()));
--              ccomma.append_expression (cvalueinit);
--              
--              // set GValue for current parameter
--              var cvalueset = new CCodeFunctionCall (get_value_setter_function (property_type));
--              cvalueset.add_argument (gvaluearg);
--              cvalueset.add_argument (value);
--              ccomma.append_expression (cvalueset);
--              
--              // move pointer to next parameter in array
--              ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, cpointer));
--
--              return ccomma;
--      }
--
-       private CCodeIncludeDirective get_internal_include (string filename) {
-               return new CCodeIncludeDirective (filename, context.library == null);
-       }
-@@ -939,7 +908,7 @@
-               }
-       }
--      private bool is_constant_ccode_expression (CCodeExpression cexpr) {
-+      public bool is_constant_ccode_expression (CCodeExpression cexpr) {
-               if (cexpr is CCodeConstant) {
-                       return true;
-               } else if (cexpr is CCodeBinaryExpression) {
-@@ -1208,133 +1177,6 @@
-               current_return_type = null;
-       }
--      public override void visit_constructor (Constructor c) {
--              current_method_inner_error = false;
--              in_constructor = true;
--
--              if (c.binding == MemberBinding.CLASS || c.binding == MemberBinding.STATIC) {
--                      in_static_or_class_ctor = true;
--              }
--              c.accept_children (codegen);
--              in_static_or_class_ctor = false;
--
--              in_constructor = false;
--
--              var cl = (Class) c.parent_symbol;
--
--              if (c.binding == MemberBinding.INSTANCE) {
--                      function = new CCodeFunction ("%s_constructor".printf (cl.get_lower_case_cname (null)), "GObject *");
--                      function.modifiers = CCodeModifiers.STATIC;
--              
--                      function.add_parameter (new CCodeFormalParameter ("type", "GType"));
--                      function.add_parameter (new CCodeFormalParameter ("n_construct_properties", "guint"));
--                      function.add_parameter (new CCodeFormalParameter ("construct_properties", "GObjectConstructParam *"));
--              
--                      source_type_member_declaration.append (function.copy ());
--
--
--                      var cblock = new CCodeBlock ();
--                      var cdecl = new CCodeDeclaration ("GObject *");
--                      cdecl.add_declarator (new CCodeVariableDeclarator ("obj"));
--                      cblock.add_statement (cdecl);
--
--                      cdecl = new CCodeDeclaration ("%sClass *".printf (cl.get_cname ()));
--                      cdecl.add_declarator (new CCodeVariableDeclarator ("klass"));
--                      cblock.add_statement (cdecl);
--
--                      cdecl = new CCodeDeclaration ("GObjectClass *");
--                      cdecl.add_declarator (new CCodeVariableDeclarator ("parent_class"));
--                      cblock.add_statement (cdecl);
--
--
--                      var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek"));
--                      ccall.add_argument (new CCodeIdentifier (cl.get_type_id ()));
--                      var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (cl.get_upper_case_cname (null))));
--                      ccast.add_argument (ccall);
--                      cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("klass"), ccast)));
--
--                      ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek_parent"));
--                      ccall.add_argument (new CCodeIdentifier ("klass"));
--                      ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
--                      ccast.add_argument (ccall);
--                      cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("parent_class"), ccast)));
--
--              
--                      ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (new CCodeIdentifier ("parent_class"), "constructor"));
--                      ccall.add_argument (new CCodeIdentifier ("type"));
--                      ccall.add_argument (new CCodeIdentifier ("n_construct_properties"));
--                      ccall.add_argument (new CCodeIdentifier ("construct_properties"));
--                      cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("obj"), ccall)));
--
--
--                      ccall = new InstanceCast (new CCodeIdentifier ("obj"), cl);
--
--                      cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
--                      cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", ccall));
--              
--                      cblock.add_statement (cdecl);
--
--                      if (current_method_inner_error) {
--                              /* always separate error parameter and inner_error local variable
--                               * as error may be set to NULL but we're always interested in inner errors
--                               */
--                              var cdecl = new CCodeDeclaration ("GError *");
--                              cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("inner_error", new CCodeConstant ("NULL")));
--                              cblock.add_statement (cdecl);
--                      }
--
--
--                      cblock.add_statement (c.body.ccodenode);
--              
--                      cblock.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("obj")));
--              
--                      function.block = cblock;
--
--                      if (c.source_reference.comment != null) {
--                              source_type_member_definition.append (new CCodeComment (c.source_reference.comment));
--                      }
--                      source_type_member_definition.append (function);
--              } else if (c.binding == MemberBinding.CLASS) {
--                      // class constructor
--
--                      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;
--
--                      source_type_member_declaration.append (base_init.copy ());
--
--                      var block = (CCodeBlock) c.body.ccodenode;
--                      if (current_method_inner_error) {
--                              /* always separate error parameter and inner_error local variable
--                               * as error may be set to NULL but we're always interested in inner errors
--                               */
--                              var cdecl = new CCodeDeclaration ("GError *");
--                              cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("inner_error", new CCodeConstant ("NULL")));
--                              block.prepend_statement (cdecl);
--                      }
--
--                      base_init.block = block;
--              
--                      source_type_member_definition.append (base_init);
--              } else if (c.binding == MemberBinding.STATIC) {
--                      // static class constructor
--                      // add to class_init
--
--                      if (current_method_inner_error) {
--                              /* always separate error parameter and inner_error local variable
--                               * as error may be set to NULL but we're always interested in inner errors
--                               */
--                              var cdecl = new CCodeDeclaration ("GError *");
--                              cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("inner_error", new CCodeConstant ("NULL")));
--                              class_init_fragment.append (cdecl);
--                      }
--
--                      class_init_fragment.append (c.body.ccodenode);
--              } else {
--                      Report.error (c.source_reference, "internal error: constructors must have instance, class, or static binding");
--              }
--      }
--
-       public override void visit_destructor (Destructor d) {
-               current_method_inner_error = false;
-@@ -1600,12 +1442,12 @@
-               }
-       }
--      public CCodeExpression? get_dup_func_expression (DataType type, SourceReference? source_reference) {
--              var cl = type.data_type as Class;
-+      public virtual CCodeExpression? get_dup_func_expression (DataType type, SourceReference? source_reference) {
-               if (type is ErrorType) {
-                       return new CCodeIdentifier ("g_error_copy");
-               } else if (type.data_type != null) {
-                       string dup_function;
-+                      var cl = type.data_type as Class;
-                       if (type.data_type.is_reference_counting ()) {
-                               dup_function = type.data_type.get_ref_function ();
-                               if (type.data_type is Interface && dup_function == null) {
-@@ -1631,8 +1473,6 @@
-               } else if (type.type_parameter != null && current_type_symbol is Class) {
-                       string func_name = "%s_dup_func".printf (type.type_parameter.name.down ());
-                       return new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), func_name);
--              } else if (type is ArrayType) {
--                      return new CCodeIdentifier (generate_array_dup_wrapper ((ArrayType) type));
-               } else if (type is PointerType) {
-                       var pointer_type = (PointerType) type;
-                       return get_dup_func_expression (pointer_type.base_type, source_reference);
-@@ -1641,78 +1481,6 @@
-               }
-       }
--      string generate_array_dup_wrapper (ArrayType array_type) {
--              string dup_func = "_vala_array_dup%d".printf (++next_array_dup_id);
--
--              if (!add_wrapper (dup_func)) {
--                      // wrapper already defined
--                      return dup_func;
--              }
--
--              // declaration
--
--              var function = new CCodeFunction (dup_func, array_type.get_cname ());
--              function.modifiers = CCodeModifiers.STATIC;
--
--              function.add_parameter (new CCodeFormalParameter ("self", array_type.get_cname ()));
--              // total length over all dimensions
--              function.add_parameter (new CCodeFormalParameter ("length", "int"));
--
--              // definition
--
--              var block = new CCodeBlock ();
--
--              if (requires_copy (array_type.element_type)) {
--                      var old_temp_vars = temp_vars;
--
--                      var cdecl = new CCodeDeclaration (array_type.get_cname ());
--                      var cvardecl = new CCodeVariableDeclarator ("result");
--                      cdecl.add_declarator (cvardecl);
--                      var gnew = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
--                      gnew.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
--                      gnew.add_argument (new CCodeIdentifier ("length"));
--                      cvardecl.initializer = gnew;
--                      block.add_statement (cdecl);
--
--                      var idx_decl = new CCodeDeclaration ("int");
--                      idx_decl.add_declarator (new CCodeVariableDeclarator ("i"));
--                      block.add_statement (idx_decl);
--
--                      var loop_body = new CCodeBlock ();
--                      loop_body.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeElementAccess (new CCodeIdentifier ("result"), new CCodeIdentifier ("i")), get_ref_cexpression (array_type.element_type, new CCodeElementAccess (new CCodeIdentifier ("self"), new CCodeIdentifier ("i")), null, array_type))));
--
--                      var cfor = new CCodeForStatement (new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), new CCodeIdentifier ("length")), loop_body);
--                      cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0")));
--                      cfor.add_iterator (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("i")));
--                      block.add_statement (cfor);
--
--                      block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
--
--                      var cfrag = new CCodeFragment ();
--                      append_temp_decl (cfrag, temp_vars);
--                      block.add_statement (cfrag);
--                      temp_vars = old_temp_vars;
--              } else {
--                      var dup_call = new CCodeFunctionCall (new CCodeIdentifier ("g_memdup"));
--                      dup_call.add_argument (new CCodeIdentifier ("self"));
--
--                      var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
--                      sizeof_call.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
--                      dup_call.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeIdentifier ("length"), sizeof_call));
--
--                      block.add_statement (new CCodeReturnStatement (dup_call));
--              }
--
--              // append to file
--
--              source_type_member_declaration.append (function.copy ());
--
--              function.block = block;
--              source_type_member_definition.append (function);
--
--              return dup_func;
--      }
--
-       private string generate_struct_dup_wrapper (ValueType value_type) {
-               string dup_func = "_%sdup".printf (value_type.type_symbol.get_lower_case_cprefix ());
-@@ -2084,546 +1852,6 @@
-               ((CodeNode) stmt).ccodenode = cfrag;
-       }
--      public override void visit_if_statement (IfStatement stmt) {
--              stmt.accept_children (codegen);
--
--              if (stmt.false_statement != null) {
--                      stmt.ccodenode = new CCodeIfStatement ((CCodeExpression) stmt.condition.ccodenode, (CCodeStatement) stmt.true_statement.ccodenode, (CCodeStatement) stmt.false_statement.ccodenode);
--              } else {
--                      stmt.ccodenode = new CCodeIfStatement ((CCodeExpression) stmt.condition.ccodenode, (CCodeStatement) stmt.true_statement.ccodenode);
--              }
--              
--              create_temp_decl (stmt, stmt.condition.temp_vars);
--      }
--
--      void visit_string_switch_statement (SwitchStatement stmt) {
--              // we need a temporary variable to save the property value
--              var temp_var = get_temp_variable (stmt.expression.value_type, true, stmt);
--              stmt.expression.temp_vars.insert (0, temp_var);
--
--              var ctemp = new CCodeIdentifier (temp_var.name);
--              var cinit = new CCodeAssignment (ctemp, (CCodeExpression) stmt.expression.ccodenode);
--              var czero = new CCodeConstant ("0");
--
--              var cswitchblock = new CCodeFragment ();
--              stmt.ccodenode = cswitchblock;
--
--              var cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeConstant ("NULL"), ctemp);
--              var cquark = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_string"));
--              cquark.add_argument (ctemp);
--
--              var ccond = new CCodeConditionalExpression (cisnull, new CCodeConstant ("0"), cquark);
--
--              temp_var = get_temp_variable (gquark_type);
--              stmt.expression.temp_vars.insert (0, temp_var);
--
--              int label_count = 0;
--
--              foreach (SwitchSection section in stmt.get_sections ()) {
--                      if (section.has_default_label ()) {
--                              continue;
--                      }
--
--                      foreach (SwitchLabel label in section.get_labels ()) {
--                              var cexpr = (CCodeExpression) label.expression.ccodenode;
--
--                              if (is_constant_ccode_expression (cexpr)) {
--                                      var cname = "%s_label%d".printf (temp_var.name, label_count++);
--                                      var cdecl = new CCodeDeclaration (gquark_type.get_cname ());
--
--                                      cdecl.modifiers = CCodeModifiers.STATIC;
--                                      cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (cname, czero));
--
--                                      cswitchblock.append (cdecl);
--                              }
--                      }
--              }
--
--              cswitchblock.append (new CCodeExpressionStatement (cinit));
--
--              ctemp = new CCodeIdentifier (temp_var.name);
--              cinit = new CCodeAssignment (ctemp, ccond);
--
--              cswitchblock.append (new CCodeExpressionStatement (cinit));
--              create_temp_decl (stmt, stmt.expression.temp_vars);
--
--              Gee.List<Statement> default_statements = null;
--              label_count = 0;
--
--              // generate nested if statements                
--              CCodeStatement ctopstmt = null;
--              CCodeIfStatement coldif = null;
--
--              foreach (SwitchSection section in stmt.get_sections ()) {
--                      if (section.has_default_label ()) {
--                              default_statements = section.get_statements ();
--                              continue;
--                      }
--
--                      CCodeBinaryExpression cor = null;
--                      foreach (SwitchLabel label in section.get_labels ()) {
--                              var cexpr = (CCodeExpression) label.expression.ccodenode;
--
--                              if (is_constant_ccode_expression (cexpr)) {
--                                      var cname = new CCodeIdentifier ("%s_label%d".printf (temp_var.name, label_count++));
--                                      var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, czero, cname);
--                                      var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_static_string"));
--                                      var cinit = new CCodeParenthesizedExpression (new CCodeAssignment (cname, ccall));
--
--                                      ccall.add_argument (cexpr);
--
--                                      cexpr = new CCodeConditionalExpression (ccond, cname, cinit);
--                              } else {
--                                      var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_string"));
--                                      ccall.add_argument (cexpr);
--                                      cexpr = ccall;
--                              }
--
--                              var ccmp = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ctemp, cexpr);
--
--                              if (cor == null) {
--                                      cor = ccmp;
--                              } else {
--                                      cor = new CCodeBinaryExpression (CCodeBinaryOperator.OR, cor, ccmp);
--                              }
--                      }
--
--                      var cblock = new CCodeBlock ();
--                      foreach (CodeNode body_stmt in section.get_statements ()) {
--                              if (body_stmt.ccodenode is CCodeFragment) {
--                                      foreach (CCodeNode cstmt in ((CCodeFragment) body_stmt.ccodenode).get_children ()) {
--                                              cblock.add_statement (cstmt);
--                                      }
--                              } else {
--                                      cblock.add_statement (body_stmt.ccodenode);
--                              }
--                      }
--
--                      var cdo = new CCodeDoStatement (cblock, new CCodeConstant ("0"));
--                      var cif = new CCodeIfStatement (cor, cdo);
--
--                      if (coldif != null) {
--                              coldif.false_statement = cif;
--                      } else {
--                              ctopstmt = cif;
--                      }
--
--                      coldif = cif;
--              }
--      
--              if (default_statements != null) {
--                      var cblock = new CCodeBlock ();
--                      foreach (CodeNode body_stmt in default_statements) {
--                              cblock.add_statement (body_stmt.ccodenode);
--                      }
--              
--                      var cdo = new CCodeDoStatement (cblock, new CCodeConstant ("0"));
--
--                      if (coldif == null) {
--                              // there is only one section and that section
--                              // contains a default label
--                              ctopstmt = cdo;
--                      } else {
--                              coldif.false_statement = cdo;
--                      }
--              }
--      
--              cswitchblock.append (ctopstmt);
--      }
--
--      public override void visit_switch_statement (SwitchStatement stmt) {
--              if (stmt.expression.value_type.compatible (string_type)) {
--                      visit_string_switch_statement (stmt);
--                      return;
--              }
--
--              var cswitch = new CCodeSwitchStatement ((CCodeExpression) stmt.expression.ccodenode);
--              stmt.ccodenode = cswitch;
--
--              foreach (SwitchSection section in stmt.get_sections ()) {
--                      if (section.has_default_label ()) {
--                              cswitch.add_statement (new CCodeLabel ("default"));
--                              var cdefaultblock = new CCodeBlock ();
--                              cswitch.add_statement (cdefaultblock);
--                              foreach (CodeNode default_stmt in section.get_statements ()) {
--                                      cdefaultblock.add_statement (default_stmt.ccodenode);
--                              }
--                              continue;
--                      }
--
--                      foreach (SwitchLabel label in section.get_labels ()) {
--                              cswitch.add_statement (new CCodeCaseStatement ((CCodeExpression) label.expression.ccodenode));
--                      }
--
--                      var cblock = new CCodeBlock ();
--                      cswitch.add_statement (cblock);
--                      foreach (CodeNode body_stmt in section.get_statements ()) {
--                              cblock.add_statement (body_stmt.ccodenode);
--                      }
--              }
--      }
--
--      public override void visit_switch_section (SwitchSection section) {
--              visit_block (section);
--      }
--
--      public override void visit_while_statement (WhileStatement stmt) {
--              stmt.accept_children (codegen);
--
--              stmt.ccodenode = new CCodeWhileStatement ((CCodeExpression) stmt.condition.ccodenode, (CCodeStatement) stmt.body.ccodenode);
--              
--              create_temp_decl (stmt, stmt.condition.temp_vars);
--      }
--
--      public override void visit_do_statement (DoStatement stmt) {
--              stmt.accept_children (codegen);
--
--              stmt.ccodenode = new CCodeDoStatement ((CCodeStatement) stmt.body.ccodenode, (CCodeExpression) stmt.condition.ccodenode);
--              
--              create_temp_decl (stmt, stmt.condition.temp_vars);
--      }
--
--      public override void visit_for_statement (ForStatement stmt) {
--              stmt.accept_children (codegen);
--
--              CCodeExpression ccondition = null;
--              if (stmt.condition != null) {
--                      ccondition = (CCodeExpression) stmt.condition.ccodenode;
--              }
--
--              var cfor = new CCodeForStatement (ccondition, (CCodeStatement) stmt.body.ccodenode);
--              stmt.ccodenode = cfor;
--              
--              foreach (Expression init_expr in stmt.get_initializer ()) {
--                      cfor.add_initializer ((CCodeExpression) init_expr.ccodenode);
--                      create_temp_decl (stmt, init_expr.temp_vars);
--              }
--              
--              foreach (Expression it_expr in stmt.get_iterator ()) {
--                      cfor.add_iterator ((CCodeExpression) it_expr.ccodenode);
--                      create_temp_decl (stmt, it_expr.temp_vars);
--              }
--
--              if (stmt.condition != null) {
--                      create_temp_decl (stmt, stmt.condition.temp_vars);
--              }
--      }
--
--      public override void visit_foreach_statement (ForeachStatement stmt) {
--              stmt.element_variable.active = true;
--              stmt.collection_variable.active = true;
--              if (stmt.iterator_variable != null) {
--                      stmt.iterator_variable.active = true;
--              }
--
--              visit_block (stmt);
--
--              var cblock = new CCodeBlock ();
--              // sets #line
--              stmt.ccodenode = cblock;
--
--              var cfrag = new CCodeFragment ();
--              append_temp_decl (cfrag, stmt.collection.temp_vars);
--              cblock.add_statement (cfrag);
--              
--              var collection_backup = stmt.collection_variable;
--              var collection_type = collection_backup.variable_type.copy ();
--              var ccoldecl = new CCodeDeclaration (collection_type.get_cname ());
--              var ccolvardecl = new CCodeVariableDeclarator.with_initializer (collection_backup.name, (CCodeExpression) stmt.collection.ccodenode);
--              ccolvardecl.line = cblock.line;
--              ccoldecl.add_declarator (ccolvardecl);
--              cblock.add_statement (ccoldecl);
--              
--              if (stmt.tree_can_fail && stmt.collection.tree_can_fail) {
--                      // exception handling
--                      var cfrag = new CCodeFragment ();
--                      head.add_simple_check (stmt.collection, cfrag);
--                      cblock.add_statement (cfrag);
--              }
--
--              if (stmt.collection.value_type is ArrayType) {
--                      var array_type = (ArrayType) stmt.collection.value_type;
--                      
--                      var array_len = head.get_array_length_cexpression (stmt.collection);
--
--                      // store array length for use by _vala_array_free
--                      var clendecl = new CCodeDeclaration ("int");
--                      clendecl.add_declarator (new CCodeVariableDeclarator.with_initializer (head.get_array_length_cname (collection_backup.name, 1), array_len));
--                      cblock.add_statement (clendecl);
--
--                      if (array_len is CCodeConstant) {
--                              // the array has no length parameter i.e. it is NULL-terminated array
--
--                              var it_name = "%s_it".printf (stmt.variable_name);
--                      
--                              var citdecl = new CCodeDeclaration (collection_type.get_cname ());
--                              citdecl.add_declarator (new CCodeVariableDeclarator (it_name));
--                              cblock.add_statement (citdecl);
--                              
--                              var cbody = new CCodeBlock ();
--
--                              CCodeExpression element_expr = new CCodeIdentifier ("*%s".printf (it_name));
--
--                              var element_type = array_type.element_type.copy ();
--                              element_type.value_owned = false;
--                              element_expr = transform_expression (element_expr, element_type, stmt.type_reference);
--
--                              var cfrag = new CCodeFragment ();
--                              append_temp_decl (cfrag, temp_vars);
--                              cbody.add_statement (cfrag);
--                              temp_vars.clear ();
--
--                              var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
--                              cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr));
--                              cbody.add_statement (cdecl);
--
--                              // add array length variable for stacked arrays
--                              if (stmt.type_reference is ArrayType) {
--                                      var inner_array_type = (ArrayType) stmt.type_reference;
--                                      for (int dim = 1; dim <= inner_array_type.rank; dim++) {
--                                              cdecl = new CCodeDeclaration ("int");
--                                              cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (head.get_array_length_cname (stmt.variable_name, dim), new CCodeConstant ("-1")));
--                                              cbody.add_statement (cdecl);
--                                      }
--                              }
--
--                              cbody.add_statement (stmt.body.ccodenode);
--                              
--                              var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("*%s".printf (it_name)), new CCodeConstant ("NULL"));
--                              
--                              var cfor = new CCodeForStatement (ccond, cbody);
--
--                              cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeIdentifier (collection_backup.name)));
--              
--                              cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier (it_name), new CCodeConstant ("1"))));
--                              cblock.add_statement (cfor);
--                      } else {
--                              // the array has a length parameter
--
--                              var it_name = (stmt.variable_name + "_it");
--                      
--                              var citdecl = new CCodeDeclaration ("int");
--                              citdecl.add_declarator (new CCodeVariableDeclarator (it_name));
--                              cblock.add_statement (citdecl);
--                              
--                              var cbody = new CCodeBlock ();
--
--                              CCodeExpression element_expr = new CCodeElementAccess (new CCodeIdentifier (collection_backup.name), new CCodeIdentifier (it_name));
--
--                              var element_type = array_type.element_type.copy ();
--                              element_type.value_owned = false;
--                              element_expr = transform_expression (element_expr, element_type, stmt.type_reference);
--
--                              var cfrag = new CCodeFragment ();
--                              append_temp_decl (cfrag, temp_vars);
--                              cbody.add_statement (cfrag);
--                              temp_vars.clear ();
--
--                              var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
--                              cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr));
--                              cbody.add_statement (cdecl);
--
--                              // add array length variable for stacked arrays
--                              if (stmt.type_reference is ArrayType) {
--                                      var inner_array_type = (ArrayType) stmt.type_reference;
--                                      for (int dim = 1; dim <= inner_array_type.rank; dim++) {
--                                              cdecl = new CCodeDeclaration ("int");
--                                              cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (head.get_array_length_cname (stmt.variable_name, dim), new CCodeConstant ("-1")));
--                                              cbody.add_statement (cdecl);
--                                      }
--                              }
--
--                              cbody.add_statement (stmt.body.ccodenode);
--                              
--                              var ccond_ind1 = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, array_len, new CCodeConstant ("-1"));
--                              var ccond_ind2 = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier (it_name), array_len);
--                              var ccond_ind = new CCodeBinaryExpression (CCodeBinaryOperator.AND, ccond_ind1, ccond_ind2);
--                              
--                              /* only check for null if the containers elements are of reference-type */
--                              CCodeBinaryExpression ccond;
--                              if (array_type.element_type.is_reference_type_or_type_parameter ()) {
--                                      var ccond_term1 = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, array_len, new CCodeConstant ("-1"));
--                                      var ccond_term2 = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeElementAccess (new CCodeIdentifier (collection_backup.name), new CCodeIdentifier (it_name)), new CCodeConstant ("NULL"));
--                                      var ccond_term = new CCodeBinaryExpression (CCodeBinaryOperator.AND, ccond_term1, ccond_term2);
--
--                                      ccond = new CCodeBinaryExpression (CCodeBinaryOperator.OR, new CCodeParenthesizedExpression (ccond_ind), new CCodeParenthesizedExpression (ccond_term));
--                              } else {
--                                      /* assert when trying to iterate over value-type arrays of unknown length */
--                                      var cassert = new CCodeFunctionCall (new CCodeIdentifier ("g_assert"));
--                                      cassert.add_argument (ccond_ind1);
--                                      cblock.add_statement (new CCodeExpressionStatement (cassert));
--
--                                      ccond = ccond_ind2;
--                              }
--                              
--                              var cfor = new CCodeForStatement (ccond, cbody);
--                              cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeConstant ("0")));
--                              cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier (it_name), new CCodeConstant ("1"))));
--                              cblock.add_statement (cfor);
--                      }
--              } else if (stmt.collection.value_type.compatible (new ObjectType (glist_type)) || stmt.collection.value_type.compatible (new ObjectType (gslist_type))) {
--                      // iterating over a GList or GSList
--
--                      var it_name = "%s_it".printf (stmt.variable_name);
--              
--                      var citdecl = new CCodeDeclaration (collection_type.get_cname ());
--                      var citvardecl = new CCodeVariableDeclarator (it_name);
--                      citvardecl.line = cblock.line;
--                      citdecl.add_declarator (citvardecl);
--                      cblock.add_statement (citdecl);
--                      
--                      var cbody = new CCodeBlock ();
--
--                      CCodeExpression element_expr = new CCodeMemberAccess.pointer (new CCodeIdentifier (it_name), "data");
--
--                      if (collection_type.get_type_arguments ().size != 1) {
--                              Report.error (stmt.source_reference, "internal error: missing generic type argument");
--                              stmt.error = true;
--                              return;
--                      }
--
--                      var element_data_type = collection_type.get_type_arguments ().get (0).copy ();
--                      element_data_type.value_owned = false;
--                      element_data_type.is_type_argument = true;
--                      element_expr = transform_expression (element_expr, element_data_type, stmt.type_reference);
--
--                      var cfrag = new CCodeFragment ();
--                      append_temp_decl (cfrag, temp_vars);
--                      cbody.add_statement (cfrag);
--                      temp_vars.clear ();
--
--                      var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
--                      var cvardecl = new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr);
--                      cvardecl.line = cblock.line;
--                      cdecl.add_declarator (cvardecl);
--                      cbody.add_statement (cdecl);
--                      
--                      cbody.add_statement (stmt.body.ccodenode);
--                      
--                      var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier (it_name), new CCodeConstant ("NULL"));
--                      
--                      var cfor = new CCodeForStatement (ccond, cbody);
--                      
--                      cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeIdentifier (collection_backup.name)));
--
--                      cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeMemberAccess.pointer (new CCodeIdentifier (it_name), "next")));
--                      cblock.add_statement (cfor);
--              } else if (list_type != null && stmt.collection.value_type.compatible (new ObjectType (list_type))) {
--                      // iterating over a Gee.List, use integer to avoid the cost of an iterator object
--
--                      var it_name = "%s_it".printf (stmt.variable_name);
--
--                      var citdecl = new CCodeDeclaration ("int");
--                      citdecl.add_declarator (new CCodeVariableDeclarator (it_name));
--                      cblock.add_statement (citdecl);
--                      
--                      var cbody = new CCodeBlock ();
--
--                      var get_method = (Method) list_type.scope.lookup ("get");
--                      var get_ccall = new CCodeFunctionCall (new CCodeIdentifier (get_method.get_cname ()));
--                      get_ccall.add_argument (new InstanceCast (new CCodeIdentifier (collection_backup.name), list_type));
--                      get_ccall.add_argument (new CCodeIdentifier (it_name));
--                      CCodeExpression element_expr = get_ccall;
--
--                      var element_type = SemanticAnalyzer.get_actual_type (stmt.collection.value_type, get_method, get_method.return_type, stmt);
--
--                      element_expr = transform_expression (element_expr, element_type, stmt.type_reference);
--
--                      var cfrag = new CCodeFragment ();
--                      append_temp_decl (cfrag, temp_vars);
--                      cbody.add_statement (cfrag);
--                      temp_vars.clear ();
--
--                      var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
--                      var cvardecl = new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr);
--                      cvardecl.line = cblock.line;
--                      cdecl.add_declarator (cvardecl);
--                      cbody.add_statement (cdecl);
--
--                      cbody.add_statement (stmt.body.ccodenode);
--
--                      var list_len = new CCodeFunctionCall (new CCodeIdentifier ("gee_collection_get_size"));
--                      list_len.add_argument (new InstanceCast (new CCodeIdentifier (collection_backup.name), this.collection_type));
--
--                      var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier (it_name), list_len);
--
--                      var cfor = new CCodeForStatement (ccond, cbody);
--                      cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeConstant ("0")));
--                      cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier (it_name), new CCodeConstant ("1"))));
--                      cfor.line = cblock.line;
--                      cblock.add_statement (cfor);
--              } else if (iterable_type != null && stmt.collection.value_type.compatible (new ObjectType (iterable_type))) {
--                      // iterating over a Gee.Iterable, use iterator
--
--                      var it_name = "%s_it".printf (stmt.variable_name);
--
--                      var citdecl = new CCodeDeclaration (iterator_type.get_cname () + "*");
--                      var it_method = (Method) iterable_type.scope.lookup ("iterator");
--                      var it_ccall = new CCodeFunctionCall (new CCodeIdentifier (it_method.get_cname ()));
--                      it_ccall.add_argument (new InstanceCast (new CCodeIdentifier (collection_backup.name), iterable_type));
--                      var citvardecl = new CCodeVariableDeclarator.with_initializer (it_name, it_ccall);
--                      citvardecl.line = cblock.line;
--                      citdecl.add_declarator (citvardecl);
--                      cblock.add_statement (citdecl);
--                      
--                      var cbody = new CCodeBlock ();
--
--                      var get_method = (Method) iterator_type.scope.lookup ("get");
--                      var get_ccall = new CCodeFunctionCall (new CCodeIdentifier (get_method.get_cname ()));
--                      get_ccall.add_argument (new CCodeIdentifier (it_name));
--                      CCodeExpression element_expr = get_ccall;
--
--                      Iterator<DataType> type_arg_it = it_method.return_type.get_type_arguments ().iterator ();
--                      type_arg_it.next ();
--                      var it_type = SemanticAnalyzer.get_actual_type (stmt.collection.value_type, it_method, type_arg_it.get (), stmt);
--
--                      element_expr = transform_expression (element_expr, it_type, stmt.type_reference);
--
--                      var cfrag = new CCodeFragment ();
--                      append_temp_decl (cfrag, temp_vars);
--                      cbody.add_statement (cfrag);
--                      temp_vars.clear ();
--
--                      var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
--                      var cvardecl = new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr);
--                      cvardecl.line = cblock.line;
--                      cdecl.add_declarator (cvardecl);
--                      cbody.add_statement (cdecl);
--                      
--                      cbody.add_statement (stmt.body.ccodenode);
--
--                      var next_method = (Method) iterator_type.scope.lookup ("next");
--                      var next_ccall = new CCodeFunctionCall (new CCodeIdentifier (next_method.get_cname ()));
--                      next_ccall.add_argument (new CCodeIdentifier (it_name));
--
--                      var cwhile = new CCodeWhileStatement (next_ccall, cbody);
--                      cwhile.line = cblock.line;
--                      cblock.add_statement (cwhile);
--              }
--
--              foreach (LocalVariable local in stmt.get_local_variables ()) {
--                      if (requires_destroy (local.variable_type)) {
--                              var ma = new MemberAccess.simple (local.name);
--                              ma.symbol_reference = local;
--                              var cunref = new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier (get_variable_cname (local.name)), local.variable_type, ma));
--                              cunref.line = cblock.line;
--                              cblock.add_statement (cunref);
--                      }
--              }
--      }
--
--      public override void visit_break_statement (BreakStatement stmt) {
--              stmt.ccodenode = new CCodeBreakStatement ();
--
--              create_local_free (stmt, true);
--      }
--
--      public override void visit_continue_statement (ContinueStatement stmt) {
--              stmt.ccodenode = new CCodeContinueStatement ();
--
--              create_local_free (stmt, true);
--      }
--
-       public void append_local_free (Symbol sym, CCodeFragment cfrag, bool stop_at_loop) {
-               var b = (Block) sym;
-@@ -2661,7 +1889,7 @@
-               }
-       }
--      private void create_local_free (CodeNode stmt, bool stop_at_loop = false) {
-+      public void create_local_free (CodeNode stmt, bool stop_at_loop = false) {
-               var cfrag = new CCodeFragment ();
-       
-               append_local_free (current_symbol, cfrag, stop_at_loop);
-@@ -2992,7 +2220,7 @@
-               return true;
-       }
--      private CCodeExpression? get_ref_cexpression (DataType expression_type, CCodeExpression cexpr, Expression? expr, CodeNode node) {
-+      public CCodeExpression? get_ref_cexpression (DataType expression_type, CCodeExpression cexpr, Expression? expr, CodeNode node) {
-               if (expression_type is ValueType && !expression_type.nullable) {
-                       // normal value type, no null check
-                       // (copy (&expr, &temp), temp)
-@@ -3785,7 +3013,7 @@
-               return cexpr;
-       }
--      private CCodeExpression get_implicit_cast_expression (CCodeExpression source_cexpr, DataType? expression_type, DataType? target_type, Expression? expr = null) {
-+      public virtual CCodeExpression get_implicit_cast_expression (CCodeExpression source_cexpr, DataType? expression_type, DataType? target_type, Expression? expr = null) {
-               var cexpr = source_cexpr;
-               if (expression_type.data_type != null && expression_type.data_type == target_type.data_type) {
-@@ -3811,180 +3039,11 @@
-                       } else {
-                               return cexpr;
-                       }
--              } else if (target_type is DelegateType && expression_type is MethodType) {
--                      var dt = (DelegateType) target_type;
--                      var mt = (MethodType) expression_type;
--
--                      var method = mt.method_symbol;
--                      if (method.base_method != null) {
--                              method = method.base_method;
--                      } else if (method.base_interface_method != null) {
--                              method = method.base_interface_method;
--                      }
--
--                      return new CCodeIdentifier (generate_delegate_wrapper (method, dt.delegate_symbol));
-               } else {
-                       return cexpr;
-               }
-       }
--      private string generate_delegate_wrapper (Method m, Delegate d) {
--              string delegate_name;
--              var sig = d.parent_symbol as Signal;
--              var dynamic_sig = sig as DynamicSignal;
--              if (dynamic_sig != null) {
--                      delegate_name = head.get_dynamic_signal_cname (dynamic_sig);
--              } else if (sig != null) {
--                      delegate_name = sig.parent_symbol.get_lower_case_cprefix () + sig.get_cname ();
--              } else {
--                      delegate_name = Symbol.camel_case_to_lower_case (d.get_cname ());
--              }
--
--              string wrapper_name = "_%s_%s".printf (m.get_cname (), delegate_name);
--
--              if (!add_wrapper (wrapper_name)) {
--                      // wrapper already defined
--                      return wrapper_name;
--              }
--
--              // declaration
--
--              var function = new CCodeFunction (wrapper_name, m.return_type.get_cname ());
--              function.modifiers = CCodeModifiers.STATIC;
--              m.ccodenode = function;
--
--              var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
--
--              if (d.has_target) {
--                      var cparam = new CCodeFormalParameter ("self", "gpointer");
--                      cparam_map.set (get_param_pos (d.cinstance_parameter_position), cparam);
--              }
--
--              var d_params = d.get_parameters ();
--              foreach (FormalParameter param in d_params) {
--                      // ensure that C code node has been generated
--                      param.accept (codegen);
--
--                      cparam_map.set (get_param_pos (param.cparameter_position), (CCodeFormalParameter) param.ccodenode);
--
--                      // handle array parameters
--                      if (!param.no_array_length && param.parameter_type is ArrayType) {
--                              var array_type = (ArrayType) param.parameter_type;
--                              
--                              var length_ctype = "int";
--                              if (param.direction != ParameterDirection.IN) {
--                                      length_ctype = "int*";
--                              }
--                              
--                              for (int dim = 1; dim <= array_type.rank; dim++) {
--                                      var cparam = new CCodeFormalParameter (head.get_array_length_cname (param.name, dim), length_ctype);
--                                      cparam_map.set (get_param_pos (param.carray_length_parameter_position + 0.01 * dim), cparam);
--                              }
--                      }
--
--              }
--
--              if (m.get_error_types ().size > 0) {
--                      var cparam = new CCodeFormalParameter ("error", "GError**");
--                      cparam_map.set (get_param_pos (-1), cparam);
--              }
--
--              // append C parameters in the right order
--              int last_pos = -1;
--              int min_pos;
--              while (true) {
--                      min_pos = -1;
--                      foreach (int pos in cparam_map.get_keys ()) {
--                              if (pos > last_pos && (min_pos == -1 || pos < min_pos)) {
--                                      min_pos = pos;
--                              }
--                      }
--                      if (min_pos == -1) {
--                              break;
--                      }
--                      function.add_parameter (cparam_map.get (min_pos));
--                      last_pos = min_pos;
--              }
--
--
--              // definition
--
--              var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
--
--              int i = 0;
--              if (m.binding == MemberBinding.INSTANCE) {
--                      CCodeExpression arg;
--                      if (d.has_target) {
--                              arg = new CCodeIdentifier ("self");
--                      } else {
--                              // use first delegate parameter as instance
--                              arg = new CCodeIdentifier ((d_params.get (0).ccodenode as CCodeFormalParameter).name);
--                              i = 1;
--                      }
--                      carg_map.set (get_param_pos (m.cinstance_parameter_position), arg);
--              }
--
--              foreach (FormalParameter param in m.get_parameters ()) {
--                      CCodeExpression arg;
--                      arg = new CCodeIdentifier ((d_params.get (i).ccodenode as CCodeFormalParameter).name);
--                      carg_map.set (get_param_pos (param.cparameter_position), arg);
--
--                      // handle array arguments
--                      if (!param.no_array_length && param.parameter_type is ArrayType) {
--                              var array_type = (ArrayType) param.parameter_type;
--                              for (int dim = 1; dim <= array_type.rank; dim++) {
--                                      CCodeExpression clength;
--                                      if (d_params.get (i).no_array_length) {
--                                              clength = new CCodeConstant ("-1");
--                                      } else {
--                                              clength = new CCodeIdentifier (head.get_array_length_cname (d_params.get (i).name, dim));
--                                      }
--                                      carg_map.set (get_param_pos (param.carray_length_parameter_position + 0.01 * dim), clength);
--                              }
--                      }
--
--                      i++;
--              }
--
--              if (m.get_error_types ().size > 0) {
--                      carg_map.set (get_param_pos (-1), new CCodeIdentifier ("error"));
--              }
--
--              var ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname ()));
--
--              // append C arguments in the right order
--              last_pos = -1;
--              while (true) {
--                      min_pos = -1;
--                      foreach (int pos in carg_map.get_keys ()) {
--                              if (pos > last_pos && (min_pos == -1 || pos < min_pos)) {
--                                      min_pos = pos;
--                              }
--                      }
--                      if (min_pos == -1) {
--                              break;
--                      }
--                      ccall.add_argument (carg_map.get (min_pos));
--                      last_pos = min_pos;
--              }
--
--              var block = new CCodeBlock ();
--              if (m.return_type is VoidType) {
--                      block.add_statement (new CCodeExpressionStatement (ccall));
--              } else {
--                      block.add_statement (new CCodeReturnStatement (ccall));
--              }
--
--              // append to file
--
--              source_type_member_declaration.append (function.copy ());
--
--              function.block = block;
--              source_type_member_definition.append (function);
--
--              return wrapper_name;
--      }
--
-       public CCodeFunctionCall get_property_set_call (Property prop, MemberAccess ma, CCodeExpression cexpr) {
-               if (ma.inner is BaseAccess) {
-                       if (prop.base_property != null) {
-Index: gobject/valaccodedelegatemodule.vala
-===================================================================
---- gobject/valaccodedelegatemodule.vala       (revision 1971)
-+++ gobject/valaccodedelegatemodule.vala       (revision 2004)
-@@ -21,7 +21,7 @@
-  *    Raffaele Sandrini <raffaele@sandrini.ch>
-  */
--using GLib;
-+using Gee;
- /**
-  * The link between an assignment and generated code.
-@@ -166,4 +166,179 @@
-       public override string get_delegate_target_destroy_notify_cname (string delegate_cname) {
-               return "%s_target_destroy_notify".printf (delegate_cname);
-       }
-+
-+      public override CCodeExpression get_implicit_cast_expression (CCodeExpression source_cexpr, DataType? expression_type, DataType? target_type, Expression? expr = null) {
-+              if (target_type is DelegateType && expression_type is MethodType) {
-+                      var dt = (DelegateType) target_type;
-+                      var mt = (MethodType) expression_type;
-+
-+                      var method = mt.method_symbol;
-+                      if (method.base_method != null) {
-+                              method = method.base_method;
-+                      } else if (method.base_interface_method != null) {
-+                              method = method.base_interface_method;
-+                      }
-+
-+                      return new CCodeIdentifier (generate_delegate_wrapper (method, dt.delegate_symbol));
-+              } else {
-+                      return base.get_implicit_cast_expression (source_cexpr, expression_type, target_type, expr);
-+              }
-+      }
-+
-+      private string generate_delegate_wrapper (Method m, Delegate d) {
-+              string delegate_name;
-+              var sig = d.parent_symbol as Signal;
-+              var dynamic_sig = sig as DynamicSignal;
-+              if (dynamic_sig != null) {
-+                      delegate_name = head.get_dynamic_signal_cname (dynamic_sig);
-+              } else if (sig != null) {
-+                      delegate_name = sig.parent_symbol.get_lower_case_cprefix () + sig.get_cname ();
-+              } else {
-+                      delegate_name = Symbol.camel_case_to_lower_case (d.get_cname ());
-+              }
-+
-+              string wrapper_name = "_%s_%s".printf (m.get_cname (), delegate_name);
-+
-+              if (!add_wrapper (wrapper_name)) {
-+                      // wrapper already defined
-+                      return wrapper_name;
-+              }
-+
-+              // declaration
-+
-+              var function = new CCodeFunction (wrapper_name, m.return_type.get_cname ());
-+              function.modifiers = CCodeModifiers.STATIC;
-+              m.ccodenode = function;
-+
-+              var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
-+
-+              if (d.has_target) {
-+                      var cparam = new CCodeFormalParameter ("self", "gpointer");
-+                      cparam_map.set (get_param_pos (d.cinstance_parameter_position), cparam);
-+              }
-+
-+              var d_params = d.get_parameters ();
-+              foreach (FormalParameter param in d_params) {
-+                      // ensure that C code node has been generated
-+                      param.accept (codegen);
-+
-+                      cparam_map.set (get_param_pos (param.cparameter_position), (CCodeFormalParameter) param.ccodenode);
-+
-+                      // handle array parameters
-+                      if (!param.no_array_length && param.parameter_type is ArrayType) {
-+                              var array_type = (ArrayType) param.parameter_type;
-+                              
-+                              var length_ctype = "int";
-+                              if (param.direction != ParameterDirection.IN) {
-+                                      length_ctype = "int*";
-+                              }
-+                              
-+                              for (int dim = 1; dim <= array_type.rank; dim++) {
-+                                      var cparam = new CCodeFormalParameter (head.get_array_length_cname (param.name, dim), length_ctype);
-+                                      cparam_map.set (get_param_pos (param.carray_length_parameter_position + 0.01 * dim), cparam);
-+                              }
-+                      }
-+
-+              }
-+
-+              if (m.get_error_types ().size > 0) {
-+                      var cparam = new CCodeFormalParameter ("error", "GError**");
-+                      cparam_map.set (get_param_pos (-1), cparam);
-+              }
-+
-+              // append C parameters in the right order
-+              int last_pos = -1;
-+              int min_pos;
-+              while (true) {
-+                      min_pos = -1;
-+                      foreach (int pos in cparam_map.get_keys ()) {
-+                              if (pos > last_pos && (min_pos == -1 || pos < min_pos)) {
-+                                      min_pos = pos;
-+                              }
-+                      }
-+                      if (min_pos == -1) {
-+                              break;
-+                      }
-+                      function.add_parameter (cparam_map.get (min_pos));
-+                      last_pos = min_pos;
-+              }
-+
-+
-+              // definition
-+
-+              var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
-+
-+              int i = 0;
-+              if (m.binding == MemberBinding.INSTANCE) {
-+                      CCodeExpression arg;
-+                      if (d.has_target) {
-+                              arg = new CCodeIdentifier ("self");
-+                      } else {
-+                              // use first delegate parameter as instance
-+                              arg = new CCodeIdentifier ((d_params.get (0).ccodenode as CCodeFormalParameter).name);
-+                              i = 1;
-+                      }
-+                      carg_map.set (get_param_pos (m.cinstance_parameter_position), arg);
-+              }
-+
-+              foreach (FormalParameter param in m.get_parameters ()) {
-+                      CCodeExpression arg;
-+                      arg = new CCodeIdentifier ((d_params.get (i).ccodenode as CCodeFormalParameter).name);
-+                      carg_map.set (get_param_pos (param.cparameter_position), arg);
-+
-+                      // handle array arguments
-+                      if (!param.no_array_length && param.parameter_type is ArrayType) {
-+                              var array_type = (ArrayType) param.parameter_type;
-+                              for (int dim = 1; dim <= array_type.rank; dim++) {
-+                                      CCodeExpression clength;
-+                                      if (d_params.get (i).no_array_length) {
-+                                              clength = new CCodeConstant ("-1");
-+                                      } else {
-+                                              clength = new CCodeIdentifier (head.get_array_length_cname (d_params.get (i).name, dim));
-+                                      }
-+                                      carg_map.set (get_param_pos (param.carray_length_parameter_position + 0.01 * dim), clength);
-+                              }
-+                      }
-+
-+                      i++;
-+              }
-+
-+              if (m.get_error_types ().size > 0) {
-+                      carg_map.set (get_param_pos (-1), new CCodeIdentifier ("error"));
-+              }
-+
-+              var ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname ()));
-+
-+              // append C arguments in the right order
-+              last_pos = -1;
-+              while (true) {
-+                      min_pos = -1;
-+                      foreach (int pos in carg_map.get_keys ()) {
-+                              if (pos > last_pos && (min_pos == -1 || pos < min_pos)) {
-+                                      min_pos = pos;
-+                              }
-+                      }
-+                      if (min_pos == -1) {
-+                              break;
-+                      }
-+                      ccall.add_argument (carg_map.get (min_pos));
-+                      last_pos = min_pos;
-+              }
-+
-+              var block = new CCodeBlock ();
-+              if (m.return_type is VoidType) {
-+                      block.add_statement (new CCodeExpressionStatement (ccall));
-+              } else {
-+                      block.add_statement (new CCodeReturnStatement (ccall));
-+              }
-+
-+              // append to file
-+
-+              source_type_member_declaration.append (function.copy ());
-+
-+              function.block = block;
-+              source_type_member_definition.append (function);
-+
-+              return wrapper_name;
-+      }
- }
-Index: gobject/valaccodearraymodule.vala
-===================================================================
---- gobject/valaccodearraymodule.vala  (revision 1971)
-+++ gobject/valaccodearraymodule.vala  (revision 2004)
-@@ -28,6 +28,8 @@
-  * The link between an assignment and generated code.
-  */
- public class Vala.CCodeArrayModule : CCodeInvocationExpressionModule {
-+      private int next_array_dup_id = 0;
-+
-       public CCodeArrayModule (CCodeGenerator codegen, CCodeModule? next) {
-               base (codegen, next);
-       }
-@@ -280,26 +282,6 @@
-                       get_ccall.add_argument (cindex);
-                       expr.ccodenode = convert_from_generic_pointer (get_ccall, expr.value_type);
--              } else if (expr.container is MemberAccess && expr.container.symbol_reference is Signal) {
--                      // should be moved to the GSignal module
--
--                      // detailed signal emission
--                      var sig = (Signal) expr.symbol_reference;
--                      var ma = (MemberAccess) expr.container;
--
--                      var detail_expr = expr.get_indices ().get (0) as StringLiteral;
--                      string signal_detail = detail_expr.eval ();
--                      
--                      var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit_by_name"));
--
--                      // FIXME: use C cast if debugging disabled
--                      var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT"));
--                      ccast.add_argument ((CCodeExpression) ma.inner.ccodenode);
--                      ccall.add_argument (ccast);
--
--                      ccall.add_argument (sig.get_canonical_cconstant (signal_detail));
--                      
--                      expr.ccodenode = ccall;
-               } else {
-                       // access to element in an array
-                       for (int i = 1; i < rank; i++) {
-@@ -416,4 +398,84 @@
-               source_type_member_definition.append (fun);
-       }
-+
-+      public override CCodeExpression? get_dup_func_expression (DataType type, SourceReference? source_reference) {
-+              if (type is ArrayType) {
-+                      return new CCodeIdentifier (generate_array_dup_wrapper ((ArrayType) type));
-+              } else {
-+                      return base.get_dup_func_expression (type, source_reference);
-+              }
-+      }
-+
-+      string generate_array_dup_wrapper (ArrayType array_type) {
-+              string dup_func = "_vala_array_dup%d".printf (++next_array_dup_id);
-+
-+              if (!add_wrapper (dup_func)) {
-+                      // wrapper already defined
-+                      return dup_func;
-+              }
-+
-+              // declaration
-+
-+              var function = new CCodeFunction (dup_func, array_type.get_cname ());
-+              function.modifiers = CCodeModifiers.STATIC;
-+
-+              function.add_parameter (new CCodeFormalParameter ("self", array_type.get_cname ()));
-+              // total length over all dimensions
-+              function.add_parameter (new CCodeFormalParameter ("length", "int"));
-+
-+              // definition
-+
-+              var block = new CCodeBlock ();
-+
-+              if (requires_copy (array_type.element_type)) {
-+                      var old_temp_vars = temp_vars;
-+
-+                      var cdecl = new CCodeDeclaration (array_type.get_cname ());
-+                      var cvardecl = new CCodeVariableDeclarator ("result");
-+                      cdecl.add_declarator (cvardecl);
-+                      var gnew = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
-+                      gnew.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
-+                      gnew.add_argument (new CCodeIdentifier ("length"));
-+                      cvardecl.initializer = gnew;
-+                      block.add_statement (cdecl);
-+
-+                      var idx_decl = new CCodeDeclaration ("int");
-+                      idx_decl.add_declarator (new CCodeVariableDeclarator ("i"));
-+                      block.add_statement (idx_decl);
-+
-+                      var loop_body = new CCodeBlock ();
-+                      loop_body.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeElementAccess (new CCodeIdentifier ("result"), new CCodeIdentifier ("i")), get_ref_cexpression (array_type.element_type, new CCodeElementAccess (new CCodeIdentifier ("self"), new CCodeIdentifier ("i")), null, array_type))));
-+
-+                      var cfor = new CCodeForStatement (new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), new CCodeIdentifier ("length")), loop_body);
-+                      cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0")));
-+                      cfor.add_iterator (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("i")));
-+                      block.add_statement (cfor);
-+
-+                      block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
-+
-+                      var cfrag = new CCodeFragment ();
-+                      append_temp_decl (cfrag, temp_vars);
-+                      block.add_statement (cfrag);
-+                      temp_vars = old_temp_vars;
-+              } else {
-+                      var dup_call = new CCodeFunctionCall (new CCodeIdentifier ("g_memdup"));
-+                      dup_call.add_argument (new CCodeIdentifier ("self"));
-+
-+                      var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
-+                      sizeof_call.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
-+                      dup_call.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeIdentifier ("length"), sizeof_call));
-+
-+                      block.add_statement (new CCodeReturnStatement (dup_call));
-+              }
-+
-+              // append to file
-+
-+              source_type_member_declaration.append (function.copy ());
-+
-+              function.block = block;
-+              source_type_member_definition.append (function);
-+
-+              return dup_func;
-+      }
- }
-Index: gobject/Makefile.am
-===================================================================
---- gobject/Makefile.am        (revision 1971)
-+++ gobject/Makefile.am        (revision 2004)
-@@ -16,9 +16,8 @@
-       valaccodeassignmentmodule.vala \
-       valaccodebasemodule.vala \
-       valaccodecompiler.vala \
-+      valaccodecontrolflowmodule.vala \
-       valaccodedelegatemodule.vala \
--      valaccodedynamicpropertymodule.vala \
--      valaccodedynamicsignalmodule.vala \
-       valaccodegenerator.vala \
-       valaccodeinvocationexpressionmodule.vala \
-       valaccodememberaccessmodule.vala \
-Index: gobject/valagobjectmodule.vala
-===================================================================
---- gobject/valagobjectmodule.vala     (revision 1971)
-+++ gobject/valagobjectmodule.vala     (revision 2004)
-@@ -24,6 +24,9 @@
- using GLib;
- public class Vala.GObjectModule : GTypeModule {
-+      int dynamic_property_id;
-+      int signal_wrapper_id;
-+
-       public GObjectModule (CCodeGenerator codegen, CCodeModule? next) {
-               base (codegen, next);
-       }
-@@ -1453,5 +1456,290 @@
-               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");
-+              
-+              var ccomma = new CCodeCommaExpression ();
-+              // set name in array for current parameter
-+              var cnamemember = new CCodeMemberAccess.pointer (cpointer, "name");
-+              var cnameassign = new CCodeAssignment (cnamemember, canonical_cconstant);
-+              ccomma.append_expression (cnameassign);
-+              
-+              var gvaluearg = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeMemberAccess.pointer (cpointer, "value"));
-+              
-+              // initialize GValue in array for current parameter
-+              var cvalueinit = new CCodeFunctionCall (new CCodeIdentifier ("g_value_init"));
-+              cvalueinit.add_argument (gvaluearg);
-+              cvalueinit.add_argument (new CCodeIdentifier (property_type.get_type_id ()));
-+              ccomma.append_expression (cvalueinit);
-+              
-+              // set GValue for current parameter
-+              var cvalueset = new CCodeFunctionCall (get_value_setter_function (property_type));
-+              cvalueset.add_argument (gvaluearg);
-+              cvalueset.add_argument (value);
-+              ccomma.append_expression (cvalueset);
-+              
-+              // move pointer to next parameter in array
-+              ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, cpointer));
-+
-+              return ccomma;
-+      }
-+
-+      public override void visit_constructor (Constructor c) {
-+              current_method_inner_error = false;
-+              in_constructor = true;
-+
-+              if (c.binding == MemberBinding.CLASS || c.binding == MemberBinding.STATIC) {
-+                      in_static_or_class_ctor = true;
-+              }
-+              c.accept_children (codegen);
-+              in_static_or_class_ctor = false;
-+
-+              in_constructor = false;
-+
-+              var cl = (Class) c.parent_symbol;
-+
-+              if (c.binding == MemberBinding.INSTANCE) {
-+                      function = new CCodeFunction ("%s_constructor".printf (cl.get_lower_case_cname (null)), "GObject *");
-+                      function.modifiers = CCodeModifiers.STATIC;
-+              
-+                      function.add_parameter (new CCodeFormalParameter ("type", "GType"));
-+                      function.add_parameter (new CCodeFormalParameter ("n_construct_properties", "guint"));
-+                      function.add_parameter (new CCodeFormalParameter ("construct_properties", "GObjectConstructParam *"));
-+              
-+                      source_type_member_declaration.append (function.copy ());
-+
-+
-+                      var cblock = new CCodeBlock ();
-+                      var cdecl = new CCodeDeclaration ("GObject *");
-+                      cdecl.add_declarator (new CCodeVariableDeclarator ("obj"));
-+                      cblock.add_statement (cdecl);
-+
-+                      cdecl = new CCodeDeclaration ("%sClass *".printf (cl.get_cname ()));
-+                      cdecl.add_declarator (new CCodeVariableDeclarator ("klass"));
-+                      cblock.add_statement (cdecl);
-+
-+                      cdecl = new CCodeDeclaration ("GObjectClass *");
-+                      cdecl.add_declarator (new CCodeVariableDeclarator ("parent_class"));
-+                      cblock.add_statement (cdecl);
-+
-+
-+                      var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek"));
-+                      ccall.add_argument (new CCodeIdentifier (cl.get_type_id ()));
-+                      var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (cl.get_upper_case_cname (null))));
-+                      ccast.add_argument (ccall);
-+                      cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("klass"), ccast)));
-+
-+                      ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek_parent"));
-+                      ccall.add_argument (new CCodeIdentifier ("klass"));
-+                      ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
-+                      ccast.add_argument (ccall);
-+                      cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("parent_class"), ccast)));
-+
-+              
-+                      ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (new CCodeIdentifier ("parent_class"), "constructor"));
-+                      ccall.add_argument (new CCodeIdentifier ("type"));
-+                      ccall.add_argument (new CCodeIdentifier ("n_construct_properties"));
-+                      ccall.add_argument (new CCodeIdentifier ("construct_properties"));
-+                      cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("obj"), ccall)));
-+
-+
-+                      ccall = new InstanceCast (new CCodeIdentifier ("obj"), cl);
-+
-+                      cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
-+                      cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", ccall));
-+              
-+                      cblock.add_statement (cdecl);
-+
-+                      if (current_method_inner_error) {
-+                              /* always separate error parameter and inner_error local variable
-+                               * as error may be set to NULL but we're always interested in inner errors
-+                               */
-+                              var cdecl = new CCodeDeclaration ("GError *");
-+                              cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("inner_error", new CCodeConstant ("NULL")));
-+                              cblock.add_statement (cdecl);
-+                      }
-+
-+
-+                      cblock.add_statement (c.body.ccodenode);
-+              
-+                      cblock.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("obj")));
-+              
-+                      function.block = cblock;
-+
-+                      if (c.source_reference.comment != null) {
-+                              source_type_member_definition.append (new CCodeComment (c.source_reference.comment));
-+                      }
-+                      source_type_member_definition.append (function);
-+              } else if (c.binding == MemberBinding.CLASS) {
-+                      // class constructor
-+
-+                      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;
-+
-+                      source_type_member_declaration.append (base_init.copy ());
-+
-+                      var block = (CCodeBlock) c.body.ccodenode;
-+                      if (current_method_inner_error) {
-+                              /* always separate error parameter and inner_error local variable
-+                               * as error may be set to NULL but we're always interested in inner errors
-+                               */
-+                              var cdecl = new CCodeDeclaration ("GError *");
-+                              cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("inner_error", new CCodeConstant ("NULL")));
-+                              block.prepend_statement (cdecl);
-+                      }
-+
-+                      base_init.block = block;
-+              
-+                      source_type_member_definition.append (base_init);
-+              } else if (c.binding == MemberBinding.STATIC) {
-+                      // static class constructor
-+                      // add to class_init
-+
-+                      if (current_method_inner_error) {
-+                              /* always separate error parameter and inner_error local variable
-+                               * as error may be set to NULL but we're always interested in inner errors
-+                               */
-+                              var cdecl = new CCodeDeclaration ("GError *");
-+                              cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("inner_error", new CCodeConstant ("NULL")));
-+                              class_init_fragment.append (cdecl);
-+                      }
-+
-+                      class_init_fragment.append (c.body.ccodenode);
-+              } else {
-+                      Report.error (c.source_reference, "internal error: constructors must have instance, class, or static binding");
-+              }
-+      }
-+
-+      public override string get_dynamic_property_getter_cname (DynamicProperty prop) {
-+              if (prop.dynamic_type.data_type == null
-+                  || !prop.dynamic_type.data_type.is_subtype_of (gobject_type)) {
-+                      return base.get_dynamic_property_getter_cname (prop);
-+              }
-+
-+              string getter_cname = "_dynamic_get_%s%d".printf (prop.name, dynamic_property_id++);
-+
-+              var func = new CCodeFunction (getter_cname, prop.property_type.get_cname ());
-+              func.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.INLINE;
-+
-+              func.add_parameter (new CCodeFormalParameter ("obj", prop.dynamic_type.get_cname ()));
-+
-+              var block = new CCodeBlock ();
-+              generate_gobject_property_getter_wrapper (prop, block);
-+
-+              // append to C source file
-+              source_type_member_declaration.append (func.copy ());
-+
-+              func.block = block;
-+              source_type_member_definition.append (func);
-+
-+              return getter_cname;
-+      }
-+
-+      public override string get_dynamic_property_setter_cname (DynamicProperty prop) {
-+              if (prop.dynamic_type.data_type == null
-+                  || !prop.dynamic_type.data_type.is_subtype_of (gobject_type)) {
-+                      return base.get_dynamic_property_setter_cname (prop);
-+              }
-+
-+              string setter_cname = "_dynamic_set_%s%d".printf (prop.name, dynamic_property_id++);
-+
-+              var func = new CCodeFunction (setter_cname, "void");
-+              func.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.INLINE;
-+
-+              func.add_parameter (new CCodeFormalParameter ("obj", prop.dynamic_type.get_cname ()));
-+              func.add_parameter (new CCodeFormalParameter ("value", prop.property_type.get_cname ()));
-+
-+              var block = new CCodeBlock ();
-+              generate_gobject_property_setter_wrapper (prop, block);
-+
-+              // append to C source file
-+              source_type_member_declaration.append (func.copy ());
-+
-+              func.block = block;
-+              source_type_member_definition.append (func);
-+
-+              return setter_cname;
-+      }
-+
-+      void generate_gobject_property_getter_wrapper (DynamicProperty node, CCodeBlock block) {
-+              var cdecl = new CCodeDeclaration (node.property_type.get_cname ());
-+              cdecl.add_declarator (new CCodeVariableDeclarator ("result"));
-+              block.add_statement (cdecl);
-+
-+              var call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get"));
-+              call.add_argument (new CCodeIdentifier ("obj"));
-+              call.add_argument (node.get_canonical_cconstant ());
-+              call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result")));
-+              call.add_argument (new CCodeConstant ("NULL"));
-+
-+              block.add_statement (new CCodeExpressionStatement (call));
-+
-+              block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
-+      }
-+
-+      void generate_gobject_property_setter_wrapper (DynamicProperty node, CCodeBlock block) {
-+              var call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_set"));
-+              call.add_argument (new CCodeIdentifier ("obj"));
-+              call.add_argument (node.get_canonical_cconstant ());
-+              call.add_argument (new CCodeIdentifier ("value"));
-+              call.add_argument (new CCodeConstant ("NULL"));
-+
-+              block.add_statement (new CCodeExpressionStatement (call));
-+      }
-+
-+      public override string get_dynamic_signal_cname (DynamicSignal node) {
-+              return "dynamic_%s%d_".printf (node.name, signal_wrapper_id++);
-+      }
-+
-+      public override string get_dynamic_signal_connect_wrapper_name (DynamicSignal sig) {
-+              if (sig.dynamic_type.data_type == null
-+                  || !sig.dynamic_type.data_type.is_subtype_of (gobject_type)) {
-+                      return base.get_dynamic_signal_connect_wrapper_name (sig);
-+              }
-+
-+              string connect_wrapper_name = "_%sconnect".printf (get_dynamic_signal_cname (sig));
-+              var func = new CCodeFunction (connect_wrapper_name, "void");
-+              func.add_parameter (new CCodeFormalParameter ("obj", "gpointer"));
-+              func.add_parameter (new CCodeFormalParameter ("signal_name", "const char *"));
-+              func.add_parameter (new CCodeFormalParameter ("handler", "GCallback"));
-+              func.add_parameter (new CCodeFormalParameter ("data", "gpointer"));
-+              var block = new CCodeBlock ();
-+              generate_gobject_connect_wrapper (sig, block);
-+
-+              // append to C source file
-+              source_type_member_declaration.append (func.copy ());
-+
-+              func.block = block;
-+              source_type_member_definition.append (func);
-+
-+              return connect_wrapper_name;
-+      }
-+
-+      void generate_gobject_connect_wrapper (DynamicSignal sig, CCodeBlock block) {
-+              var m = (Method) sig.handler.symbol_reference;
-+
-+              sig.accept (codegen);
-+
-+              string connect_func = "g_signal_connect_object";
-+              if (m.binding != MemberBinding.INSTANCE) {
-+                      connect_func = "g_signal_connect";
-+              }
-+
-+              var call = new CCodeFunctionCall (new CCodeIdentifier (connect_func));
-+              call.add_argument (new CCodeIdentifier ("obj"));
-+              call.add_argument (new CCodeIdentifier ("signal_name"));
-+              call.add_argument (new CCodeIdentifier ("handler"));
-+              call.add_argument (new CCodeIdentifier ("data"));
-+
-+              if (m.binding == MemberBinding.INSTANCE) {
-+                      call.add_argument (new CCodeConstant ("0"));
-+              }
-+
-+              block.add_statement (new CCodeExpressionStatement (call));
-+      }
- }
-Index: gobject/valaccodegenerator.vala
-===================================================================
---- gobject/valaccodegenerator.vala    (revision 1971)
-+++ gobject/valaccodegenerator.vala    (revision 2004)
-@@ -35,13 +35,12 @@
-               head = new CCodeBaseModule (this, head);
-               head = new CCodeStructModule (this, head);
-               head = new CCodeMethodModule (this, head);
-+              head = new CCodeControlFlowModule (this, head);
-               head = new CCodeMemberAccessModule (this, head);
-               head = new CCodeAssignmentModule (this, head);
-               head = new CCodeInvocationExpressionModule (this, head);
-               head = new CCodeArrayModule (this, head);
-               head = new CCodeDelegateModule (this, head);
--              head = new CCodeDynamicPropertyModule (this, head);
--              head = new CCodeDynamicSignalModule (this, head);
-               head = new GErrorModule (this, head);
-               head = new GTypeModule (this, head);
-               head = new GObjectModule (this, head);
This page took 0.493638 seconds and 4 git commands to generate.