diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala
index 8922464..ccafe12 100644
--- a/codegen/valaccodearraymodule.vala
+++ b/codegen/valaccodearraymodule.vala
@@ -2,6 +2,8 @@
  *
  * Copyright (C) 2006-2010  Jürg Billeter
  * Copyright (C) 2006-2008  Raffaele Sandrini
+ * Copyright (C) 2010  Jukka-Pekka Iivonen
+ * Copyright (C) 2016  Geert Jordaens
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,8 +20,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
  *
  * Author:
- * 	Jürg Billeter <j@bitron.ch>
- *	Raffaele Sandrini <raffaele@sandrini.ch>
+ *  Jürg Billeter <j@bitron.ch>
+ *  Raffaele Sandrini <raffaele@sandrini.ch>
+ *  Jukka-Pekka Iivonen <jp0409@jippii.fi>
+ *  Geert Jordaens <geert.jordaens@telenet.be>
  */
 
 
@@ -74,12 +78,12 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
 				cexpr = new CCodeBinaryExpression (CCodeBinaryOperator.MUL, cexpr, csize);
 			}
 		}
-		
+
 		// add extra item to have array NULL-terminated for all reference types
 		if (expr.element_type.data_type != null && expr.element_type.data_type.is_reference_type ()) {
 			cexpr = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, cexpr, new CCodeConstant ("1"));
 		}
-		
+
 		gnew.add_argument (cexpr);
 
 		var temp_var = get_temp_variable (expr.value_type, true, expr);
@@ -371,6 +375,195 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
 		cfile.add_function (fun);
 	}
 
+	public override void append_vala_array_sort () {
+		cfile.add_include ("stdlib.h");
+
+		var fun = new CCodeFunction ("_vala_array_sort", "void");
+		fun.modifiers = CCodeModifiers.STATIC;
+		fun.add_parameter (new CCodeParameter ("array", "gconstpointer"));
+		fun.add_parameter (new CCodeParameter ("array_length", "gint"));
+		fun.add_parameter (new CCodeParameter ("element_size", "gsize"));
+		fun.add_parameter (new CCodeParameter ("compare_func", "GCompareDataFunc"));
+
+		push_function (fun);
+		var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_qsort_with_data"));
+		ccall.add_argument (new CCodeIdentifier ("array"));
+		ccall.add_argument (new CCodeIdentifier ("array_length"));
+		ccall.add_argument (new CCodeIdentifier ("element_size"));
+		ccall.add_argument (new CCodeIdentifier ("compare_func"));
+		ccall.add_argument (new CCodeConstant ("NULL"));
+		ccode.add_expression (ccall);
+
+		pop_function ();
+
+		cfile.add_function_declaration (fun);
+		cfile.add_function (fun);
+
+		// Add _vala_compare_*
+		string[] simple_types;
+		// These names are the actual C names of simple types
+		simple_types = new string[] { "string", "gunichar", "gchar", "guchar", "gdouble", "gfloat", "glong", "gulong", "gint", "guint", "gshort", "gushort", "gsize", "gint8", "guint8", "gint16", "guint16", "gint32", "guint32", "gint64", "guint64" };
+
+		foreach (string comptype in requires_compare_func) {
+			string fn_name = comptype;
+			if (! (comptype in simple_types)) {
+				fn_name = comptype.down ().replace ("*", "");
+			}
+			fun = new CCodeFunction ("_vala_compare_%s".printf (fn_name), "int");
+			fun.modifiers = CCodeModifiers.STATIC;
+			fun.add_parameter (new CCodeParameter ("a", "gconstpointer"));
+			fun.add_parameter (new CCodeParameter ("b", "gconstpointer"));
+			push_function (fun);
+
+			string ctypename = comptype;
+			if (comptype == "string") {
+				ctypename = "char*";
+			}
+
+			ccode.add_declaration ("%s".printf (ctypename), new CCodeVariableDeclarator ("pa"));
+			ccode.add_declaration ("%s".printf (ctypename), new CCodeVariableDeclarator ("pb"));
+			ccode.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("pa"), new CCodeConstant ("*(%s*) a".printf (ctypename)))));
+			ccode.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("pb"), new CCodeConstant ("*(%s*) b".printf (ctypename)))));
+
+			if (comptype in simple_types) {
+				if (comptype == "string") {
+					ccode.add_statement (new CCodeReturnStatement (new CCodeConstant ("g_strcmp0 (pa, pb)")));
+				} else {
+					ccode.add_statement (new CCodeReturnStatement (new CCodeConstant ("(a == NULL && b == NULL) ? 0 : (a == NULL) ? -1 : (b == NULL) ? 1 : (pa < pb) ? -1 : ((pa == pb) ? 0: 1)")));
+				}
+			} else {
+				ccode.add_statement (new CCodeReturnStatement (new CCodeConstant ("(pa == NULL && pb == NULL) ? 0 : (pa == NULL) ? -1 : (pb == NULL) ? 1 : %s_compare (pa, pb)".printf (fn_name))));
+			}
+
+			pop_function ();
+
+			cfile.add_function_declaration (fun);
+			cfile.add_function (fun);
+		}
+	}
+
+	public override void append_vala_array_reverse () {
+		cfile.add_include ("string.h");
+
+		var fun = new CCodeFunction ("_vala_array_reverse", "void");
+		fun.modifiers = CCodeModifiers.STATIC;
+		fun.add_parameter (new CCodeParameter ("array", "gpointer"));
+		fun.add_parameter (new CCodeParameter ("element_size", "gsize"));
+		fun.add_parameter (new CCodeParameter ("array_length", "gint"));
+
+		push_function (fun);
+
+
+		ccode.add_declaration ("int", new CCodeVariableDeclarator ("i"));
+		ccode.add_declaration ("void*", new CCodeVariableDeclarator ("tmpbuf"));
+
+		var init_call = new CCodeFunctionCall (new CCodeIdentifier ("g_malloc"));
+		init_call.add_argument (new CCodeConstant ("element_size"));
+
+		ccode.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("tmpbuf"), init_call)));
+
+		ccode.add_declaration ("int", new CCodeVariableDeclarator ("newi"));
+
+		var cforinit = new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0"));
+		var cforcond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), new CCodeBinaryExpression (CCodeBinaryOperator.DIV, new CCodeIdentifier ("array_length"), new CCodeConstant ("2")));
+		var cforiter = new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("i"), new CCodeConstant ("1")));
+		ccode.open_for (cforinit, cforcond, cforiter);
+
+		ccode.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("newi"), new CCodeConstant ("array_length - i - 1"))));
+
+		var totmp_call = new CCodeFunctionCall (new CCodeIdentifier ("memcpy"));
+		totmp_call.add_argument (new CCodeConstant ("tmpbuf"));
+		totmp_call.add_argument (new CCodeConstant ("(((char*) array) + (i*element_size))"));
+		totmp_call.add_argument (new CCodeConstant ("element_size"));
+		ccode.add_statement (new CCodeExpressionStatement (totmp_call));
+
+		var toarr_call = new CCodeFunctionCall (new CCodeIdentifier ("memcpy"));
+		toarr_call.add_argument (new CCodeConstant ("(((char*) array) + (i*element_size))"));
+		toarr_call.add_argument (new CCodeConstant ("(((char*) array) + (newi*element_size))"));
+		toarr_call.add_argument (new CCodeConstant ("element_size"));
+		ccode.add_statement (new CCodeExpressionStatement (toarr_call));
+
+		var tonew_call = new CCodeFunctionCall (new CCodeIdentifier ("memcpy"));
+		tonew_call.add_argument (new CCodeConstant ("(((char*) array) + (newi*element_size))"));
+		tonew_call.add_argument (new CCodeConstant ("tmpbuf"));
+		tonew_call.add_argument (new CCodeConstant ("element_size"));
+		ccode.add_statement (new CCodeExpressionStatement (tonew_call));
+
+		ccode.close ();
+
+		var free_call = new CCodeFunctionCall (new CCodeIdentifier ("g_free"));
+		free_call.add_argument (new CCodeConstant ("tmpbuf"));
+
+		ccode.add_statement (new CCodeExpressionStatement (free_call));
+
+		pop_function ();
+
+		cfile.add_function_declaration (fun);
+		cfile.add_function (fun);
+	}
+
+	public override void append_vala_array_shuffle () {
+		cfile.add_include ("string.h");
+
+		var fun = new CCodeFunction ("_vala_array_shuffle", "void");
+		fun.modifiers = CCodeModifiers.STATIC;
+		fun.add_parameter (new CCodeParameter ("array", "gpointer"));
+		fun.add_parameter (new CCodeParameter ("element_size", "gsize"));
+		fun.add_parameter (new CCodeParameter ("array_length", "gint"));
+
+		push_function (fun);
+
+
+		ccode.add_declaration ("int", new CCodeVariableDeclarator ("i"));
+		ccode.add_declaration ("void*", new CCodeVariableDeclarator ("tmpbuf"));
+		var init_call = new CCodeFunctionCall (new CCodeIdentifier ("g_malloc"));
+		init_call.add_argument (new CCodeConstant ("element_size"));
+
+		ccode.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("tmpbuf"), init_call)));
+
+		ccode.add_declaration ("int", new CCodeVariableDeclarator ("newi"));
+
+		var cforinit = new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0"));
+		var cforcond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), new CCodeIdentifier ("array_length"));
+		var cforiter = new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("i"), new CCodeConstant ("1")));
+		ccode.open_for (cforinit, cforcond, cforiter);
+
+
+		var rand_call = new CCodeFunctionCall (new CCodeIdentifier ("g_random_int_range"));
+		rand_call.add_argument (new CCodeConstant ("0"));
+		rand_call.add_argument (new CCodeConstant ("array_length"));
+		ccode.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("newi"), rand_call)));
+
+		var totmp_call = new CCodeFunctionCall (new CCodeIdentifier ("memcpy"));
+		totmp_call.add_argument (new CCodeConstant ("tmpbuf"));
+		totmp_call.add_argument (new CCodeConstant ("(((char*) array) + (i*element_size))"));
+		totmp_call.add_argument (new CCodeConstant ("element_size"));
+		ccode.add_statement (new CCodeExpressionStatement (totmp_call));
+
+		var toarr_call = new CCodeFunctionCall (new CCodeIdentifier ("memcpy"));
+		toarr_call.add_argument (new CCodeConstant ("(((char*) array) + (i*element_size))"));
+		toarr_call.add_argument (new CCodeConstant ("(((char*) array) + (newi*element_size))"));
+		toarr_call.add_argument (new CCodeConstant ("element_size"));
+		ccode.add_statement (new CCodeExpressionStatement (toarr_call));
+
+		var tonew_call = new CCodeFunctionCall (new CCodeIdentifier ("memcpy"));
+		tonew_call.add_argument (new CCodeConstant ("(((char*) array) + (newi*element_size))"));
+		tonew_call.add_argument (new CCodeConstant ("tmpbuf"));
+		tonew_call.add_argument (new CCodeConstant ("element_size"));
+		ccode.add_statement (new CCodeExpressionStatement (tonew_call));
+
+		ccode.close ();
+		var free_call = new CCodeFunctionCall (new CCodeIdentifier ("g_free"));
+		free_call.add_argument (new CCodeConstant ("tmpbuf"));
+
+		ccode.add_statement (new CCodeExpressionStatement (free_call));
+
+		pop_function ();
+
+		cfile.add_function_declaration (fun);
+		cfile.add_function (fun);
+	}
+
 	public override void append_vala_array_length () {
 		var fun = new CCodeFunction ("_vala_array_length", "gint");
 		fun.modifiers = CCodeModifiers.STATIC;
@@ -506,8 +699,8 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
 			ccode.add_declaration ("int", new CCodeVariableDeclarator ("i"));
 
 			ccode.open_for (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0")),
-			                   new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), new CCodeIdentifier ("length")),
-			                   new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("i")));
+							   new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), new CCodeIdentifier ("length")),
+							   new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("i")));
 
 			ccode.add_assignment (new CCodeElementAccess (new CCodeIdentifier ("result"), new CCodeIdentifier ("i")), get_cvalue_ (copy_value (new GLibValue (array_type.element_type, new CCodeElementAccess (new CCodeIdentifier ("self"), new CCodeIdentifier ("i")), true), array_type)));
 			ccode.close ();
@@ -559,8 +752,8 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
 			ccode.add_declaration ("int", new CCodeVariableDeclarator ("i"));
 
 			ccode.open_for (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0")),
-			                   new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), get_ccodenode (array_type.length)),
-			                   new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("i")));
+							   new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), get_ccodenode (array_type.length)),
+							   new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("i")));
 
 
 			ccode.add_assignment (new CCodeElementAccess (new CCodeIdentifier ("dest"), new CCodeIdentifier ("i")), get_cvalue_ (copy_value (new GLibValue (array_type.element_type, new CCodeElementAccess (new CCodeIdentifier ("self"), new CCodeIdentifier ("i")), true), array_type)));
@@ -680,7 +873,7 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
 
 		var array_var = array.symbol_reference;
 		if (array_type.rank == 1 && array_var != null && array_var.is_internal_symbol ()
-		    && (array_var is LocalVariable || array_var is Field)) {
+			&& (array_var is LocalVariable || array_var is Field)) {
 			// valid array add
 		} else {
 			Report.error (assignment.source_reference, "Array concatenation not supported for public array variables and parameters");
@@ -728,7 +921,7 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
 			if (param.direction != ParameterDirection.IN) {
 				length_ctype = "%s*".printf (length_ctype);
 			}
-			
+
 			for (int dim = 1; dim <= array_type.rank; dim++) {
 				var cparam = new CCodeParameter (get_parameter_array_length_cname (param, dim), length_ctype);
 				cparam_map.set (get_param_pos (get_ccode_array_length_pos (param) + 0.01 * dim), cparam);
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 72aeed7..cfcb95b 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -2,6 +2,8 @@
  *
  * Copyright (C) 2006-2012  Jürg Billeter
  * Copyright (C) 2006-2008  Raffaele Sandrini
+ * Copyright (C) 2010  Jukka-Pekka Iivonen
+ * Copyright (C) 2016  Geert Jordaens
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,6 +22,8 @@
  * Author:
  * 	Jürg Billeter <j@bitron.ch>
  * 	Raffaele Sandrini <raffaele@sandrini.ch>
+ *  Jukka-Pekka Iivonen <jp0409@jippii.fi>
+ *  Geert Jordaens <geert.jordaens@telenet.be>
  */
 
 
@@ -235,7 +239,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 	public EmitContext base_finalize_context;
 	public EmitContext instance_init_context;
 	public EmitContext instance_finalize_context;
-	
+
 	public CCodeStruct param_spec_struct;
 	public CCodeStruct closure_struct;
 	public CCodeEnum prop_enum;
@@ -250,7 +254,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 	public Set<string> predefined_marshal_set;
 	/* (constant) hash table with all reserved identifiers in the generated code */
 	Set<string> reserved_identifiers;
-	
+
 	public int next_temp_var_id {
 		get { return emit_context.next_temp_var_id; }
 		set { emit_context.next_temp_var_id = value; }
@@ -325,13 +329,17 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 
 	public bool in_plugin = false;
 	public string module_init_param_name;
-	
+
 	public bool gvaluecollector_h_needed;
 	public bool requires_assert;
 	public bool requires_array_free;
 	public bool requires_array_move;
+	public bool requires_array_sort;
+	public bool requires_array_shuffle;
+	public bool requires_array_reverse;
 	public bool requires_array_length;
 	public bool requires_clear_mutex;
+	public HashSet<string> requires_compare_func;
 
 	public Set<string> wrappers;
 	Set<Symbol> generated_external_symbols;
@@ -661,6 +669,15 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 	public virtual void append_vala_array_move () {
 	}
 
+	public virtual void append_vala_array_sort () {
+	}
+
+	public virtual void append_vala_array_reverse () {
+	}
+
+	public virtual void append_vala_array_shuffle () {
+	}
+
 	public virtual void append_vala_array_length () {
 	}
 
@@ -702,17 +719,21 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 
 	public override void visit_source_file (SourceFile source_file) {
 		cfile = new CCodeFile ();
-		
+
 		user_marshal_set = new HashSet<string> (str_hash, str_equal);
-		
+
 		next_regex_id = 0;
-		
+
 		gvaluecollector_h_needed = false;
 		requires_assert = false;
 		requires_array_free = false;
 		requires_array_move = false;
+		requires_array_sort = false;
+		requires_array_reverse = false;
+		requires_array_shuffle = false;
 		requires_array_length = false;
 		requires_clear_mutex = false;
+		requires_compare_func = new HashSet<string> (str_hash, str_equal);
 
 		wrappers = new HashSet<string> (str_hash, str_equal);
 		generated_external_symbols = new HashSet<Symbol> ();
@@ -748,6 +769,15 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 		if (requires_array_move) {
 			append_vala_array_move ();
 		}
+		if (requires_array_sort) {
+			append_vala_array_sort ();
+		}
+		if (requires_array_reverse) {
+			append_vala_array_reverse ();
+		}
+		if (requires_array_shuffle) {
+			append_vala_array_shuffle ();
+		}
 		if (requires_array_length) {
 			append_vala_array_length ();
 		}
@@ -1095,13 +1125,13 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 				var rhs = get_cvalue (f.initializer);
 				if (!is_simple_struct_creation (f, f.initializer)) {
 					// otherwise handled in visit_object_creation_expression
-					
+
 					ccode.add_assignment (lhs, rhs);
-					
+
 					if (f.variable_type is ArrayType && get_ccode_array_length (f)) {
 						var array_type = (ArrayType) f.variable_type;
 						var field_value = get_field_cvalue (f, load_this_parameter ((TypeSymbol) f.parent_symbol));
-						
+
 						var glib_value = (GLibValue) f.initializer.target_value;
 						if (glib_value.array_length_cvalues != null) {
 							for (int dim = 1; dim <= array_type.rank; dim++) {
@@ -1112,14 +1142,14 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 							requires_array_length = true;
 							var len_call = new CCodeFunctionCall (new CCodeIdentifier ("_vala_array_length"));
 							len_call.add_argument (get_cvalue_ (glib_value));
-							
+
 							ccode.add_assignment (get_array_length_cvalue (field_value, 1), len_call);
 						} else {
 							for (int dim = 1; dim <= array_type.rank; dim++) {
 								ccode.add_assignment (get_array_length_cvalue (field_value, dim), new CCodeConstant ("-1"));
 							}
 						}
-						
+
 						if (array_type.rank == 1 && f.is_internal_symbol ()) {
 							var lhs_array_size = get_array_size_cvalue (field_value);
 							var rhs_array_len = get_array_length_cvalue (field_value, 1);
@@ -1136,7 +1166,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 
 				pop_context ();
 			}
-			
+
 			if (requires_destroy (f.variable_type) && instance_finalize_context != null) {
 				push_context (instance_finalize_context);
 				ccode.add_expression (destroy_field (f, load_this_parameter ((TypeSymbol) f.parent_symbol)));
@@ -2021,7 +2051,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 			var unref_fun = new CCodeFunction ("block%d_data_unref".printf (block_id), "void");
 			unref_fun.add_parameter (new CCodeParameter ("_userdata_", "void *"));
 			unref_fun.modifiers = CCodeModifiers.STATIC;
-			
+
 			push_function (unref_fun);
 
 			ccode.add_declaration (struct_name + "*", new CCodeVariableDeclarator ("_data%d_".printf (block_id), new CCodeCastExpression (new CCodeIdentifier ("_userdata_"), struct_name + "*")));
@@ -2548,7 +2578,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 		}
 
 		next_temp_var_id++;
-		
+
 		return local;
 	}
 
@@ -3080,7 +3110,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 					element_destroy_func_expression = get_destroy0_func_expression (type_arg);
 				}
 			}
-			
+
 			if (elements_require_free && element_destroy_func_expression is CCodeIdentifier) {
 				return new CCodeIdentifier (generate_collection_free_wrapper (type, (CCodeIdentifier) element_destroy_func_expression));
 			} else {
@@ -3334,7 +3364,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 		}
 
 		/* (foo == NULL ? NULL : foo = (unref (foo), NULL)) */
-		
+
 		/* can be simplified to
 		 * foo = (unref (foo), NULL)
 		 * if foo is of static type non-null
@@ -3396,10 +3426,10 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 				}
 			}
 		}
-		
+
 		ccomma.append_expression (ccall);
 		ccomma.append_expression (new CCodeConstant ("NULL"));
-		
+
 		var cassign = new CCodeAssignment (cvar, ccomma);
 
 		// g_free (NULL) is allowed
@@ -3411,7 +3441,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 
 		return new CCodeConditionalExpression (cisnull, new CCodeConstant ("NULL"), cassign);
 	}
-	
+
 	public override void visit_end_full_expression (Expression expr) {
 		/* expr is a full expression, i.e. an initializer, the
 		 * expression in an expression statement, the controlling
@@ -3436,7 +3466,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 
 		temp_ref_values.clear ();
 	}
-	
+
 	public void emit_temp_var (LocalVariable local) {
 		if (is_in_coroutine ()) {
 			closure_struct.add_field (get_ccode_name (local.variable_type), local.name);
@@ -3737,7 +3767,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 		var inner_node = ((MemberAccess)resource).inner;
 		var member = resource.symbol_reference;
 		var parent = (TypeSymbol)resource.symbol_reference.parent_symbol;
-		
+
 		if (member.is_instance_member ()) {
 			if (inner_node  == null) {
 				l = new CCodeIdentifier ("self");
@@ -3768,7 +3798,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 		}
 		return l;
 	}
-		
+
 	public override void visit_lock_statement (LockStatement stmt) {
 		var l = get_lock_expression (stmt, stmt.resource);
 
@@ -3777,13 +3807,13 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 
 		ccode.add_expression (fc);
 	}
-		
+
 	public override void visit_unlock_statement (UnlockStatement stmt) {
 		var l = get_lock_expression (stmt, stmt.resource);
-		
+
 		var fc = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_name (mutex_type.scope.lookup ("unlock"))));
 		fc.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, l));
-		
+
 		ccode.add_expression (fc);
 	}
 
@@ -4035,17 +4065,17 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 		// return previous value
 		expr.target_value = temp_value;
 	}
-	
+
 	private MemberAccess? find_property_access (Expression expr) {
 		if (!(expr is MemberAccess)) {
 			return null;
 		}
-		
+
 		var ma = (MemberAccess) expr;
 		if (ma.symbol_reference is Property) {
 			return ma;
 		}
-		
+
 		return null;
 	}
 
@@ -4189,7 +4219,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 		 * ref (expr)
 		 * if static type of expr is non-null
 		 */
-		 
+
 		var dupexpr = get_dup_func_expression (type, node.source_reference);
 
 		if (dupexpr == null) {
@@ -4237,7 +4267,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 		if (!(type is ArrayType) && get_non_null (value) && !is_ref_function_void (type)) {
 			// expression is non-null
 			ccall.add_argument (cexpr);
-			
+
 			return store_temp_value (new GLibValue (type, ccall), node);
 		} else {
 			var cnotnull = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, cexpr, new CCodeConstant ("NULL"));
@@ -4647,14 +4677,14 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 					cexpr = handle_struct_argument (null, arg, cexpr);
 					arg_pos = get_param_pos (i, ellipsis);
 				}
-			
+
 				carg_map.set (arg_pos, cexpr);
 
 				i++;
 			}
 			if (params_it.next ()) {
 				var param = params_it.get ();
-				
+
 				/* if there are more parameters than arguments,
 				 * the additional parameter is an ellipsis parameter
 				 * otherwise there is a bug in the semantic analyzer
@@ -5153,7 +5183,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 			}
 		}
 	}
-	
+
 	public override void visit_named_argument (NamedArgument expr) {
 		set_cvalue (expr, get_cvalue (expr.inner));
 	}
@@ -5196,7 +5226,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 			}
 		} else {
 			ccode.add_assignment (get_cvalue (expr.inner), new CCodeConstant ("NULL"));
-		}			
+		}
 	}
 
 	public override void visit_binary_expression (BinaryExpression expr) {
@@ -5292,7 +5322,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 		} else {
 			assert_not_reached ();
 		}
-		
+
 		if (expr.operator == BinaryOperator.EQUALITY ||
 		    expr.operator == BinaryOperator.INEQUALITY) {
 			var left_type = expr.left.target_type;
@@ -5745,7 +5775,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 				array_needs_copy = requires_copy (target_array.element_type);
 			}
 		}
-		
+
 		if (!gvalue_boxing && !gvariant_boxing && target_type.value_owned && (!type.value_owned || boxing || unboxing || array_needs_copy) && requires_copy (target_type) && !(type is NullType)) {
 			// need to copy value
 			var copy = (GLibValue) copy_value (result, node);
@@ -5798,7 +5828,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 				var base_class = (Class) prop.base_property.parent_symbol;
 				var vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (get_ccode_upper_case_name (base_class, null))));
 				vcast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (get_ccode_lower_case_name (current_class, null))));
-				
+
 				var ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, "set_%s".printf (prop.name)));
 				ccall.add_argument ((CCodeExpression) get_ccodenode (instance));
 				ccall.add_argument (get_cvalue_ (value));
@@ -5818,7 +5848,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 		}
 
 		var set_func = "g_object_set";
-		
+
 		var base_property = prop;
 		if (!get_ccode_no_accessor_method (prop)) {
 			if (prop.base_property != null) {
@@ -5842,7 +5872,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 				}
 			}
 		}
-		
+
 		var ccall = new CCodeFunctionCall (new CCodeIdentifier (set_func));
 
 		if (prop.binding == MemberBinding.INSTANCE) {
@@ -5961,7 +5991,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 		}
 		return null;
 	}
-	
+
 	private void create_property_type_check_statement (Property prop, bool check_return_type, TypeSymbol t, bool non_null, string var_name) {
 		if (check_return_type) {
 			create_type_check_statement (prop, prop.property_type, t, non_null, var_name);
diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala
index 4f846b6..b450158 100644
--- a/codegen/valaccodememberaccessmodule.vala
+++ b/codegen/valaccodememberaccessmodule.vala
@@ -2,6 +2,8 @@
  *
  * Copyright (C) 2006-2010  Jürg Billeter
  * Copyright (C) 2006-2008  Raffaele Sandrini
+ * Copyright (C) 2010  Jukka-Pekka Iivonen
+ * Copyright (C) 2016  Geert Jordaens
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,12 +22,14 @@
  * Author:
  * 	Jürg Billeter <j@bitron.ch>
  *	Raffaele Sandrini <raffaele@sandrini.ch>
+ *  Jukka-Pekka Iivonen <jp0409@jippii.fi>
+ *  Geert Jordaens <geert.jordaens@telenet.be>
  */
 
 public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
 	public override void visit_member_access (MemberAccess expr) {
 		CCodeExpression pub_inst = null;
-	
+
 		if (expr.inner != null) {
 			pub_inst = get_cvalue (expr.inner);
 		}
@@ -36,7 +40,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
 		if (expr.symbol_reference is Method) {
 			var m = (Method) expr.symbol_reference;
 
-			if (!(m is DynamicMethod || m is ArrayMoveMethod || m is ArrayResizeMethod)) {
+			if (!(m is DynamicMethod || m is ArrayMoveMethod || m is ArrayResizeMethod || m is ArraySortMethod || m is ArrayReverseMethod || m is ArrayShuffleMethod)) {
 				generate_method_declaration (m, cfile);
 
 				if (!m.external && m.external_package) {
@@ -53,7 +57,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
 					var base_class = (Class) m.base_method.parent_symbol;
 					var vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (get_ccode_upper_case_name (base_class, null))));
 					vcast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (get_ccode_lower_case_name (current_class, null))));
-					
+
 					set_cvalue (expr, new CCodeMemberAccess.pointer (vcast, get_ccode_vfunc_name (m)));
 					return;
 				} else if (m.base_interface_method != null) {
@@ -179,7 +183,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
 					var base_class = (Class) base_prop.parent_symbol;
 					var vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (get_ccode_upper_case_name (base_class, null))));
 					vcast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (get_ccode_lower_case_name (current_class, null))));
-					
+
 					var ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, "get_%s".printf (prop.name)));
 					ccall.add_argument (get_cvalue (expr.inner));
 					set_cvalue (expr, ccall);
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index 8e923ea..b13792d 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -2,6 +2,8 @@
  *
  * Copyright (C) 2006-2010  Jürg Billeter
  * Copyright (C) 2006-2008  Raffaele Sandrini
+ * Copyright (C) 2010  Jukka-Pekka Iivonen
+ * Copyright (C) 2016  Geert Jordaens
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,8 +20,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
  *
  * Author:
- * 	Jürg Billeter <j@bitron.ch>
- *	Raffaele Sandrini <raffaele@sandrini.ch>
+ *  Jürg Billeter <j@bitron.ch>
+ *  Raffaele Sandrini <raffaele@sandrini.ch>
+ *  Jukka-Pekka Iivonen <jp0409@jippii.fi>
+ *  Geert Jordaens <geert.jordaens@telenet.be>
  */
 
 using GLib;
@@ -35,12 +39,12 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 		Method m = null;
 		Delegate deleg = null;
 		List<Parameter> params;
-		
+
 		var ma = expr.call as MemberAccess;
-		
+
 		var itype = expr.call.value_type;
 		params = itype.get_parameters ();
-		
+
 		if (itype is MethodType) {
 			assert (ma != null);
 			m = ((MethodType) itype).method_symbol;
@@ -188,7 +192,13 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 			in_arg_map.set (get_param_pos (0), new CCodeIdentifier (get_ccode_name (array_type.element_type)));
 		} else if (m is ArrayMoveMethod) {
 			requires_array_move = true;
-		}
+		} else if (m is ArraySortMethod) {
+			requires_array_sort = true;
+		} else if (m is ArrayReverseMethod) {
+			requires_array_reverse = true;
+		} else if (m is ArrayShuffleMethod) {
+			requires_array_shuffle = true;
+ 		}
 
 		CCodeExpression instance = null;
 		if (m != null && m.is_async_callback) {
@@ -223,7 +233,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 		} else if (m != null && m.binding == MemberBinding.CLASS) {
 			var cl = (Class) m.parent_symbol;
 			var cast = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_upper_case_name (cl, null) + "_CLASS"));
-			
+
 			CCodeExpression klass;
 			if (ma.inner == null) {
 				if (get_this_type () == null) {
@@ -271,6 +281,92 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 			var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
 			csizeof.add_argument (new CCodeIdentifier (get_ccode_name (array_type.element_type)));
 			in_arg_map.set (get_param_pos (0.1), csizeof);
+		} else if (m is ArraySortMethod) {
+			var array_type = (ArrayType) ma.inner.value_type;
+
+			CCodeExpression lenexpr = get_array_length_cexpression (ma.inner, 1);
+			for (int dim=2; dim<=array_type.rank; dim++) {
+				lenexpr = new CCodeBinaryExpression (CCodeBinaryOperator.MUL, lenexpr, get_array_length_cexpression (ma.inner, dim));
+			}
+			in_arg_map.set (get_param_pos (0.1), lenexpr);
+			var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
+			csizeof.add_argument (new CCodeIdentifier (get_ccode_name (array_type.element_type)));
+			in_arg_map.set (get_param_pos (0.2), csizeof);
+
+			string? comp_func = null;
+			string func_type_cast ="(GCompareDataFunc)";
+
+			switch (get_ccode_name (array_type.element_type)) {
+			case "float":
+				comp_func = "gfloat";
+				requires_compare_func.add (comp_func);
+				break;
+			case "double":
+				comp_func = "gdouble";
+				requires_compare_func.add (comp_func);
+				break;
+			case "gunichar":
+			case "guchar":
+			case "guint8":
+			case "gint16":
+			case "guint16":
+			case "gint32":
+			case "guint32":
+			case "gint64":
+			case "guint64":
+			case "gsize":
+			case "glong":
+			case "gulong":
+			case "gchar":
+			case "gshort":
+			case "gushort":
+			case "gint":
+			case "guint":
+			case "gint8":
+				comp_func = get_ccode_name (array_type.element_type);
+				requires_compare_func.add (comp_func);
+				break;
+			case "char*":
+			case "gchar*":
+				comp_func = "string";
+				requires_compare_func.add (comp_func);
+				break;
+			case "gboolean":
+				comp_func = "gint";
+				requires_compare_func.add (comp_func);
+				break;
+			default:
+				Symbol sym = array_type.element_type.get_member ("compare");
+				assert (sym != null);
+				comp_func = get_ccode_lower_case_name(array_type.element_type);
+				requires_compare_func.add (get_ccode_name (array_type.element_type));
+				break;
+			}
+			var comp_func_const = new CCodeConstant ("%s _vala_compare_%s".printf (func_type_cast, comp_func));
+			in_arg_map.set (get_param_pos (0.3), comp_func_const);
+		} else if (m is ArrayReverseMethod) {
+			var array_type = (ArrayType) ma.inner.value_type;
+			var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
+			csizeof.add_argument (new CCodeIdentifier (get_ccode_name (array_type.element_type)));
+			in_arg_map.set (get_param_pos (0.1), csizeof);
+
+			CCodeExpression lenexpr = get_array_length_cexpression (ma.inner, 1);
+			for (int dim=2; dim<=array_type.rank; dim++) {
+				lenexpr = new CCodeBinaryExpression (CCodeBinaryOperator.MUL, lenexpr, get_array_length_cexpression (ma.inner, dim));
+			}
+			in_arg_map.set (get_param_pos (0.2), lenexpr);
+		} else if (m is ArrayShuffleMethod) {
+			var array_type = (ArrayType) ma.inner.value_type;
+			var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
+			csizeof.add_argument (new CCodeIdentifier (get_ccode_name (array_type.element_type)));
+			in_arg_map.set (get_param_pos (0.1), csizeof);
+
+			CCodeExpression lenexpr = get_array_length_cexpression (ma.inner, 1);
+			for (int dim=2; dim<=array_type.rank; dim++) {
+				lenexpr = new CCodeBinaryExpression (CCodeBinaryOperator.MUL, lenexpr, get_array_length_cexpression (ma.inner, dim));
+			}
+			in_arg_map.set (get_param_pos (0.2), lenexpr);
+
 		} else if (m is DynamicMethod) {
 			m.clear_parameters ();
 			int param_nr = 1;
@@ -324,7 +420,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 		}
 
 		bool ellipsis = false;
-		
+
 		int i = 1;
 		int arg_pos;
 		Iterator<Parameter> params_it = params.iterator ();
@@ -648,7 +744,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 		}
 
 		// append C arguments in the right order
-		
+
 		int last_pos;
 		int min_pos;
 
@@ -759,7 +855,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 			var array_var = ma.inner.symbol_reference;
 			var array_local = array_var as LocalVariable;
 			if (array_var != null && array_var.is_internal_symbol ()
-			    && ((array_var is LocalVariable && !array_local.captured) || array_var is Field)) {
+				&& ((array_var is LocalVariable && !array_local.captured) || array_var is Field)) {
 				ccode.add_assignment (get_array_size_cvalue (ma.inner.target_value), temp_ref);
 			}
 
@@ -776,7 +872,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 			if (expr.formal_value_type is GenericType && !(expr.value_type is GenericType)) {
 				var st = expr.formal_value_type.type_parameter.parent_symbol.parent_symbol as Struct;
 				if (expr.formal_value_type.type_parameter.parent_symbol == garray_type ||
-				    (st != null && get_ccode_name (st) == "va_list")) {
+					(st != null && get_ccode_name (st) == "va_list")) {
 					// GArray and va_list don't use pointer-based generics
 					// above logic copied from visit_expression ()
 					// TODO avoid code duplication
@@ -801,7 +897,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 		params_it = params.iterator ();
 		foreach (Expression arg in expr.get_argument_list ()) {
 			Parameter param = null;
-			
+
 			if (params_it.next ()) {
 				param = params_it.get ();
 				if (param.params_array || param.ellipsis) {
@@ -828,7 +924,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 				requires_array_length = true;
 				var len_call = new CCodeFunctionCall (new CCodeIdentifier ("_vala_array_length"));
 				len_call.add_argument (get_cvalue_ (unary.inner.target_value));
-				
+
 				ccode.add_assignment (get_array_length_cvalue (unary.inner.target_value, 1), len_call);
 			}
 		}
@@ -875,4 +971,3 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 		return to_string_func;
 	}
 }
-
diff --git a/tests/arrays/bug530450.vala b/tests/arrays/bug530450.vala
new file mode 100644
index 0000000..5c24d6e
--- /dev/null
+++ b/tests/arrays/bug530450.vala
@@ -0,0 +1,125 @@
+
+
+public class Currency : Object {
+	public string symbol;
+	public double usd_rate;
+	public Currency (string sym, double usd_rate)
+	{
+		this.symbol = sym;
+		this.usd_rate = usd_rate;
+	}
+}
+
+public class Price : Object {
+	public double price;
+	public Currency currency;
+	public Price (double price, Currency currency)
+	{
+		this.price = price;
+		this.currency = currency;
+	}
+	public int compare (Price p)
+	{
+		double v1 = price / currency.usd_rate;
+		double v2 = p.price / p.currency.usd_rate;
+		if (v1 == v2) {
+			return 0;
+		} else if (v1 < v2) {
+			return -1;
+		} else {
+			return 1;
+		}
+	}
+	public string to_string ()
+	{
+		return "%g %s".printf (price, currency.symbol);
+	}
+}
+
+
+static void main (string[] args)
+{
+	var cities = new string[] { "Helsinki", "Stockholm", "Oslo", "London", "Paris", "Berlin", "Amsterdam", "Madrid" };
+	print ("cities:\n");
+	print ("------\n\n");
+	cities.sort ();
+	foreach (string city in cities) {
+		print ("%s\t", city);
+	}
+	print ("\n");
+
+	cities.reverse ();
+	foreach (string city in cities) {
+		print ("%s\t", city);
+	}
+	print ("\n");
+
+	cities.shuffle ();
+	foreach (string city in cities) {
+		print ("%s\t", city);
+	}
+	print ("\n");
+
+	var usd = new Currency ("USD", 1.0000);
+	var eur = new Currency ("EUR", 0.7690);
+	var jpy = new Currency ("JPY", 94.3650);
+
+	var prices = new Price[] {
+		new Price (26.39, usd),
+		new Price (16.50, usd),
+		new Price (12.99, eur),
+		new Price (1919.00, jpy)
+	};
+	print ("prices:\n");
+	print ("------\n\n");
+	foreach (Price price in prices) {
+		print ("%s\t", price.to_string ());
+	}
+	print ("\n");
+
+	prices.sort ();
+	foreach (Price price in prices) {
+		print ("%s\t", price.to_string ());
+	}
+	print ("\n");
+
+	prices.reverse ();
+	foreach (Price price in prices) {
+		print ("%s\t", price.to_string ());
+	}
+	print ("\n");
+
+	prices.shuffle ();
+	foreach (Price price in prices) {
+		print ("%s\t", price.to_string ());
+	}
+	print ("\n");
+
+	var integers = new int[] { 1,7,2,6,3,8,4,5,9 };
+
+	print ("integers:\n");
+	print ("------\n\n");
+	foreach (int i in integers) {
+		print ("%d\t", i);
+	}
+	print ("\n");
+
+	integers.sort ();
+	foreach (int i in integers) {
+		print ("%d\t", i);
+	}
+	print ("\n");
+
+	integers.reverse ();
+	foreach (int i in integers) {
+		print ("%d\t", i);
+	}
+	print ("\n");
+
+	integers.shuffle ();
+	foreach (int i in integers) {
+		print ("%d\t", i);
+	}
+	print ("\n");
+
+}
diff --git a/vala/Makefile.am b/vala/Makefile.am
index bd16142..a2cff77 100644
--- a/vala/Makefile.am
+++ b/vala/Makefile.am
@@ -21,7 +21,10 @@ libvalacore_la_VALASOURCES = \
 	valaarraycreationexpression.vala \
 	valaarraylengthfield.vala \
 	valaarraymovemethod.vala \
+	valaarrayshufflemethod.vala \
+	valaarraysortmethod.vala \
 	valaarrayresizemethod.vala \
+	valaarrayreversemethod.vala \
 	valaarraytype.vala \
 	valaassignment.vala \
 	valaattribute.vala \
diff --git a/vala/valaarrayreversemethod.vala b/vala/valaarrayreversemethod.vala
new file mode 100644
index 0000000..c817fdb
--- /dev/null
+++ b/vala/valaarrayreversemethod.vala
@@ -0,0 +1,40 @@
+/* valaarrayreversemethod.vala
+ *
+ * Copyright (C) 2010  Jukka-Pekka Iivonen
+ * Copyright (C) 2016  Geert Jordaens
+ *
+ * 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:
+ * 	Jukka-Pekka Iivonen <jp0409@jippii.fi>
+ *  Geert Jordaens <geert.jordaens@telenet.be>  
+ */
+
+using GLib;
+
+/**
+ * Represents the Array.reverse method.
+ */
+public class Vala.ArrayReverseMethod : Method {
+	/**
+	 * Creates a new array reverse method.
+	 *
+	 * @return newly created method
+	 */
+	public ArrayReverseMethod (SourceReference source_reference) {
+		base ("reverse", new VoidType (), source_reference);
+		external = true;
+	}
+}
diff --git a/vala/valaarrayshufflemethod.vala b/vala/valaarrayshufflemethod.vala
new file mode 100644
index 0000000..ec03636
--- /dev/null
+++ b/vala/valaarrayshufflemethod.vala
@@ -0,0 +1,40 @@
+/* valaarrayshufflemethod.vala
+ *
+ * Copyright (C) 2010  Jukka-Pekka Iivonen
+ * Copyright (C) 2016  Geert Jordaens
+ *
+ * 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:
+ * 	Jukka-Pekka Iivonen <jp0409@jippii.fi>
+ *  Geert Jordaens <geert.jordaens@telenet.be>  
+ */
+
+using GLib;
+
+/**
+ * Represents the Array.shuffle method.
+ */
+public class Vala.ArrayShuffleMethod : Method {
+	/**
+	 * Creates a new array shuffle method.
+	 *
+	 * @return newly created method
+	 */
+	public ArrayShuffleMethod (SourceReference source_reference) {
+		base ("shuffle", new VoidType (), source_reference);
+		external = true;
+	}
+}
diff --git a/vala/valaarraysortmethod.vala b/vala/valaarraysortmethod.vala
new file mode 100644
index 0000000..959c241
--- /dev/null
+++ b/vala/valaarraysortmethod.vala
@@ -0,0 +1,40 @@
+/* valaarraysortmethod.vala
+ *
+ * Copyright (C) 2010  Jukka-Pekka Iivonen
+ * Copyright (C) 2016  Geert Jordaens
+ *
+ * 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:
+ * 	Jukka-Pekka Iivonen <jp0409@jippii.fi>
+ *  Geert Jordaens <geert.jordaens@telenet.be>  
+ */
+
+using GLib;
+
+/**
+ * Represents the Array.sort method.
+ */
+public class Vala.ArraySortMethod : Method {
+	/**
+	 * Creates a new array sort method.
+	 *
+	 * @return newly created method
+	 */
+	public ArraySortMethod (SourceReference source_reference) {
+		base ("sort", new VoidType (), source_reference);
+		external = true;
+	}
+}
diff --git a/vala/valaarraytype.vala b/vala/valaarraytype.vala
index d993e3c..6068286 100644
--- a/vala/valaarraytype.vala
+++ b/vala/valaarraytype.vala
@@ -1,6 +1,7 @@
 /* valaarraytype.vala
  *
  * Copyright (C) 2007-2012  Jürg Billeter
+ * Copyright (C) 2016  Geert Jordaens
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,6 +19,7 @@
  *
  * Author:
  * 	Jürg Billeter <j@bitron.ch>
+ *  Geert Jordaens <geert.jordaens@telenet.be>
  */
 
 using GLib;
@@ -67,6 +69,9 @@ public class Vala.ArrayType : ReferenceType {
 	private ArrayLengthField length_field;
 	private ArrayResizeMethod resize_method;
 	private ArrayMoveMethod move_method;
+    private ArraySortMethod sort_method;
+	private ArrayReverseMethod reverse_method;
+	private ArrayShuffleMethod shuffle_method;
 
 	public ArrayType (DataType element_type, int rank, SourceReference? source_reference) {
 		this.element_type = element_type;
@@ -84,6 +89,12 @@ public class Vala.ArrayType : ReferenceType {
 				return null;
 			}
 			return get_resize_method ();
+		} else if (member_name == "sort") {
+			return get_sort_method ();
+		} else if (member_name == "reverse") {
+			return get_reverse_method ();
+		} else if (member_name == "shuffle") {
+			return get_shuffle_method ();
 		}
 		return null;
 	}
@@ -115,12 +126,12 @@ public class Vala.ArrayType : ReferenceType {
 			resize_method.access = SymbolAccessibility.PUBLIC;
 
 			resize_method.set_attribute_string ("CCode", "cname", "g_renew");
-			
+
 			var root_symbol = source_reference.file.context.root;
 			var int_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int"));
 
 			resize_method.add_parameter (new Parameter ("length", int_type));
-			
+
 			resize_method.returns_modified_pointer = true;
 		}
 		return resize_method;
@@ -145,6 +156,43 @@ public class Vala.ArrayType : ReferenceType {
 		return move_method;
 	}
 
+	private ArraySortMethod get_sort_method () {
+		if (sort_method == null) {
+			sort_method = new ArraySortMethod (source_reference);
+
+			sort_method.return_type = new VoidType ();
+			sort_method.access = SymbolAccessibility.PUBLIC;
+
+			sort_method.set_attribute_string ("CCode", "cname", "_vala_array_sort");
+		}
+		return sort_method;
+	}
+
+	private ArrayReverseMethod get_reverse_method () {
+		if (reverse_method == null) {
+			reverse_method = new ArrayReverseMethod (source_reference);
+
+			reverse_method.return_type = new VoidType ();
+			reverse_method.access = SymbolAccessibility.PUBLIC;
+
+			reverse_method.set_attribute_string ("CCode", "cname", "_vala_array_reverse");
+		}
+		return reverse_method;
+	}
+
+	private ArrayShuffleMethod get_shuffle_method () {
+		if (shuffle_method == null) {
+			shuffle_method = new ArrayShuffleMethod (source_reference);
+
+			shuffle_method.return_type = new VoidType ();
+			shuffle_method.access = SymbolAccessibility.PUBLIC;
+
+			shuffle_method.set_attribute_string ("CCode", "cname", "_vala_array_shuffle");
+		}
+		return shuffle_method;
+	}
+
+
 	public override DataType copy () {
 		var result = new ArrayType (element_type.copy (), rank, source_reference);
 		result.value_owned = value_owned;
@@ -169,7 +217,7 @@ public class Vala.ArrayType : ReferenceType {
 		if (element_type.is_weak () && !(parent_node is Constant)) {
 			elem_str = "(unowned %s)".printf (elem_str);
 		}
-		
+
 		if (!fixed_length) {
 			return "%s[%s]%s".printf (elem_str, string.nfill (rank - 1, ','), nullable ? "?" : "");
 		} else {
