diff --git a/uc_attribute/uc_attribute.module b/uc_attribute/uc_attribute.module
index b8bc6c9..4703087 100644
--- a/uc_attribute/uc_attribute.module
+++ b/uc_attribute/uc_attribute.module
@@ -504,40 +504,34 @@ function uc_attribute_uc_product_class($type, $op) {
 }
 
 /**
- * Implements hook_uc_cart_item().
+ * Implements hook_uc_product_alter().
  */
-function uc_attribute_uc_cart_item($op, $item) {
-  switch ($op) {
-    case 'load':
-      if (!isset($item->data['attributes'])) {
-        return;
-      }
-
-      $options = _uc_cart_product_get_options($item);
-      foreach ($options as $option) {
-        $item->cost += $option['cost'];
-        $item->price += $option['price'];
-        $item->display_price += $option['price'];
-        $item->weight += $option['weight'];
-      }
+function uc_attribute_uc_product_alter(&$node) {
+  if (isset($node->data['attributes'])) {
+    $options = _uc_cart_product_get_options($node);
+    foreach ($options as $option) {
+      $node->cost += $option['cost'];
+      $node->price += $option['price'];
+      $node->display_price += $option['price'];
+      $node->weight += $option['weight'];
+    }
 
-      $combination = array();
-      foreach ((array)$item->data['attributes'] as $aid => $value) {
-        if (is_numeric($value)) {
-          $attribute = uc_attribute_load($aid, $item->nid, 'product');
-          if ($attribute && ($attribute->display == 1 || $attribute->display == 2)) {
-            $combination[$aid] = $value;
-          }
+    $combination = array();
+    foreach ($node->data['attributes'] as $aid => $value) {
+      if (is_numeric($value)) {
+        $attribute = uc_attribute_load($aid, $node->nid, 'product');
+        if ($attribute && ($attribute->display == 1 || $attribute->display == 2)) {
+          $combination[$aid] = $value;
         }
       }
-      ksort($combination);
+    }
+    ksort($combination);
 
-      $model = db_query("SELECT model FROM {uc_product_adjustments} WHERE nid = :nid AND combination LIKE :combo", array(':nid' => $item->nid, ':combo' => serialize($combination)))->fetchField();
+    $model = db_query("SELECT model FROM {uc_product_adjustments} WHERE nid = :nid AND combination LIKE :combo", array(':nid' => $node->nid, ':combo' => serialize($combination)))->fetchField();
 
-      if (!empty($model)) {
-        $item->model = $model;
-      }
-      break;
+    if (!empty($model)) {
+      $node->model = $model;
+    }
   }
 }
 
@@ -1263,18 +1257,21 @@ function _uc_attribute_alter_form($product) {
     // Build the attribute's options array.
     $options = array();
     foreach ($attribute->options as $option) {
+      $display_price = '';
+      $variant = uc_product_load_variant($product->nid, array('attributes' => array($attribute->aid => $option->oid)));
       switch (variable_get('uc_attribute_option_price_format', 'adjustment')) {
         case 'total':
-          $display_price = in_array($attribute->aid, $priced_attributes) ? ', ' . uc_currency_format($product->sell_price + $option->price) : '';
+          if (in_array($attribute->aid, $priced_attributes)) {
+            $display_price = uc_currency_format($variant->display_price);
+          }
           if (count($priced_attributes) == 1 && $attribute->display != 3) {
             break;
           }
         case 'adjustment':
-          $display_price = ($option->price != 0 ? ', ' . ($option->price > 0 ? '+' : '') . uc_currency_format($option->price) : '');
-          break;
-        case 'none':
-        default:
-          $display_price = '';
+          $adjustment = $variant->display_price - $product->display_price;
+          if ($adjustment) {
+            $display_price = ($adjustment > 0 ? '+' : '') . uc_currency_format($adjustment);
+          }
           break;
       }
       $options[$option->oid] = $option->name;
@@ -1282,7 +1279,9 @@ function _uc_attribute_alter_form($product) {
         // Select options are check_plain()ed, but radio button labels are not.
         $options[$option->oid] = check_plain($options[$option->oid]);
       }
-      $options[$option->oid] .= $display_price;
+      if ($display_price) {
+        $options[$option->oid] .= ', ' . $display_price;
+      }
     }
 
     if (count($attribute->options) && $attribute->display > 0) {
diff --git a/uc_cart/uc_cart.module b/uc_cart/uc_cart.module
index ca7c8f4..c9f9111 100644
--- a/uc_cart/uc_cart.module
+++ b/uc_cart/uc_cart.module
@@ -1371,37 +1371,12 @@ function uc_cart_get_item($item) {
     $item = db_query("SELECT * FROM {uc_cart_products} WHERE cart_item_id = :id", array(':id' => $item))->fetchObject();
   }
 
-  if (empty($item)) {
-    return;
-  }
-
-  $product = node_load($item->nid);
-  if (!$product) {
-    return;
+  if ($item && $product = uc_product_load_variant($item->nid, unserialize($item->data))) {
+    $product->cart_item_id = $item->cart_item_id;
+    $product->qty = $item->qty;
+    $product->module = $product->data['module'];
+    return $product;
   }
-
-  $item->vid = $product->vid;
-  $item->title = $product->title;
-  $item->cost = $product->cost;
-  $item->price = $product->sell_price;
-  $item->weight = $product->weight;
-  $item->weight_units = $product->weight_units;
-  $item->data = unserialize($item->data);
-  $item->module = $item->data['module'];
-  $item->model = $product->model;
-  $item->display_price = $product->sell_price;
-  $item->display_price_suffix = '';
-
-  // Invoke hook_uc_cart_item() with $op = 'load' in enabled modules.
-  foreach (module_implements('uc_cart_item') as $module) {
-    $func = $module . '_uc_cart_item';
-    if (function_exists($func)) {
-      // $item must be passed by reference.
-      $func('load', $item);
-    }
-  }
-
-  return $item;
 }
 
 /**
diff --git a/uc_product/uc_product.module b/uc_product/uc_product.module
index 6fc7e0b..2ee003d 100644
--- a/uc_product/uc_product.module
+++ b/uc_product/uc_product.module
@@ -689,12 +689,32 @@ function uc_product_load($nodes) {
     foreach ($node as $field => $value) {
       $nodes[$node->nid]->$field = $value;
     }
-    $nodes[$node->nid]->display_price = $node->sell_price;
-    $nodes[$node->nid]->display_price_suffix = '';
+    _uc_product_calculate($nodes[$node->nid]);
   }
 }
 
 /**
+ * Load a specific altered variant of a product.
+ */
+function uc_product_load_variant($nid, $data) {
+  $node = clone node_load($nid);
+  $node->data = $data;
+  _uc_product_calculate($node);
+  return $node;
+}
+
+/**
+ * Calculate the sale and display prices for a product.
+ */
+function _uc_product_calculate(&$node) {
+  $node->price = $node->sell_price;
+  $node->display_price = $node->price = $node->sell_price;
+  $node->display_price_suffix = '';
+
+  drupal_alter('uc_product', $node);
+}
+
+/**
  * Implements hook_delete().
  */
 function uc_product_delete(&$node) {
diff --git a/uc_product_kit/uc_product_kit.module b/uc_product_kit/uc_product_kit.module
index bc94e93..5d545cd 100644
--- a/uc_product_kit/uc_product_kit.module
+++ b/uc_product_kit/uc_product_kit.module
@@ -365,33 +365,34 @@ function uc_product_kit_load($nodes) {
     $nodes[$prod->nid]->mutable = $prod->mutable;
     $nodes[$prod->nid]->synchronized = $prod->synchronized;
 
-    // Save products in an associative array to know exactly which products
-    // belong to which kit.
-    $all_products[$prod->nid][$prod->product_id] = $prod;
-  }
-
-  foreach ($all_products as $kit_products) {
-    $products = node_load_multiple(array_keys($kit_products));
-    foreach ($products as $p) {
-      // Get our component product.
-      $prod = $kit_products[$p->nid];
-
-      // We need to clone the object to avoid changes by reference
-      // http://www.php.net/manual/en/language.references.php#93812
-      $product = clone $p;
-
-      // Add the component information.
-      $product->qty = $prod->qty;
-      $product->discount = $prod->discount;
-      $product->ordering = $prod->ordering;
-
-      // Add product to the kit.
-      $nodes[$prod->nid]->products[$product->nid] = $product;
+    // Add the component information.
+    $data = array();
+    if ($prod->mutable != UC_PRODUCT_KIT_MUTABLE) {
+      $data = array('kit_id' => $prod->nid, 'kit_discount' => $prod->discount);
     }
+    $product = uc_product_load_variant($prod->product_id, $data);
+    $product->qty = $prod->qty;
+    $product->discount = $prod->discount;
+    $product->ordering = $prod->ordering;
+
+    // Add product to the kit.
+    $nodes[$prod->nid]->products[$product->nid] = $product;
   }
 
   // Add product data to kits.
   uc_product_load($nodes);
+
+  // Recalculate display price.
+  foreach ($nodes as &$node) {
+    if ($node->mutable != UC_PRODUCT_KIT_MUTABLE) {
+      $node->display_price = 0;
+      $node->display_price_suffix = '';
+      foreach ($node->products as $pid => &$product) {
+        $node->display_price += $product->display_price * $product->qty;
+        $node->display_price_suffix .= $product->display_price_suffix;
+      }
+    }
+  }
 }
 
 /**
@@ -973,22 +974,27 @@ function uc_product_kit_uc_add_to_cart($nid, $qty, $kit_data) {
 }
 
 /**
- * Implements hook_uc_cart_item().
+ * Implements hook_uc_product_alter().
  */
-function uc_product_kit_uc_cart_item($op, $item) {
-  switch ($op) {
-    case 'load':
-      if (isset($item->data['kit_id']) && ($kit = node_load($item->data['kit_id'])) && $kit->mutable != UC_PRODUCT_KIT_MUTABLE) {
-        $kit_discount = $kit->products[$item->nid]->discount;
-        if ($kit_discount !== '') {
-          $item->price += $kit_discount;
-          $item->display_price += $kit_discount;
-        }
-      }
-    break;
+function uc_product_kit_uc_product_alter(&$node) {
+  if (isset($node->data['kit_id'])) {
+    // If this is a kit component load, we would cause infinite recursion trying
+    // to node_load() the parent, but we already have the discount available.
+    if (isset($node->data['kit_discount'])) {
+      $discount = isset($node->data['kit_discount']);
+    }
+    elseif (($kit = node_load($node->data['kit_id'])) && $kit->mutable != UC_PRODUCT_KIT_MUTABLE) {
+      $discount = $kit->products[$node->nid]->discount;
+    }
+    else {
+      $discount = 0;
+    }
+    $node->price += $discount;
+    $node->display_price += $discount;
   }
 }
 
+
 /**
  * Implements hook_uc_order_product_alter().
  *
diff --git a/uc_taxes/uc_taxes.module b/uc_taxes/uc_taxes.module
index 0dfd7c7..78e4db5 100644
--- a/uc_taxes/uc_taxes.module
+++ b/uc_taxes/uc_taxes.module
@@ -82,50 +82,16 @@ function uc_taxes_module_implements_alter(&$implementations, $hook) {
 }
 
 /**
- * Implements hook_uc_cart_item().
+ * Implements hook_uc_product_alter().
  *
  * Adds included taxes (VAT) to display price of applicable products.
  */
-function uc_taxes_uc_cart_item($op, $item) {
-  if ($op == 'load') {
-    $product = node_load($item->nid);
+function uc_taxes_uc_product_alter(&$node) {
+  list($amount, $suffixes) = uc_taxes_get_included_tax($node, $node->price);
 
-    list($amount, $suffixes) = uc_taxes_get_included_tax($product, $item->price);
-
-    $item->display_price += $amount;
-    if (!empty($suffixes)) {
-      $item->display_price_suffix .= implode(' ', $suffixes);
-    }
-  }
-}
-
-/**
- * Implements hook_node_load().
- * Adds included taxes (VAT) to display price of applicable products.
- */
-function uc_taxes_node_load($nodes, $types) {
-  foreach ($nodes as &$node) {
-    if (uc_product_is_product($node)) {
-      $amount = 0;
-      $suffixes = array();
-      if ($node->type == 'product_kit') {
-        // For product kits, the total tax is the sum of the tax on the discounted
-        // prices of component products.
-        foreach ($node->products as $pid => &$product) {
-          $discount =  ($node->mutable != UC_PRODUCT_KIT_MUTABLE) ? $product->discount : 0;
-          list($this_amount, $these_suffixes) = uc_taxes_get_included_tax($product, $product->sell_price + $discount);
-          $amount += $this_amount * $product->qty;
-          $suffixes += $these_suffixes;
-        }
-      }
-      else {
-        list($amount, $suffixes) = uc_taxes_get_included_tax($node);
-      }
-      $node->display_price += $amount;
-      if (!empty($suffixes)) {
-        $node->display_price_suffix .= implode(' ', $suffixes);
-      }
-    }
+  $node->display_price += $amount;
+  if (!empty($suffixes)) {
+    $node->display_price_suffix .= implode(' ', $suffixes);
   }
 }
 
