diff --git a/Makefile b/Makefile
index f11c60075ebbdb4d6a26e43de0651e0cd69ab5e0..f5a38f7d175bd01f46a0e06f83fa2614e5fc9a77 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 BASE=rules_shipping
 BASE_ADV=rules_shipping_advanced
 PLUGINTYPE=vmshipment
-VERSION=2.1.3
+VERSION=2.2.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/elements/vmlengthunit.php b/elements/vmlengthunit.php
new file mode 100644
index 0000000000000000000000000000000000000000..b3186022ce52f315e10ea8618054547da60d5ae9
--- /dev/null
+++ b/elements/vmlengthunit.php
@@ -0,0 +1,64 @@
+<?php
+defined('_JEXEC') or die();
+/**
+ *
+ * @package	VirtueMart
+ * @subpackage Plugins  - Elements
+ * @author Valérie Isaksen, Reinhold Kainhofer
+ * @link http://www.virtuemart.net
+ * @copyright Copyright (c) 2004 - 2011 VirtueMart Team. All rights reserved.
+ * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
+ * VirtueMart is free software. This version may have been modified pursuant
+ * to the GNU General Public License, and as distributed it includes or
+ * is derivative of works licensed under the GNU General Public License or
+ * other free or open source software licenses.
+ * @version $Id: $
+ */
+/*
+ * This class is used by VirtueMart Payment or Shipment Plugins
+ * which uses JParameter
+ * So It should be an extension of JElement
+ * Those plugins cannot be configured througth the Plugin Manager anyway.
+ */
+ 
+ 
+// print "<h3>vmlengthunit.php LOADING</h3>";
+
+if (!class_exists('VmConfig'))
+    require(JPATH_ROOT . DS . 'administrator' . DS . 'components' . DS . 'com_virtuemart' . DS . 'helpers' . DS . 'config.php');
+
+if (!class_exists('ShopFunctions'))
+    require(JPATH_VM_ADMINISTRATOR . DS . 'helpers' . DS . 'shopfunctions.php');
+
+class JElementVmLengthUnit extends JElement {
+
+    /**
+     * Element name
+     * @access	protected
+     * @var		string
+     */
+    var $_name = 'LengthUnit';
+
+    function fetchElement($nm, $value, &$node, $control_name) {
+		// For now, this is a modified copy of ShopFunctions::renderLWHUnitList to use JHTML::_ instead of VmHTML 
+		// (which would NOT remove the [ and ] from the ID and thus break the javascript magic!)
+		if (!class_exists ('VmHTML')) {
+			require(JPATH_VM_ADMINISTRATOR . DS . 'helpers' . DS . 'html.php');
+		}
+		$name = $control_name . '[' . $nm . ']';
+
+		$lwh_unit_default = array('M' => JText::_ ('COM_VIRTUEMART_UNIT_NAME_M')
+		, 'CM'                        => JText::_ ('COM_VIRTUEMART_UNIT_NAME_CM')
+		, 'MM'                        => JText::_ ('COM_VIRTUEMART_UNIT_NAME_MM')
+		, 'YD'                        => JText::_ ('COM_VIRTUEMART_UNIT_NAME_YARD')
+		, 'FT'                        => JText::_ ('COM_VIRTUEMART_UNIT_NAME_FOOT')
+		, 'IN'                        => JText::_ ('COM_VIRTUEMART_UNIT_NAME_INCH')
+		);
+		foreach ($lwh_unit_default as  $key => $value) {
+			$lu_list[] = JHTML::_ ('select.option', $key, $value, $name);
+		}
+		$listHTML = JHTML::_ ('Select.genericlist', $lu_list, $name, '', $name, 'text', $selected);
+		return $listHTML;
+    }
+
+}
\ No newline at end of file
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 62e7d12bc2ce8e8b380e0dcaf884f5f744e5f3b6..ae6f35a7200531138b1dc0568c0db19588b09535 100644
--- a/language/en-GB/en-GB.plg_vmshipment_rules_shipping.ini
+++ b/language/en-GB/en-GB.plg_vmshipment_rules_shipping.ini
@@ -13,6 +13,9 @@ VMSHIPMENT_RULES_PLUGIN_ADV="<b>Shipment based on general rules (weight, product
 VMSHIPMENT_RULES_HELP="<div style='background: #DDDDDD; padding:5px; margin:3px;'><h2>Overview of the Rules Syntax</h2><ul><li>Each line contains one rule consisting of several <b>conditions and assignments in arbitrary order and separated by semicolons</b>. </li><li>The <b>first matching rule is used</b> to calculate the shipping costs.</li><li>All rule parts with <b>comparison operators (&lt;, &lt;=, =&lt;, ==, !=, &lt;&gt;, &gt;=, =&gt;, &gt;)</b> are conditions.</li><li> Supported <b>variables (case-insensitive)</b>: <b><tt>Amount</tt></b>, <b><tt>Weight</tt></b>, <b><tt>ZIP</tt></b>, <b><tt>Products</tt></b> (number of different products), <b><tt>Articles</tt></b> (counted with quantity), <b><tt>Volume</tt></b> (total volume of the order) and <b><tt>MinVolume</tt>, <tt>MinLength</tt>, <tt>MinWidth</tt>, <tt>MinHeight</tt></b> as well as the same variables with <tt>Max</tt> instead of <tt>Min</tt>.</li><li>A condition can consist of multiple chained comparisons.</li><li>All rule parts of the form <b><tt>[VARIABLE]=VALUE</tt> are assignments</b>, with <tt>[VARIABLE]</tt> being one of <b><tt>Name</tt></b> (optional name of the rule, displayed in the cart and invoice), <b><tt>Shipping</tt></b> (shipping cost without tax if the rule matches) and <b><tt>ShippingWithTax</tt></b> (shipping cost including taxes if the rule matches). The <tt>Shipping=</tt> can be left out (<tt>ShippingWithTax=</tt> can not be left out). I.e. a rule part consisting only of a numerical value is understood as net shipping cost without tax.</li></ul><p>EXAMPLE: A rule named &quot;Europe&quot; that sets shipping costs of 4.50 for order amounts from 50 to less than 100, and free shipping from 100€ on would be:</p><blockquote><tt>Name=Europe; 50&lt;=Amount&lt;100; Shipping=4.50<br>Name=Free Shipping; 100&lt;= Amount; 0</tt></blockquote></div>"
 VMSHIPMENT_RULES_HELP_ADV="<div style='background: #DDDDDD; padding:5px; margin:3px;'><h2>Overview of the Rules Syntax</h2><ul><li>Each line contains one rule consisting of several <b>conditions and assignments in arbitrary order and separated by semicolons</b>. </li><li>The <b>first matching rule is used</b> to calculate the shipping costs.</li><li>All rule parts with <b>comparison operators (&lt;, &lt;=, =&lt;, ==, !=, &lt;&gt;, &gt;=, =&gt;, &gt;)</b> are conditions.</li><li> Supported <b>variables (case-insensitive)</b>: <b><tt>Amount</tt></b>, <b><tt>Weight</tt></b>, <b><tt>ZIP</tt></b>, <b><tt>Products</tt></b> (number of different products), <b><tt>Articles</tt></b> (counted with quantity), <b><tt>Volume</tt></b> (total volume of the order) and <b><tt>MinVolume</tt>, <tt>MinLength</tt>, <tt>MinWidth</tt>, <tt>MinHeight</tt></b> as well as the same variables with <tt>Max</tt> instead of <tt>Min</tt>.</li><li>A condition can consist of multiple chained comparisons.</li><li>All rule parts of the form <b><tt>[VARIABLE]=VALUE</tt> are assignments</b>, with <tt>[VARIABLE]</tt> being one of <b><tt>Name</tt></b> (optional name of the rule, displayed in the cart and invoice), <b><tt>Shipping</tt></b> (shipping cost without tax if the rule matches) and <b><tt>ShippingWithTax</tt></b> (shipping cost including taxes if the rule matches). The <tt>Shipping=</tt> can be left out (<tt>ShippingWithTax=</tt> can not be left out). I.e. a rule part consisting only of a numerical value is understood as net shipping cost without tax.</li><li>In the advanced version, all expressions (conditions and shipping costs) may contain <b>arbitrary basic arithmetic expressions (+, -, *, /, %, ^ and parentheses)</b> of the above variables.</li></ul><p>EXAMPLE: A rule named &quot;Europe&quot; that sets shipping costs of 5€ plus 1.50€ per article for order amounts from 50 to less than 100, and free shipping from 100€ on would be:</p><blockquote><tt>Name=Europe; 50&lt;=Amount&lt;100; Shipping=5+1.50*Articles<br>Name=Free Shipping; 100&lt;= Amount; 0</blockquote></div>"
 
+VMSHIPMENT_RULES_LENGTH_UNIT="Length Unit"
+VMSHIPMENT_RULES_LENGTH_UNIT_DESC="The length unit, in which the length, width and heights are given, and from which the volume is calculated."
+
 VMSHIPMENT_RULES_COUNTRIES1_LABEL="<b>Rules for country set 1</b>"
 VMSHIPMENT_RULES_COUNTRIES2_LABEL="<b>Rules for country set 2</b>"
 VMSHIPMENT_RULES_COUNTRIES3_LABEL="<b>Rules for country set 3</b>"
diff --git a/releases/plg_vmshipment_rules_shipping_advanced_v2.2.0.zip b/releases/plg_vmshipment_rules_shipping_advanced_v2.2.0.zip
new file mode 100644
index 0000000000000000000000000000000000000000..778fdd8a4396cfc9269debc3b8a7c5b540263f6d
Binary files /dev/null and b/releases/plg_vmshipment_rules_shipping_advanced_v2.2.0.zip differ
diff --git a/releases/plg_vmshipment_rules_shipping_v2.2.0.zip b/releases/plg_vmshipment_rules_shipping_v2.2.0.zip
new file mode 100644
index 0000000000000000000000000000000000000000..063e5a859c48623291dd1bb79b9d9b494c5b896c
Binary files /dev/null and b/releases/plg_vmshipment_rules_shipping_v2.2.0.zip differ
diff --git a/rules_shipping.xml b/rules_shipping.xml
index 811fa857896e2e77c5ed6d63c330fdc385d42f03..562531558ee2d3898803600757a3a152a66b9c41 100644
--- a/rules_shipping.xml
+++ b/rules_shipping.xml
@@ -6,7 +6,7 @@
     <authorUrl>http://www.kainhofer.com</authorUrl>
     <copyright>Copyright (C) 2013, Reinhold Kainhofer</copyright>
     <license>GPL v3+</license>
-    <version>2.1.3</version>
+    <version>2.2.0</version>
     <description>VMSHIPMENT_RULES_DESC</description>
     <files>
 	<filename plugin="rules_shipping">rules_shipping.php</filename>
@@ -21,9 +21,12 @@
     <scriptfile>rules_shipping.script.php</scriptfile>
 
 
-    <params  addpath="/administrator/components/com_virtuemart/elements"/>
 
-    <params addpath="/plugins/vmshipment/rules_shipping_advanced/elements/">
+    <params addpath="/administrator/components/com_virtuemart/elements" />
+    <params addpath="/plugins/vmshipment/rules_shipping/rules_shipping/elements" />
+    <params addpath="/plugins/vmshipment/rules_shipping/elements" />
+
+    <params>
 	<param type="vmjpluginwarning" />
 	<param type="spacer" default='VMSHIPMENT_RULES_PLUGIN' level="level1" />
 	<param	name="shipment_logos" type="vmfiles" label="VMSHIPMENT_WEIGHT_COUNTRIES_LOGOS"
@@ -32,6 +35,7 @@
              	default="default" hide_default="1" hide_none="1"
              	stripext="0"   exclude="^_" />
 	<param name="weight_unit" type="vmweightunit" size="10" default="" label="VMSHIPMENT_WEIGHT_COUNTRIES_WEIGHT_UNIT" description="VMSHIPMENT_WEIGHT_COUNTRIES_WEIGHT_UNIT_DESC"/>
+	<param name="length_unit" type="vmlengthunit" size="10" default="" label="VMSHIPMENT_RULES_LENGTH_UNIT" description="VMSHIPMENT_RULES_LENGTH_UNIT_DESC"/>
 
 	<param type="rklabel" default='VMSHIPMENT_RULES_HELP' />
 
diff --git a/rules_shipping_advanced.php b/rules_shipping_advanced.php
index 6d00afa3bba3156b5cec26b161660d8577498482..14dd0e710ebda21b5e3eb6ee753fffe58db4a962 100644
--- a/rules_shipping_advanced.php
+++ b/rules_shipping_advanced.php
@@ -48,20 +48,6 @@ class plgVmShipmentRules_Shipping_Advanced extends plgVmShipmentRules_Shipping_B
 }
 
 
-// is_comparison: if the expression $o is a (possibly chained) comparison consisting of operators in $ops, 
-// return the last term of hte comparison; null otherwise
-function is_comparison ($o, $ops) {
-	if (!is_array($o)) 
-		return null;
-	if (in_array($o[0], $ops))
-		return $o[2];
-	$o2comp = is_comparison($o[2], $ops);
-	if (trim($o[0])=='AND' && !is_null (is_comparison($o[1], $ops)) && !is_null($o2comp))
-		return $o2comp;
-	return null;
-}
-
-
 /** Extend the shipping rules by allowing arbitrary mathematical expressions
  */
 class ShippingRule_Advanced extends ShippingRule {
@@ -70,7 +56,7 @@ class ShippingRule_Advanced extends ShippingRule {
 		"*"  => 60, "/"  => 60, "%"  => 60, 
 		"+"  => 50, "-"  => 50, 
 		"<"  => 40, "<=" => 40, ">"  => 40, ">=" => 40, "=>" => 40, "=<" => 40,
-		"==" => 40, "!=" => 40, "<>" => 40,
+		"==" => 40, "!=" => 40, "<>" => 40, "~" => 40,
 		"&&"  => 21, " AND " => 21, "AND" => 21,
 		" OR "  => 20, "OR" => 20,
 		"="  => 10,
@@ -86,7 +72,7 @@ class ShippingRule_Advanced extends ShippingRule {
 		$str_re = '/("(?:\\"|[^"])*"|\'(?:\\\'|[^\'])*\')/';
 		$strings = preg_split($str_re, $expression, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
 		// Then split all other parts of the expression at the operators
-		$op_re = ':\s*( OR |&&| AND |<=|=>|>=|=>|<>|!=|==|<|=|>|\+|-|\*|/|%|\(|\)|\^)\s*:';
+		$op_re = ':\s*( OR |&&| AND |<=|=>|>=|=>|<>|!=|==|<|=|>|~|\+|-|\*|/|%|\(|\)|\^)\s*:';
 		$atoms = array();
 		foreach ($strings as $s) {
 			if (preg_match($str_re, $s)) {
@@ -155,8 +141,9 @@ class ShippingRule_Advanced extends ShippingRule {
 		$atoms = $this->tokenize_expression ($rulepart);
 		
 		// Any of these indicate a comparison and thus a condition:
-		$comparison_ops = array('<', '<=', '=<', '<>', '!=', '==', '>', '>=', '=>', ' OR ', 'OR', 'AND', ' AND ', '&&');
-		$is_comparison = false;
+		$condition_ops = array('<', '<=', '=<', '<>', '!=', '==', '>', '>=', '=>', '~', ' OR ', 'OR', 'AND', ' AND ', '&&');
+		$comparison_ops = array('<', '<=', '=<', '<>', '!=', '==', '>', '>=', '=>', '~');
+		$is_condition = false;
 		$is_assignment = false;
 		
 		if (count($atoms)==1) return $atoms[0];
@@ -185,7 +172,7 @@ class ShippingRule_Advanced extends ShippingRule {
 				// For operators, pop operators from the stack until you reach an opening parenthesis, 
 				// an operator of lower precedence, or a right associative symbol of equal precedence. 
 				$prec = $this->operators[$a];
-				$is_comparison |= in_array($a, $comparison_ops);
+				$is_condition |= in_array($a, $condition_ops);
 				$is_assignment |= ($a == "=");
 				
 				while (count($stack)>0) { // 4a)
@@ -243,12 +230,16 @@ class ShippingRule_Advanced extends ShippingRule {
 				}
 				$o2 = array_pop($stack); // 4a)
 				$o1 = array_pop($stack);
-				// TODO: Special-case chained comparisons: if e is a comparison, and operator(o1) is also a comparison, 
-				//       insert AND(o1, e(arg2(o1), o2)) instead of e(o1, o1)
-				// is_comparison nicely returns the last term of the (possibly chained) comparison, null otherwise
-				$o1comp = is_comparison($o1, $comparison_ops);
-				if (in_array ($e, $comparison_ops) && !is_null($o1comp) ) {
-					$op = array ('AND', $o1, array($e, $o1comp, $o2));
+				// Special-case chained comparisons: if e is a comparison, and operator(o1) is also a comparison, 
+				// insert the arguments to the existing comparison instead of creating a new one
+				if (in_array ($e, $comparison_ops)) {
+					if ($o1[0]=='comparison') {
+						$op = $o1;
+						// Append the new comparison to the existing one
+						array_push($op, $e, $o2);
+					} else {
+						$op = array ('comparison', $o1, $e, $o2);
+					}
 				} else {
 					$op = array ($e, $o1, $o2); // 4b)
 				}
@@ -262,7 +253,7 @@ class ShippingRule_Advanced extends ShippingRule {
 		}
 		$res = array_pop($stack); // 5)
 		
-		if ($is_comparison) { // Comparisons are conditions
+		if ($is_condition) { // Comparisons are conditions
 			$this->conditions[] = $res;
 		} elseif ($is_assignment) {
 
diff --git a/rules_shipping_advanced.xml b/rules_shipping_advanced.xml
index 49db8619a67946a37d0fb01b6045ac3f1e1e11ac..ca9a10d486e872675039d073a040181ab7b58a89 100644
--- a/rules_shipping_advanced.xml
+++ b/rules_shipping_advanced.xml
@@ -6,7 +6,7 @@
     <authorUrl>http://www.kainhofer.com</authorUrl>
     <copyright>Copyright (C) 2013, Reinhold Kainhofer</copyright>
     <license>GPL v3+</license>
-    <version>2.1.3</version>
+    <version>2.2.0</version>
     <description>VMSHIPMENT_RULES_ADV_DESC</description>
     <files>
 	<filename plugin="rules_shipping_advanced">rules_shipping_advanced.php</filename>
@@ -21,9 +21,11 @@
     <scriptfile>rules_shipping_advanced.script.php</scriptfile>
 
 
-    <params addpath="/plugins/vmshipment/rules_shipping_advanced/elements/" />
+    <params addpath="/administrator/components/com_virtuemart/elements" />
+    <params addpath="/plugins/vmshipment/rules_shipping_advanced/rules_shipping_advanced/elements" />
+    <params addpath="/plugins/vmshipment/rules_shipping_advanced/elements" />
 
-    <params addpath="/administrator/components/com_virtuemart/elements">
+    <params>
 	<param type="vmjpluginwarning" />
 	<param type="rklabel" default='VMSHIPMENT_RULES_PLUGIN_ADV' level="level1" />
 	<param	name="shipment_logos" type="vmfiles" label="VMSHIPMENT_WEIGHT_COUNTRIES_LOGOS"
@@ -32,6 +34,7 @@
              	default="default" hide_default="1" hide_none="1"
              	stripext="0"   exclude="^_" />
 	<param name="weight_unit" type="vmweightunit" size="10" default="" label="VMSHIPMENT_WEIGHT_COUNTRIES_WEIGHT_UNIT" description="VMSHIPMENT_WEIGHT_COUNTRIES_WEIGHT_UNIT_DESC"/>
+	<param name="length_unit" type="vmlengthunit" size="10" default="" label="VMSHIPMENT_RULES_LENGTH_UNIT" description="VMSHIPMENT_RULES_LENGTH_UNIT_DESC"/>
 
 	<param type="rklabel" default='VMSHIPMENT_RULES_HELP_ADV' />
 
diff --git a/rules_shipping_base.php b/rules_shipping_base.php
index 876aadb661191e96ca7f8f6ca77b7b1e08a22ae7..39c3ef77027ba64c189c3c2959fc4439705cd6fe 100644
--- a/rules_shipping_base.php
+++ b/rules_shipping_base.php
@@ -322,7 +322,7 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin {
 		return $articles;
 	}
 
-	protected function getOrderDimensions (VirtueMartCart $cart) {
+	protected function getOrderDimensions (VirtueMartCart $cart, $length_dimension) {
 		/* Cache the value in a static variable and calculate it only once! */
 		static $calculated = 0;
 		static $dimensions=array(
@@ -335,22 +335,29 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin {
 		if ($calculated==0) {
 			$calculated=1;
 			foreach ($cart->products as $product) {
-				$volume = $product->product_length * $product->product_width * $product->product_height;
+	
+				$l = ShopFunctions::convertDimensionUnit ($product->product_length, $product->product_lwh_uom, $length_dimension);
+				$w = ShopFunctions::convertDimensionUnit ($product->product_width, $product->product_lwh_uom, $length_dimension);
+				$h = ShopFunctions::convertDimensionUnit ($product->product_height, $product->product_lwh_uom, $length_dimension);
+// JFactory::getApplication()->enqueueMessage("<pre>Product, returned dimensions: $l x $w x $h, from $product->product_lwh_uom to $length_dimension,  ".print_r($product,1)."</pre>", 'error');
+
+				$volume = $l * $w * $h;
 				$dimensions['volume'] += $volume * $product->quantity;
 				$dimensions['maxvolume'] = max ($dimensions['maxvolume'], $volume);
 				$dimensions['minvolume'] = min ($dimensions['minvolume'], $volume);
-				$dimensions['maxlength'] = max ($dimensions['maxlength'], $product->product_length);
-				$dimensions['minlength'] = min ($dimensions['minlength'], $product->product_length);
-				$dimensions['maxwidth'] = max ($dimensions['maxwidth'], $product->product_width);
-				$dimensions['minwidth'] = min ($dimensions['minwidth'], $product->product_width);
-				$dimensions['maxheight'] = max ($dimensions['maxheight'], $product->product_height);
-				$dimensions['minheight'] = min ($dimensions['minheight'], $product->product_height);
-				$dimensions['totallength'] += $product->product_length;
-				$dimensions['totalwidth'] += $product->product_width;
-				$dimensions['totalheight'] += $product->product_height;
-				
+				$dimensions['maxlength'] = max ($dimensions['maxlength'], $l);
+				$dimensions['minlength'] = min ($dimensions['minlength'], $l);
+				$dimensions['maxwidth'] = max ($dimensions['maxwidth'], $w);
+				$dimensions['minwidth'] = min ($dimensions['minwidth'], $w);
+				$dimensions['maxheight'] = max ($dimensions['maxheight'], $h);
+				$dimensions['minheight'] = min ($dimensions['minheight'], $h);
+				$dimensions['totallength'] += $l * $product->quantity;
+				$dimensions['totalwidth'] += $w * $product->quantity;
+				$dimensions['totalheight'] += $h * $product->quantity;
 			}
 		}
+// JFactory::getApplication()->enqueueMessage("<pre>Dimensions: ".print_r($dimensions,1)."</pre>", 'error');
+
 		return $dimensions;
 	}
 
@@ -377,8 +384,15 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin {
 			$products += 1;
 			$articles += $product->quantity;
 		}
+		$zip = $address['zip'];
 		$cartvals = array('weight'=>$orderWeight, 
-				  'zip'=>$address['zip'], 
+				  'zip'=>$zip, 
+				  'zip1'=>substr($zip,0,1), 
+				  'zip2'=>substr($zip,0,2), 
+				  'zip3'=>substr($zip,0,3), 
+				  'zip4'=>substr($zip,0,4), 
+				  'zip5'=>substr($zip,0,5), 
+				  'zip6'=>substr($zip,0,6), 
 				  'articles'=>$articles, 
 				  'products'=>$products,
 				  'amount'=>$cart_prices['salesPrice'],
@@ -397,7 +411,7 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin {
 
 				  'country'=>$address['virtuemart_country_id'],
 			);
-		$cartvals = array_merge ($cartvals, $this->getOrderDimensions ($cart));
+		$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);
 		return $cartvals;
@@ -617,6 +631,42 @@ class ShippingRule {
 		return strtolower($expr);
 	}
 	
+	function evaluateComparison ($terms, $vals) {
+		while (count($terms)>2) {
+			$res = false;
+			switch ($terms[1]) {
+				case '<':  $res = ($terms[0] < $terms[2]);  break;
+				case '<=': 
+				case '=<': $res = ($terms[0] <= $terms[2]); break;
+				case '==': $res = ($terms[0] == $terms[2]); break;
+				case '!=':
+				case '<>': $res = ($terms[0] != $terms[2]); break;
+				case '>=':
+				case '=>': $res = ($terms[0] >= $terms[2]); break;
+				case '>':  $res = ($terms[0] >  $terms[2]);  break;
+				case '~':  
+					$l=min(strlen($terms[0]), strlen($terms[2]));
+					$res = (strncmp ($terms[0], $terms[2], $l) == 0);
+JFactory::getApplication()->enqueueMessage("String-comparing $terms[0] and $terms[2] ($l chars), result=$res", 'error');
+					break;
+				default:
+					JFactory::getApplication()->enqueueMessage(JText::sprintf('VMSHIPMENT_RULES_UNKNOWN_OPERATOR', $terms[1], $this->rulestring), 'error');
+					$res = false;
+			}
+
+			if ($res==false) return false;
+			array_shift($terms);
+			array_shift($terms);
+		}
+		if (count($terms)>1) {
+			// We do not have the correct number of terms for chained comparisons, i.e. two terms leftover instead of one!
+			JFactory::getApplication()->enqueueMessage(JText::sprintf('VMSHIPMENT_RULES_EVALUATE_UNKNOWN_ERROR', $this->rulestring), 'error');
+			return false;
+		} 
+		// All conditions were fulfilled, so we can return true
+		return true;
+	}
+	
 	function evaluateTerm ($expr, $vals) {
 		if (is_null($expr)) {
 			return $expr;
@@ -636,8 +686,13 @@ class ShippingRule {
 			// Operator
 			$op = array_shift($expr);
 			$args = array();
+			$evaluate = true;
 			foreach ($expr as $e) {
-				$term = $this->evaluateTerm($e, $vals);
+				$term = $evaluate ? ($this->evaluateTerm($e, $vals)) : $e;
+				if ($op == 'comparison') {
+					// For comparisons, we only evaluate every other term (the operators are NOT evaluated!)
+					$evaluate = !$evaluate;
+				}
 				if (is_null($term)) return null;
 				$args[] = $term;
 			}
@@ -650,15 +705,19 @@ class ShippingRule {
 				case ' AND ':  $res = true; foreach ($args as $a) { $res = ($res && $a); }; break;
 				case 'in': $needle = array_shift($args); $res = in_array($needle, $args); break;
 				
-				case '<':  $res = ($args[0] < $args[1]);  break;
+				case '<':  
 				case '<=': 
-				case '=<': $res = ($args[0] <= $args[1]); break;
-				case '==': $res = ($args[0] == $args[1]); break;
+				case '=<': 
+				case '==': 
 				case '!=':
-				case '<>': $res = ($args[0] != $args[1]); break;
+				case '<>': 
 				case '>=':
-				case '=>': $res = ($args[0] >= $args[1]); break;
-				case '>':  $res = ($args[0] >  $args[1]);  break;
+				case '=>': 
+				case '>':
+				case '~':
+					$res = $this->evaluateComparison(array($args[0], $op, $args[1]), $vals); break;
+				case 'comparison':
+					$res = $this->evaluateComparison($args, $vals); break;
 				
 				case "+":  $res = ($args[0] +  $args[1]); break;
 				case "-":  $res = ($args[0] -  $args[1]); break;
@@ -669,6 +728,8 @@ class ShippingRule {
 				
 				default:   $res = false;
 			}
+			
+// 			JFactory::getApplication()->enqueueMessage("<pre>Result of ".print_r($expr,1)." is $res.</pre>", 'error');
 			return $res;
 		} else {
 			// Neither string nor numeric, nor operator...