diff --git a/Makefile b/Makefile
index bbd0b7cc259903c9edc70ce215d10be2be960393..5c57efa657b79be0a75aaab170844c3985483c96 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ BASE=rules_shipping
 BASE_ADV=rules_shipping_advanced
 PLUGINTYPE=vmshipment
 ZIPBASE=opentools_vm2
-VERSION=3.97
+VERSION=4.0
 
 PLUGINFILES=$(BASE).php $(BASE)_base.php $(BASE).script.php $(BASE).xml index.html
 PLUGINFILES_ADV=$(BASE_ADV).php $(BASE)_base.php $(BASE_ADV).script.php $(BASE_ADV).xml index.html
diff --git a/language/de-DE/de-DE.plg_vmshipment_rules_shipping.ini b/language/de-DE/de-DE.plg_vmshipment_rules_shipping.ini
index 05b96444bf88182e741fbc08f85ce4b431d86d4d..ec6c6ec1355c692ce595d6ae681c57e580f301a0 100644
--- a/language/de-DE/de-DE.plg_vmshipment_rules_shipping.ini
+++ b/language/de-DE/de-DE.plg_vmshipment_rules_shipping.ini
@@ -44,4 +44,10 @@ VMSHIPMENT_RULES_EVALUATE_SYNTAXERROR="Syntax error during evaluation, RPN is no
 VMSHIPMENT_RULES_EVALUATE_UNKNOWN_OPERATOR="Unknown operator '%s' encountered during evaluation of rule '%s'."
 VMSHIPMENT_RULES_EVALUATE_UNKNOWN_ERROR="Unknown error occurred during evaluation of rule '%s'."
 VMSHIPMENT_RULES_EVALUATE_ASSIGNMENT_TOPLEVEL="Assignments are not allows inside expressions (rule given was '%s')"
-VMSHIPMENT_RULES_EVALUATE_UNKNOWN_VALUE="Evaluation yields unknown value while evaluating rule part '%s'."
\ No newline at end of file
+VMSHIPMENT_RULES_EVALUATE_UNKNOWN_VALUE="Evaluation yields unknown value while evaluating rule part '%s'."
+
+VMSHIPMENT_RULES_EVALUATE_LISTFUNCTION_ARGS="List function '%s' requires all arguments to be lists. (Full rule: '%s')" 
+VMSHIPMENT_RULES_EVALUATE_LISTFUNCTION_CONTAIN_ARGS="List function '%s' requires the first argument to be lists. (Full rule: '%s')" 
+VMSHIPMENT_RULES_EVALUATE_LISTFUNCTION_UNKNOWN="Unknown list function '%s' encountered. (Full rule: '%s')" 
+
+VMSHIPMENT_RULES_NOSHIPPING_MESSAGE="%s"
diff --git a/language/en-GB/en-GB.plg_vmshipment_rules_shipping.ini b/language/en-GB/en-GB.plg_vmshipment_rules_shipping.ini
index 1c19d7bb062565f0d2c43b21aafa1a1a91ee85e1..ee5381b1597d193dc3999ab9d4e5fb04f3649bb9 100755
--- a/language/en-GB/en-GB.plg_vmshipment_rules_shipping.ini
+++ b/language/en-GB/en-GB.plg_vmshipment_rules_shipping.ini
@@ -55,6 +55,7 @@ VMSHIPMENT_RULES_EVALUATE_ASSIGNMENT_TOPLEVEL="Assignments are not allows inside
 VMSHIPMENT_RULES_EVALUATE_UNKNOWN_VALUE="Evaluation yields unknown value while evaluating rule part '%s'."
 
 VMSHIPMENT_RULES_EVALUATE_LISTFUNCTION_ARGS="List function '%s' requires all arguments to be lists. (Full rule: '%s')" 
+VMSHIPMENT_RULES_EVALUATE_LISTFUNCTION_CONTAIN_ARGS="List function '%s' requires the first argument to be lists. (Full rule: '%s')" 
 VMSHIPMENT_RULES_EVALUATE_LISTFUNCTION_UNKNOWN="Unknown list function '%s' encountered. (Full rule: '%s')" 
 
 VMSHIPMENT_RULES_NOSHIPPING_MESSAGE="%s"
diff --git a/releases/plg_opentools_vm2_rules_shipping_advanced_v4.0.zip b/releases/plg_opentools_vm2_rules_shipping_advanced_v4.0.zip
new file mode 100644
index 0000000000000000000000000000000000000000..1b968da339511be20e2c2fa4ff0754c82d8b1c94
Binary files /dev/null and b/releases/plg_opentools_vm2_rules_shipping_advanced_v4.0.zip differ
diff --git a/releases/plg_opentools_vm2_rules_shipping_v4.0.zip b/releases/plg_opentools_vm2_rules_shipping_v4.0.zip
new file mode 100644
index 0000000000000000000000000000000000000000..38afbe1bebd6dd2f776b9447d5f5356658320d6a
Binary files /dev/null and b/releases/plg_opentools_vm2_rules_shipping_v4.0.zip differ
diff --git a/rules_shipping.xml b/rules_shipping.xml
index eace41a31a331dd78f465fd772a080a6da64549e..1c31e6e34ede7273475283ea2f210c27e503d1f9 100644
--- a/rules_shipping.xml
+++ b/rules_shipping.xml
@@ -6,7 +6,7 @@
     <authorUrl>http://www.open-tools.net</authorUrl>
     <copyright>Copyright (C) 2013, Reinhold Kainhofer</copyright>
     <license>GPL v3+</license>
-    <version>3.97</version>
+    <version>4.0</version>
     <description>VMSHIPMENT_RULES_DESC</description>
     <files>
 	<filename plugin="rules_shipping">rules_shipping.php</filename>
diff --git a/rules_shipping_advanced.xml b/rules_shipping_advanced.xml
index ee0a926fa629aca90f680a32760f25079c374f0a..058b612b87b831ea845935148d755795c412e7f6 100644
--- a/rules_shipping_advanced.xml
+++ b/rules_shipping_advanced.xml
@@ -6,7 +6,7 @@
     <authorUrl>http://www.open-tools.net</authorUrl>
     <copyright>Copyright (C) 2013, Reinhold Kainhofer</copyright>
     <license>GPL v3+</license>
-    <version>3.97</version>
+    <version>4.0</version>
     <description>VMSHIPMENT_RULES_ADV_DESC</description>
     <files>
 	<filename plugin="rules_shipping_advanced">rules_shipping_advanced.php</filename>
diff --git a/rules_shipping_base.php b/rules_shipping_base.php
index 34a1f98feb62b967a27456867c71d92a026baab5..08a2635b330960d5109e87be9ca7bd22b8e82e79 100644
--- a/rules_shipping_base.php
+++ b/rules_shipping_base.php
@@ -29,8 +29,6 @@ if (class_exists ('plgVmShipmentRules_Shipping_Base')) {
 	return;
 }
 
-// Keep track of warning messages, so we don't print them twice:
-$printed_warnings = array();
 
 function is_equal($a, $b) {
 	if (is_array($a) && is_array($b)) {
@@ -70,12 +68,14 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin {
 	}
 	
 	public function printWarning($message) {
+		// Keep track of warning messages, so we don't print them twice:
 		global $printed_warnings;
+		if (!isset($printed_warnings))
+			$printed_warnings = array();
 		if (!in_array($message, $printed_warnings)) {
 			JFactory::getApplication()->enqueueMessage($message, 'error');
 			$printed_warnings[] = $message;
 		}
-		
 	}
 
 	/**
@@ -619,6 +619,9 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin {
 		$cartvals = array_merge ($cartvals, $this->getOrderDimensions ($cart, $method->length_unit));
 		// Let child classes update the $cartvals array, or add new variables
 		$this->addCustomCartValues($cart, $cart_prices, $cartvals);
+		// Add the whole list of cart value to the values, so we can print them out as a debug statement!
+		$cartvals['values_debug'] = print_r($cartvals,1);
+		$cartvals['values'] = $cartvals;
 // JFactory::getApplication()->enqueueMessage("<pre>cart values: ".print_r($cartvals,1)."</pre>", 'error');
 		return $cartvals;
 	}
@@ -880,6 +883,34 @@ class ShippingRule {
 		}
 	}
 	
+	function evaluateListContainmentFunction ($function, $args) {
+		# First make sure that the first argument is a list:
+		if (!is_array($args[0])) {
+			JFactory::getApplication()->enqueueMessage(JText::sprintf('VMSHIPMENT_RULES_EVALUATE_LISTFUNCTION_CONTAIN_ARGS', $function, $this->rulestring), 'error');
+			return false;
+		}
+		// Extract the array from the args, the $args varialbe will now only contain the elements to be checked:
+		$array = array_shift($args);
+		switch ($function) {
+			case "contains_any": 
+					foreach ($args as $a) { 
+						if (in_array($a, $array)) 
+							return true; 
+					}
+					return false;
+			
+			case "contains_all":
+					foreach ($args as $a) { 
+						if (!in_array($a, $array)) 
+							return false; 
+					}
+					return true;
+			default: 
+				JFactory::getApplication()->enqueueMessage(JText::sprintf('VMSHIPMENT_RULES_EVALUATE_LISTFUNCTION_UNKNOWN', $function, $this->rulestring), 'error');
+				return false;
+		}
+	}
+	
 	function evaluateFunction ($function, $args) {
 		$func = strtolower($function);
 		// Functions with no argument:
@@ -920,16 +951,28 @@ class ShippingRule {
 				case "substring": return substr($args[0], $args[1]-1, $args[2]); break;
 			}
 		}
-		// List functions
-		if (in_array($func, array("length", "complement", "issubset", "contains", "union", "join", "intersection", "list_equal"))) {
-			return $this->evaluateListFunction ($func, $args);
-		}
 		// Functions with variable number of args
 		switch ($func) {
-			case "max": return max($args); break;
-			case "min": return min($args); break;
+			case "max": 
+					return max($args); break;
+			case "min": 
+					return min($args); break;
 			case "list": 
-			case "array": return $args; break;
+			case "array": 
+					return $args; break;
+			// List functions:
+		    case "length":
+		    case "complement":
+		    case "issubset":
+		    case "contains":
+		    case "union":
+		    case "join":
+		    case "intersection":
+		    case "list_equal":
+					return $this->evaluateListFunction ($func, $args); break;
+			case "contains_any": 
+			case "contains_all":
+					return $this->evaluateListContainmentFunction($func, $args); break;
 		}
 		// No known function matches => print an error, return 0
 		JFactory::getApplication()->enqueueMessage(JText::sprintf('VMSHIPMENT_RULES_EVALUATE_UNKNOWN_FUNCTION', $function, $this->rulestring), 'error');