diff --git a/rules_shipping_advanced.php b/rules_shipping_advanced.php
index 13d69a82be507bde0c530a0e75d2cca98983048a..e6c845c9a16ecaffa16d5f389da457218a9e5e6b 100644
--- a/rules_shipping_advanced.php
+++ b/rules_shipping_advanced.php
@@ -152,7 +152,7 @@ class ShippingRule_Advanced extends ShippingRule {
 
 		
 		// Special-case the name assignment, where we don't want to interpret the value as an arithmetic expression!
-		if (preg_match('/^\s*(name)\s*=\s*(["\']?)(.*)\2\s*$/i', $rulepart, $matches)) {
+		if (preg_match('/^\s*(name|variable|definition)\s*=\s*(["\']?)(.*)\2\s*$/i', $rulepart, $matches)) {
 			$this->handleAssignment ($matches[1], $matches[3], $rulepart);
 			return;
 		}
@@ -389,20 +389,21 @@ class ShippingRule_Advanced extends ShippingRule {
 		// 5a)
 		if (count($stack) != 1) {
 			JFactory::getApplication()->enqueueMessage(JText::sprintf('VMSHIPMENT_RULES_EVALUATE_UNKNOWN_ERROR', $rulepart), 'error');
+			JFactory::getApplication()->enqueueMessage(JText::sprintf('Outstack: <pre>%s</pre>', print_r($out_stack,1)), 'error');
+			
 			$stack = array (0);
 		}
 		$res = array_pop($stack); // 5)
 		
-		if ($is_condition) { // Comparisons are conditions
-			$this->conditions[] = $res;
-		} elseif ($is_assignment) {
-
+		if ($is_assignment) { // Assignments are handled first, so conditions can be assigned to variables
 			if ($res[0]=='=') {
 				$this->handleAssignment ($res[1], $res[2], $rulepart);
 			} else {
 				// Assignment has to be top-level!
 				JFactory::getApplication()->enqueueMessage(JText::sprintf('VMSHIPMENT_RULES_EVALUATE_ASSIGNMENT_TOPLEVEL', $rulepart), 'error');
 			}
+		} elseif ($is_condition) { // Comparisons are conditions
+			$this->conditions[] = $res;
 		} else {
 			// Terms without comparisons or assignments are shipping cost expressions
 			$this->shipping = $res;
diff --git a/rules_shipping_base.php b/rules_shipping_base.php
index 78457dc868cc6793e78b73c6286f1f4765207de8..8ba11e33358628b13259a86752376085a8f60767 100644
--- a/rules_shipping_base.php
+++ b/rules_shipping_base.php
@@ -224,6 +224,48 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin {
 
 
 
+	protected function findMatchingRule (&$cartvals, $method) {
+		$result = array("rule"=>Null, "rule_name"=>"", "modifiers"=>array());
+		// TODO: Handle modifiers
+		foreach ($method->rules as $r) {
+			// If the rule is a variable definition, it will NOT match, but modify the $cartvals array for the next rules
+			if ($r->matches($cartvals)) {
+				$result["rule"] = $r;
+				$result["rule_name"] = $r->getRuleName($cartvals);
+				return $result;
+			}
+		}
+		// None of the rules matched, so return NULL;
+		return NULL;
+	}
+
+	/**
+	 * @param \VirtueMartCart $cart
+	 * @param int             $method
+	 * @param array           $cart_prices
+	 * @return bool
+	 */
+	protected function checkConditions ($cart, $method, $cart_prices) {
+		if (!isset($method->rules)) $this->parseMethodRules($method);
+
+		$cartvals = $this->getCartValues ($cart, $method, $cart_prices);
+		$match = $this->findMatchingRule ($cartvals, $method);
+		if ($match) {
+			$method->matched_rule = $match["rule"];
+			$method->rule_name = $match["rule_name"];
+			// If NoShipping is set, this method should NOT offer any shipping at all, so return FALSE, otherwise TRUE
+			if ($method->matched_rule->isNoShipping()) {
+				$this->printWarning(JText::sprintf('VMSHIPMENT_RULES_NOSHIPPING_MESSAGE', $method->rule_name));
+				vmdebug('checkConditions '.$method->shipment_name.' indicates NoShipping for rule "'.$method->rule_name.'" ('.$method->matched_rule->rulestring.').');
+				return FALSE;
+			} else {
+				return TRUE;
+			}
+		}
+		vmdebug('checkConditions '.$method->shipment_name.' does not fit');
+		return FALSE;
+	}
+
 	/**
 	 * @param VirtueMartCart $cart
 	 * @param                $method
@@ -233,18 +275,17 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin {
 	function getCosts (VirtueMartCart $cart, $method, $cart_prices) {
 		if (!isset($method->rules)) $this->parseMethodRules($method);
 		$cartvals = $this->getCartValues ($cart, $method, $cart_prices);
-		
-		foreach ($method->rules as $r) {
-			if ($r->matches($cartvals)) {
-				$rulename=$r->getRuleName($cartvals);
-				vmdebug('Rule '.$rulename.' ('.$r->rulestring.') matched.');
-				$method->tax_id = $r->tax_id;
-				$method->matched_rule = $r;
-				$method->rule_name = $r->getRuleName($cartvals);
-				$method->cost = $r->getShippingCosts($cartvals);
-				$method->includes_tax = $r->includes_tax;
-				return $method->cost;
-			}
+		$match = $this->findMatchingRule ($cartvals, $method);
+		if ($match) {
+			$r = $match["rule"];
+			$rulename = $match["rule_name"];
+			vmdebug('Rule '.$rulename.' ('.$r->rulestring.') matched.');
+			$method->tax_id = $r->tax_id;
+			$method->matched_rule = $r;
+			$method->rule_name = $rulename;
+			$method->cost = $r->getShippingCosts($cartvals);
+			$method->includes_tax = $r->includes_tax;
+			return $method->cost;
 		}
 		
 		vmdebug('getCosts '.$method->name.' does not return shipping costs');
@@ -530,35 +571,6 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin {
 		return $cartvals;
 	}
 
-
-	/**
-	 * @param \VirtueMartCart $cart
-	 * @param int             $method
-	 * @param array           $cart_prices
-	 * @return bool
-	 */
-	protected function checkConditions ($cart, $method, $cart_prices) {
-		if (!isset($method->rules)) $this->parseMethodRules($method);
-
-		$cartvals = $this->getCartValues ($cart, $method, $cart_prices);
-		foreach ($method->rules as $r) {
-			if ($r->matches($cartvals)) {
-				$method->matched_rule = $r;
-				$method->rule_name = $r->getRuleName($cartvals);
-				// If NoShipping is set, this method should NOT offer any shipping at all, so return FALSE, otherwise TRUE
-				if ($r->isNoShipping()) {
-					$this->printWarning(JText::sprintf('VMSHIPMENT_RULES_NOSHIPPING_MESSAGE', $method->rule_name));
-					vmdebug('checkConditions '.$method->shipment_name.' indicates NoShipping for rule "'.$method->rule_name.'" ('.$r->rulestring.').');
-					return FALSE;
-				} else {
-					return TRUE;
-				}
-			}
-		}
-		vmdebug('checkConditions '.$method->shipment_name.' does not fit');
-		return FALSE;
-	}
-
 	/**
 	 * Create the table for this plugin if it does not yet exist.
 	 * This functions checks if the called plugin is active one.
@@ -683,6 +695,7 @@ class ShippingRule {
 	var $shipping = 0;
 	var $includes_tax = 0;
 	var $name = '';
+	var $is_definition = 0;
 	
 	function __construct ($rule, $countries, $tax_id) {
 		if (is_array($countries)) {
@@ -704,10 +717,14 @@ class ShippingRule {
 	
 	function handleAssignment ($var, $value, $rulepart) {
 		switch (strtolower($var)) {
+			case 'name': $this->name = $value; break;
 			case 'shipping': $this->shipping = $value; $this->includes_tax = False; break;
 			case 'shippingwithtax': $this->shipping = $value; $this->includes_tax = True; break;
-			case 'name': $this->name = $value; break;
+			case 'variable':   // Variable=... is the same as Definition=...
+			case 'definition': $this->name = $value; $this->is_definition = True; break;
+			case 'value': $this->shipping = $value; break; // definition values are also stored in the shipping member!
 			case 'comment': break; // Completely ignore all comments!
+			case 'condition': $this->conditions[] = $value; break;
 			default: JFactory::getApplication()->enqueueMessage(JText::sprintf('VMSHIPMENT_RULES_UNKNOWN_VARIABLE', $var, $rulepart), 'error');
 		}
 	}
@@ -951,24 +968,29 @@ class ShippingRule {
 		return $this->evaluateTerm($this->shipping, $vals);
 	}
 
-	function matches($vals) {
+	function matches(&$vals) {
 		// First, check the country, if any conditions are given:
 		if (count ($this->countries) > 0 && !in_array ($vals['countryid'], $this->countries)) {
 // 			vmdebug('Rule::matches: Country check failed: countryid='.print_r($vals['countryid'],1).', countries are: '.print_r($this->countries,1).'...');
 			return False;
 		}
-		
+
 		foreach ($this->conditions as $c) {
 			// All conditions have to match!
 			$ret = $this->evaluateTerm($c, $vals);
-			// JFactory::getApplication()->enqueueMessage("Evaluating term <pre>".print_r($c,1)."</pre> returns $ret", 'error');
 
 			if (is_null($ret) || (!$ret)) {
 				return false;
 			}
 		}
-		// All conditions match, so return true
-		return true;
+		// All conditions match, so return true for rules; For definitions add the variable to the vals 
+		if ($this->is_definition) {
+			$vals[$this->name] = $this->evaluateTerm($this->shipping, $vals);
+			// This rule does not specify shipping costs (just modify the cart values!), so return false
+			return false;
+		} else {
+			return true;
+		}
 	}
 
 	function getRuleName($vals) {
@@ -994,6 +1016,9 @@ class ShippingRule {
 		// NoShipping is set, so if the rule matches, this method should not offer any shipping at all
 		return (is_string($this->shipping) && (strtolower($this->shipping)=="noshipping"));
 	}
+	function isDefinition() {
+		return $this->is_definition;
+	}
 
 }