diff --git a/rules_shipping_base.php b/rules_shipping_base.php
index 819bc9ce31d5664db217291e37b661eeb213ffc2..af26407326bf6758446aa2ef0115c480563096ac 100644
--- a/rules_shipping_base.php
+++ b/rules_shipping_base.php
@@ -173,9 +173,9 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin {
 		$values['virtuemart_shipmentmethod_id'] = $order['details']['BT']->virtuemart_shipmentmethod_id;
 		$values['shipment_name'] = $this->renderPluginName ($method);
 		$values['rule_name'] = $method->rule_name;
-		$values['order_weight'] = $this->getOrderWeight ($cart, $method->weight_unit);
-		$values['order_articles'] = $this->getOrderArticles ($cart);
-		$values['order_products'] = $this->getOrderProducts ($cart);
+// 		$values['order_weight'] = $this->getOrderWeight ($cart, $method->weight_unit);
+// 		$values['order_articles'] = $this->getOrderArticles ($cart);
+// 		$values['order_products'] = $this->getOrderProducts ($cart);
 		$values['shipment_weight_unit'] = $method->weight_unit;
 		$values['shipment_cost'] = $method->cost;
 		$values['tax_id'] = $method->tax_id;
@@ -265,7 +265,9 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin {
 	}
 
 
-
+	/** This function evaluates all rules, one after the other until it finds a matching rule that
+	 *  defines shipping costs (or uses NoShipping). If a modifier or definition is encountered,
+	 *  its effect is stored, but the loop continues */
 	protected function evaluateMethodRules ($cart, $method, $cart_prices) {
 		// $method->match will cache the matched rule and the modifiers
 		if (isset($this->match[$method->virtuemart_shipmentmethod_id])) {
@@ -274,8 +276,13 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin {
 			// Evaluate all rules and find the matching ones (including modifiers and definitions!)
 			$result = array("rule"=>Null, "rule_name"=>"", "modifiers_add"=>array(), "modifiers_multiply"=>array());
 			$cartvals = $this->getCartValues ($cart, $cart->products, $method, $cart_prices);
+			// Pass a callback function to matches to obtain the cartvals for a subset of the products
+			$this_class = $this;
+			$cartvals_callback = function ($products) use ($this_class, $cart, $method, $cart_prices) {
+				return $this_class->getCartValues ($cart, $products, $method, NULL);
+			};
 			foreach ($this->rules[$method->virtuemart_shipmentmethod_id] as $r) {
-				if ($r->matches($cartvals)) {
+				if ($r->matches($cartvals, $cart->products, $cartvals_callback)) {
 					$rtype = $r->getType();
 					switch ($rtype) {
 						case 'shipping': 
@@ -288,7 +295,9 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin {
 						case 'modifiers_multiply':
 								$result[$rtype][] = $r;
 								break;
-						case 'definition': // A definition has modified the $cartvals, but has no other effects
+						case 'definition': // A definition updates the $cartvals, but has no other effects
+								$cartvals[strtolower($r->getRuleName())] = $r->getShippingCosts();
+								// TODO
 								break;
 						default:
 								$this->printWarning(JText::sprintf('VMSHIPMENT_RULES_UNKNOWN_TYPE', $r->getType(), $r->rulestring));
@@ -657,18 +666,18 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin {
 			'zip6'=>substr($zip,0,6),
 			'city'=>isset($address['city'])?trim($address['city']):'',
 		);
-		data['company'] = $address['company'];
-		data['title'] = $address['title'];
-		data['first_name'] = $address['first_name'];
-		data['middle_name'] = $address['middle_name'];
-		data['last_name'] = $address['last_name'];
-		data['address1'] = $address['address_1'];
-		data['address2'] = $address['address_2'];
-		data['city'] = $address['city'];
-		data['phone1'] = $address['phone_1'];
-		data['phone2'] = $address['phone_2'];
-		data['fax'] = $address['fax'];
-		data['email'] = $address['email'];
+		$data['company'] = $address['company'];
+		$data['title'] = $address['title'];
+		$data['first_name'] = $address['first_name'];
+		$data['middle_name'] = $address['middle_name'];
+		$data['last_name'] = $address['last_name'];
+		$data['address1'] = $address['address_1'];
+		$data['address2'] = $address['address_2'];
+		$data['city'] = $address['city'];
+		$data['phone1'] = $address['phone_1'];
+		$data['phone2'] = $address['phone_2'];
+		$data['fax'] = $address['fax'];
+		$data['email'] = $address['email'];
 		return $data;
 	}
 	
@@ -885,7 +894,7 @@ function filterProducts($products, $filter_conditions) {
 	foreach ($products as $p) {
 		if (!empty($filter_conditions['skus']) && !in_array($p->product_sku, $filter_conditions['skus']))
 			continue;
-		if (!empty($filter_conditions['categories']) && count(array_intersect($filter_conditions['categories'], $p->product_categories))==0)
+		if (!empty($filter_conditions['categories']) && count(array_intersect($filter_conditions['categories'], $p->categories))==0)
 			continue;
 		if (!empty($filter_conditions['manufacturers']) && count(array_intersect($filter_conditions['manufacturers'], $p->product_manufacturers))==0)
 			continue;
@@ -1115,10 +1124,11 @@ class ShippingRule {
 	
 	/** Evaluate the given expression $expr only for the products that match the filter given by the scoping 
 	 * function and the corresponding conditions */
-	protected function evaluateScoping($expr, $scoping, $conditionvals, $vals) {
-		if (count($conditions)<1)
-			return $this->evaluateTerm($expr, $vals);
-			
+	protected function evaluateScoping($expr, $scoping, $conditionvals, $vals, $products, $cartvals_callback) {
+// JFactory::getApplication()->enqueueMessage("<pre>Scoping, begin, scoping=$scoping, expression=".print_r($expr,1).", conditionvals=".print_r($conditionvals, 1)."</pre>", 'error');
+		if (count($conditionvals)<1)
+			return $this->evaluateTerm($expr, $vals, $products, $cartvals_callback);
+
 		$filterkeys = array( 
 			"evaluate_for_categories" =>    'categories',
 			"evaluate_for_products" =>      'products',
@@ -1126,15 +1136,17 @@ class ShippingRule {
 			"evaluate_for_manufacturers" => 'manufacturers'
 		);
 		
+// JFactory::getApplication()->enqueueMessage("<pre>Scoping: condition is ".$filterkeys[$scoping].'='.print_r($conditionvals,1).", Old cartvals are: ".print_r($vals,1)."</pre>", 'error');
 		$conditions = array();
 		if (isset($filterkeys[$scoping])) 
-			$conditions[$filterkeys[$scoping]] = $conditionsvals;
+			$conditions[$filterkeys[$scoping]] = $conditionvals;
 
 		// Pass the conditions to the parent plugin class to filter the current list of products:
-		$products = filterProducts($currentproducts, $conditions);
-		$vals = $this->plugin->getCartValues ($cart, $products, /* FIXME: method*/ $this->method, $cart_prices);
-		// FIXME: IMPLEMENT
-		// TODO
+		$filteredproducts = filterProducts($products, $conditions);
+		// We have been handed a callback function to calculate the cartvals for the filtered list of products, so use it:
+		$filteredvals = $cartvals_callback($filteredproducts);
+// JFactory::getApplication()->enqueueMessage("<pre>Scoping: condition is ".print_r($conditions,1).", products filtered: ".count($filteredproducts).", New cartvals are: ".print_r($filteredvals,1)."</pre>", 'error');
+		return $this->evaluateTerm ($expr, $filteredvals, $filteredproducts, $cartvals_callback);
 	}
 
 	protected function evaluateFunction ($function, $args) {
@@ -1231,7 +1243,7 @@ class ShippingRule {
 		}
 	}
 
-	protected function evaluateTerm ($expr, $vals) {
+	protected function evaluateTerm ($expr, $vals, $products, $cartvals_callback) {
 		// The scoping functions need to be handled differently, because they first need to adjust the cart variables to the filtered product list
 		// before evaluating its first argument. So even though parsing the rules handles scoping functions like any other function, their 
 		// evaluation is fundamentally different and is special-cased here:
@@ -1254,7 +1266,7 @@ class ShippingRule {
 			$func = array_shift($expr); // The scoping function name
 			$expression = array_shift($expr); // The expression to be evaluated
 			$conditions = $expr; // the remaining $expr list now contains the conditions
-			return $this->evaluateScoping ($expression, $func, $conditions, $vals);
+			return $this->evaluateScoping ($expression, $func, $conditions, $vals, $products, $cartvals_callback);
 			
 		} elseif (is_array($expr)) {
 			// Operator
@@ -1266,7 +1278,7 @@ class ShippingRule {
 				$evaluate = false;
 			}
 			foreach ($expr as $e) {
-				$term = $evaluate ? ($this->evaluateTerm($e, $vals)) : $e;
+				$term = $evaluate ? ($this->evaluateTerm($e, $vals, $products, $cartvals_callback)) : $e;
 				if ($op == 'COMPARISON') {
 					// For comparisons, we only evaluate every other term (the operators are NOT evaluated!)
 					// The data format for comparisons is: array('COMPARISON', $operand1, '<', $operand2, '<=', ....)
@@ -1329,11 +1341,11 @@ class ShippingRule {
 		}
 	}
 
-	protected function calculateShipping ($vals) {
-		return $this->evaluateTerm($this->shipping, $vals);
+	protected function calculateShipping ($vals, $products, $cartvals_callback) {
+		return $this->evaluateTerm($this->shipping, $vals, $products, $cartvals_callback);
 	}
 
-	protected function evaluateRule (&$vals) {
+	protected function evaluateRule (&$vals, $products, $cartvals_callback) {
 		if ($this->evaluated) 
 			return; // Already evaluated
 
@@ -1347,7 +1359,7 @@ class ShippingRule {
 
 		foreach ($this->conditions as $c) {
 			// All conditions have to match!
-			$ret = $this->evaluateTerm($c, $vals);
+			$ret = $this->evaluateTerm($c, $vals, $products, $cartvals_callback);
 
 			if (is_null($ret) || (!$ret)) {
 				return;
@@ -1356,7 +1368,7 @@ class ShippingRule {
 		// All conditions match
 		$this->match = True;
 		// Calculate the value (i.e. shipping cost or modifier)
-		$this->value = $this->calculateShipping($vals);
+		$this->value = $this->calculateShipping($vals, $products, $cartvals_callback);
 		// For definitions add the variable to the vals 
 		if ($this->ruletype=='definition') {
 			$vals[strtolower($this->name)] = $this->value;
@@ -1376,8 +1388,8 @@ class ShippingRule {
 		$this->rulename = $name;
 	}
 
-	function matches(&$vals) {
-		$this->evaluateRule($vals);
+	function matches(&$vals, $products, $cartvals_callback) {
+		$this->evaluateRule($vals, $products, $cartvals_callback);
 		return $this->match;
 	}