diff --git a/payment/uc_google_checkout/uc_google_checkout.module b/payment/uc_google_checkout/uc_google_checkout.module
index 7703798..2663f35 100644
--- a/payment/uc_google_checkout/uc_google_checkout.module
+++ b/payment/uc_google_checkout/uc_google_checkout.module
@@ -264,23 +264,6 @@ function uc_google_checkout_node_revision_delete($node) {
  ******************************************************************************/
 
 /**
- * Implements hook_uc_cart_pane().
- */
-function uc_google_checkout_uc_cart_pane() {
-  $panes['uc_google_checkout'] = array(
-    'title' => t('Google Checkout'),
-    'enabled' => TRUE,
-    'weight' => 1,
-    'body' => drupal_get_form('uc_google_checkout_cart_form') + array(
-      '#prefix' => '<div align="' . variable_get('uc_google_checkout_button_align', 'right') . '">',
-      '#suffix' => '</div>',
-    ),
-  );
-
-  return $panes;
-}
-
-/**
  * Implements hook_uc_order_pane().
  */
 function uc_google_checkout_uc_order_pane() {
@@ -456,226 +439,6 @@ function uc_google_checkout_uc_shipment($op, $shipment) {
  * Callback Functions, Forms, and Tables                                      *
  ******************************************************************************/
 
-/**
- * Form builder for uc_google_checkout_cart_form().
- *
- * @see uc_google_checkout_cart_form_submit()
- * @ingroup forms
- */
-function uc_google_checkout_cart_form($form, &$form_state) {
-  if (variable_get('uc_google_checkout_mode', 'checkout') == 'checkout') {
-    $merchant_id = variable_get('uc_google_checkout_merchant_id', '');
-    $checkout_url = 'https://checkout.google.com';
-  }
-  else {
-    $merchant_id = variable_get('uc_google_checkout_test_merchant_id', '');
-    $checkout_url = 'https://sandbox.google.com/checkout';
-  }
-  if (!$merchant_id) {
-    watchdog('google', 'Google Checkout is enabled, but no Merchant ID found.', array(), WATCHDOG_ERROR, 'admin/store/settings/google_checkout');
-    return;
-  }
-
-  global $user;
-  $id = variable_get('googleanalytics_account', '');
-  if (module_exists('googleanalytics') && !empty($id) && _googleanalytics_visibility_pages() && _googleanalytics_visibility_user($user)) {
-    $form['#attributes'] = array('onsubmit' => 'setUrchinInputCode(pageTracker);');
-  }
-
-  $disable = FALSE;
-  foreach (uc_cart_get_contents() as $item) {
-    $product = node_load($item->nid);
-    if (!$product->gc_salable) {
-      $disable = TRUE;
-      break;
-    }
-  }
-
-  switch (variable_get('uc_google_checkout_button_size', 'large')) {
-    case 'large':
-      $width = 180;
-      $height = 46;
-    break;
-    case 'medium':
-      $width = 168;
-      $height = 44;
-    break;
-    case 'small':
-      $width = 160;
-      $height = 43;
-    break;
-  }
-
-  $form['submit'] = array(
-    '#type' => 'image_button',
-    '#src' => $checkout_url . '/buttons/checkout.gif?merchant_id=' . $merchant_id . '&w=' . $width . '&h=' . $height . '&style=' . variable_get('uc_google_checkout_button_color', 'trans') . '&variant=' . ($disable ? 'disabled' : 'text') . '&loc=en_US',
-    '#disabled' => $disable,
-    '#attributes' => array(
-      'alt' => t('Google Checkout'),
-      'title' => t('Fast checkout through Google.'),
-      'height' => $height,
-      'width' => $width,
-    ),
-    '#description' => '<a href="javascript:void(window.open(\' http://checkout.google.com/seller/what_is_google_checkout.html\',\'whatischeckout\',\'scrollbars=0,resizable=1,directories=0,height=250,width=400\'));" OnMouseOver="return window.status = \'' . addslashes(t('What is Google Checkout?')) . '\';" OnMouseOut="return window.status = \'\';">' . addslashes(t('What is Google Checkout?')) . '</a>',
-  );
-
-  $form['analyticsdata'] = array(
-    '#type' => 'hidden',
-    '#default_value' => '',
-  );
-
-  return $form;
-}
-
-/**
- * Form submission handler for uc_google_checkout_cart_form().
- *
- * @see uc_google_checkout_cart_form()
- */
-function uc_google_checkout_cart_form_submit($form, &$form_state) {
-  global $user;
-  $items = uc_cart_get_contents();
-
-  if (!is_array($items) || count($items) == 0) {
-    drupal_set_message(t('You do not have any items in your shopping cart.'));
-    return;
-  }
-
-  if (empty($_SESSION['cart_order'])) {
-    $order = uc_order_new($user->uid);
-    $_SESSION['cart_order'] = $order->order_id;
-  }
-  else {
-    $order = new stdClass();
-    $order->uid = $user->uid;
-    $order->order_id = $_SESSION['cart_order'];
-    $order->primary_email = $user->mail;
-    $order->order_status = uc_order_state_default('in_checkout');
-  }
-
-  $order->products = $items;
-  uc_order_save($order);
-  uc_order_update_status($order->order_id, 'in_google_checkout');
-  $order->order_status = 'in_google_checkout';
-
-  $order->analytics_data = $form_state['values']['analyticsdata'];
-  $request = uc_google_checkout_cart_request($order);
-  if ($response = uc_google_checkout_send_request('merchantCheckout', $request)) {
-    $redirect = (string) $response->{'redirect-url'};
-    drupal_goto($redirect);
-  }
-}
-
-function uc_google_checkout_cart_request($order) {
-  if (variable_get('uc_google_checkout_mode', 'checkout') == 'checkout') {
-    $merchant_id = variable_get('uc_google_checkout_merchant_id', '');
-  }
-  else {
-    $merchant_id = variable_get('uc_google_checkout_test_merchant_id', '');
-  }
-
-  $output = '<?xml version="1.0" encoding="UTF-8"?>';
-  $output .= "\n";
-
-  if (count($order->products)) {
-    $output .= '<checkout-shopping-cart xmlns="http://checkout.google.com/schema/2">';
-    $output .= '<shopping-cart>';
-    $output .= '<items>';
-    foreach ($order->products as $product) {
-      $output .= '<item>';
-      $output .= '<item-name>' . check_plain($product->model) . '</item-name>';
-      $output .= '<item-description>' . check_plain($product->title) . '</item-description>';
-      $output .= '<unit-price currency="' . variable_get('uc_currency_code', 'USD') . '">' . $product->price . '</unit-price>';
-      $output .= '<item-weight unit="LB" value="' . $product->weight * uc_weight_conversion($product->weight_units, 'lb') . '" />';
-      if (!uc_cart_product_is_shippable($product)) {
-        $output .= '<digital-content>';
-          $output .= '<display-disposition>PESSIMISTIC</display-disposition>';
-          $output .= '<email-delivery>true</email-delivery>';
-        $output .= '</digital-content>';
-      }
-      $output .= '<quantity>' . $product->qty . '</quantity>';
-      $output .= '<merchant-item-id>' . $product->nid . '|' . $product->model . '</merchant-item-id>';
-      $output .= '</item>';
-    }
-    $output .= '</items>';
-    $output .= '<merchant-private-data>';
-    $output .= '<cart-id>' . uc_cart_get_id() . '</cart-id>';
-    $output .= '<order-id>' . $order->order_id . '</order-id>';
-    $output .= '</merchant-private-data>';
-    $output .= '</shopping-cart>';
-    $output .= '<checkout-flow-support>';
-    $output .= '<merchant-checkout-flow-support>';
-
-    if (uc_order_is_shippable($order)) {
-      $output .= '<shipping-methods>';
-
-      $order->delivery_city = variable_get('uc_google_checkout_delivery_city', '');
-      $order->delivery_zone = variable_get('uc_google_checkout_delivery_zone', 0);
-      $order->delivery_country = variable_get('uc_google_checkout_delivery_country', 0);
-      $order->delivery_postal_code = variable_get('uc_google_checkout_delivery_postal_code', '');
-
-      $methods = module_invoke_all('shipping_method');
-      module_load_include('inc', 'uc_quote', 'uc_quote.pages');
-      $quote_data = uc_quote_assemble_quotes($order);
-      foreach ($quote_data as $method_id => $options) {
-        foreach ($options as $accsrl => $data) {
-          if (isset($data['rate'])) {
-            $output .= '<merchant-calculated-shipping name="' . check_plain($methods[$method_id]['quote']['accessorials'][$accsrl]) . '">';
-            $output .= '<price currency="' . variable_get('uc_currency_code', 'USD') . '">' . $data['rate'] . '</price>';
-            $output .= '</merchant-calculated-shipping>';
-          }
-        }
-      }
-
-      $output .= '</shipping-methods>';
-      $output .= '<merchant-calculations>';
-      $output .= '<merchant-calculations-url>' . url('google_checkout/calculations', array('absolute' => TRUE)) . '</merchant-calculations-url>';
-      $output .= '</merchant-calculations>';
-    }
-
-    $output .= '<analytics-data>' . $order->analytics_data . '</analytics-data>';
-
-    $tax_table = '';
-    $result = db_query("SELECT zone, rate, tax_shipping FROM {uc_gc_taxes}");
-    foreach ($result as $tax) {
-      $tax_table .= '<default-tax-rule>';
-      if ($tax->tax_shipping) {
-        $tax_table .= '<shipping-taxed>true</shipping-taxed>';
-      }
-      $tax_table .= '<rate>' . (float)$tax->rate . '</rate>';
-
-      $tax_table .= '<tax-area>';
-      $tax_table .= '<us-state-area>';
-      $tax_table .= '<state>' . $tax->zone . '</state>';
-      $tax_table .= '</us-state-area>';
-      $tax_table .= '</tax-area>';
-
-      $tax_table .= '</default-tax-rule>';
-    }
-
-    if ($tax_table) {
-      $output .= '<tax-tables>';
-      $output .= '<default-tax-table>';
-      $output .= '<tax-rules>';
-      $output .= $tax_table;
-      $output .= '</tax-rules>';
-      $output .= '</default-tax-table>';
-      $output .= '</tax-tables>';
-    }
-
-    $output .= '<edit-cart-url>' . url('cart', array('absolute' => TRUE)) . '</edit-cart-url>';
-    if (($page = variable_get('uc_continue_shopping_url', '')) != '<none>') {
-      $output .= '<continue-shopping-url>' . url($page, array('absolute' => TRUE)) . '</continue-shopping-url>';
-    }
-    $output .= '<platform-id>218752253180456</platform-id>';
-    $output .= '</merchant-checkout-flow-support>';
-    $output .= '</checkout-flow-support>';
-    $output .= '</checkout-shopping-cart>';
-  }
-
-  return $output;
-}
-
 function uc_google_checkout_headers() {
   if (variable_get('uc_google_checkout_mode', 'checkout') == 'checkout') {
     $merchant_id = variable_get('uc_google_checkout_merchant_id', '');
diff --git a/payment/uc_google_checkout/uc_google_checkout.uc_cart.inc b/payment/uc_google_checkout/uc_google_checkout.uc_cart.inc
new file mode 100644
index 0000000..3238bc1
--- /dev/null
+++ b/payment/uc_google_checkout/uc_google_checkout.uc_cart.inc
@@ -0,0 +1,243 @@
+<?php
+
+/**
+ * @file
+ * Cart hook implementations for Google Checkout.
+ */
+
+/**
+ * Implements hook_uc_cart_pane().
+ */
+function uc_google_checkout_uc_cart_pane() {
+  $panes['uc_google_checkout'] = array(
+    'title' => t('Google Checkout'),
+    'enabled' => TRUE,
+    'weight' => 1,
+    'body' => drupal_get_form('uc_google_checkout_cart_form') + array(
+      '#prefix' => '<div align="' . variable_get('uc_google_checkout_button_align', 'right') . '">',
+      '#suffix' => '</div>',
+    ),
+  );
+
+  return $panes;
+}
+
+/**
+ * Form builder for uc_google_checkout_cart_form().
+ *
+ * @see uc_google_checkout_cart_form_submit()
+ * @ingroup forms
+ */
+function uc_google_checkout_cart_form($form, &$form_state) {
+  if (variable_get('uc_google_checkout_mode', 'checkout') == 'checkout') {
+    $merchant_id = variable_get('uc_google_checkout_merchant_id', '');
+    $checkout_url = 'https://checkout.google.com';
+  }
+  else {
+    $merchant_id = variable_get('uc_google_checkout_test_merchant_id', '');
+    $checkout_url = 'https://sandbox.google.com/checkout';
+  }
+  if (!$merchant_id) {
+    watchdog('google', 'Google Checkout is enabled, but no Merchant ID found.', array(), WATCHDOG_ERROR, 'admin/store/settings/google_checkout');
+    return;
+  }
+
+  global $user;
+  $id = variable_get('googleanalytics_account', '');
+  if (module_exists('googleanalytics') && !empty($id) && _googleanalytics_visibility_pages() && _googleanalytics_visibility_user($user)) {
+    $form['#attributes'] = array('onsubmit' => 'setUrchinInputCode(pageTracker);');
+  }
+
+  $disable = FALSE;
+  foreach (uc_cart_get_contents() as $item) {
+    $product = node_load($item->nid);
+    if (!$product->gc_salable) {
+      $disable = TRUE;
+      break;
+    }
+  }
+
+  switch (variable_get('uc_google_checkout_button_size', 'large')) {
+    case 'large':
+      $width = 180;
+      $height = 46;
+    break;
+    case 'medium':
+      $width = 168;
+      $height = 44;
+    break;
+    case 'small':
+      $width = 160;
+      $height = 43;
+    break;
+  }
+
+  $form['submit'] = array(
+    '#type' => 'image_button',
+    '#src' => $checkout_url . '/buttons/checkout.gif?merchant_id=' . $merchant_id . '&w=' . $width . '&h=' . $height . '&style=' . variable_get('uc_google_checkout_button_color', 'trans') . '&variant=' . ($disable ? 'disabled' : 'text') . '&loc=en_US',
+    '#disabled' => $disable,
+    '#attributes' => array(
+      'alt' => t('Google Checkout'),
+      'title' => t('Fast checkout through Google.'),
+      'height' => $height,
+      'width' => $width,
+    ),
+    '#description' => '<a href="javascript:void(window.open(\' http://checkout.google.com/seller/what_is_google_checkout.html\',\'whatischeckout\',\'scrollbars=0,resizable=1,directories=0,height=250,width=400\'));" OnMouseOver="return window.status = \'' . addslashes(t('What is Google Checkout?')) . '\';" OnMouseOut="return window.status = \'\';">' . addslashes(t('What is Google Checkout?')) . '</a>',
+  );
+
+  $form['analyticsdata'] = array(
+    '#type' => 'hidden',
+    '#default_value' => '',
+  );
+
+  return $form;
+}
+
+/**
+ * Form submission handler for uc_google_checkout_cart_form().
+ *
+ * @see uc_google_checkout_cart_form()
+ */
+function uc_google_checkout_cart_form_submit($form, &$form_state) {
+  global $user;
+  $items = uc_cart_get_contents();
+
+  if (!is_array($items) || count($items) == 0) {
+    drupal_set_message(t('You do not have any items in your shopping cart.'));
+    return;
+  }
+
+  if (empty($_SESSION['cart_order'])) {
+    $order = uc_order_new($user->uid);
+    $_SESSION['cart_order'] = $order->order_id;
+  }
+  else {
+    $order = new stdClass();
+    $order->uid = $user->uid;
+    $order->order_id = $_SESSION['cart_order'];
+    $order->primary_email = $user->mail;
+    $order->order_status = uc_order_state_default('in_checkout');
+  }
+
+  $order->products = $items;
+  uc_order_save($order);
+  uc_order_update_status($order->order_id, 'in_google_checkout');
+  $order->order_status = 'in_google_checkout';
+
+  $order->analytics_data = $form_state['values']['analyticsdata'];
+  $request = uc_google_checkout_cart_request($order);
+  if ($response = uc_google_checkout_send_request('merchantCheckout', $request)) {
+    $redirect = (string) $response->{'redirect-url'};
+    drupal_goto($redirect);
+  }
+}
+
+function uc_google_checkout_cart_request($order) {
+  if (variable_get('uc_google_checkout_mode', 'checkout') == 'checkout') {
+    $merchant_id = variable_get('uc_google_checkout_merchant_id', '');
+  }
+  else {
+    $merchant_id = variable_get('uc_google_checkout_test_merchant_id', '');
+  }
+
+  $output = '<?xml version="1.0" encoding="UTF-8"?>';
+  $output .= "\n";
+
+  if (count($order->products)) {
+    $output .= '<checkout-shopping-cart xmlns="http://checkout.google.com/schema/2">';
+    $output .= '<shopping-cart>';
+    $output .= '<items>';
+    foreach ($order->products as $product) {
+      $output .= '<item>';
+      $output .= '<item-name>' . check_plain($product->model) . '</item-name>';
+      $output .= '<item-description>' . check_plain($product->title) . '</item-description>';
+      $output .= '<unit-price currency="' . variable_get('uc_currency_code', 'USD') . '">' . $product->price . '</unit-price>';
+      $output .= '<item-weight unit="LB" value="' . $product->weight * uc_weight_conversion($product->weight_units, 'lb') . '" />';
+      if (!uc_cart_product_is_shippable($product)) {
+        $output .= '<digital-content>';
+          $output .= '<display-disposition>PESSIMISTIC</display-disposition>';
+          $output .= '<email-delivery>true</email-delivery>';
+        $output .= '</digital-content>';
+      }
+      $output .= '<quantity>' . $product->qty . '</quantity>';
+      $output .= '<merchant-item-id>' . $product->nid . '|' . $product->model . '</merchant-item-id>';
+      $output .= '</item>';
+    }
+    $output .= '</items>';
+    $output .= '<merchant-private-data>';
+    $output .= '<cart-id>' . uc_cart_get_id() . '</cart-id>';
+    $output .= '<order-id>' . $order->order_id . '</order-id>';
+    $output .= '</merchant-private-data>';
+    $output .= '</shopping-cart>';
+    $output .= '<checkout-flow-support>';
+    $output .= '<merchant-checkout-flow-support>';
+
+    if (uc_order_is_shippable($order)) {
+      $output .= '<shipping-methods>';
+
+      $order->delivery_city = variable_get('uc_google_checkout_delivery_city', '');
+      $order->delivery_zone = variable_get('uc_google_checkout_delivery_zone', 0);
+      $order->delivery_country = variable_get('uc_google_checkout_delivery_country', 0);
+      $order->delivery_postal_code = variable_get('uc_google_checkout_delivery_postal_code', '');
+
+      $methods = module_invoke_all('shipping_method');
+      module_load_include('inc', 'uc_quote', 'uc_quote.pages');
+      $quote_data = uc_quote_assemble_quotes($order);
+      foreach ($quote_data as $method_id => $options) {
+        foreach ($options as $accsrl => $data) {
+          if (isset($data['rate'])) {
+            $output .= '<merchant-calculated-shipping name="' . check_plain($methods[$method_id]['quote']['accessorials'][$accsrl]) . '">';
+            $output .= '<price currency="' . variable_get('uc_currency_code', 'USD') . '">' . $data['rate'] . '</price>';
+            $output .= '</merchant-calculated-shipping>';
+          }
+        }
+      }
+
+      $output .= '</shipping-methods>';
+      $output .= '<merchant-calculations>';
+      $output .= '<merchant-calculations-url>' . url('google_checkout/calculations', array('absolute' => TRUE)) . '</merchant-calculations-url>';
+      $output .= '</merchant-calculations>';
+    }
+
+    $output .= '<analytics-data>' . $order->analytics_data . '</analytics-data>';
+
+    $tax_table = '';
+    $result = db_query("SELECT zone, rate, tax_shipping FROM {uc_gc_taxes}");
+    foreach ($result as $tax) {
+      $tax_table .= '<default-tax-rule>';
+      if ($tax->tax_shipping) {
+        $tax_table .= '<shipping-taxed>true</shipping-taxed>';
+      }
+      $tax_table .= '<rate>' . (float)$tax->rate . '</rate>';
+
+      $tax_table .= '<tax-area>';
+      $tax_table .= '<us-state-area>';
+      $tax_table .= '<state>' . $tax->zone . '</state>';
+      $tax_table .= '</us-state-area>';
+      $tax_table .= '</tax-area>';
+
+      $tax_table .= '</default-tax-rule>';
+    }
+
+    if ($tax_table) {
+      $output .= '<tax-tables>';
+      $output .= '<default-tax-table>';
+      $output .= '<tax-rules>';
+      $output .= $tax_table;
+      $output .= '</tax-rules>';
+      $output .= '</default-tax-table>';
+      $output .= '</tax-tables>';
+    }
+
+    $output .= '<edit-cart-url>' . url('cart', array('absolute' => TRUE)) . '</edit-cart-url>';
+    if (($page = variable_get('uc_continue_shopping_url', '')) != '<none>') {
+      $output .= '<continue-shopping-url>' . url($page, array('absolute' => TRUE)) . '</continue-shopping-url>';
+    }
+    $output .= '<platform-id>218752253180456</platform-id>';
+    $output .= '</merchant-checkout-flow-support>';
+    $output .= '</checkout-flow-support>';
+    $output .= '</checkout-shopping-cart>';
+  }
+
+  return $output;
+}
diff --git a/payment/uc_paypal/uc_paypal.module b/payment/uc_paypal/uc_paypal.module
index be3f404..a4a2ad1 100644
--- a/payment/uc_paypal/uc_paypal.module
+++ b/payment/uc_paypal/uc_paypal.module
@@ -108,23 +108,6 @@ function uc_paypal_form_uc_cart_checkout_review_form_alter(&$form, &$form_state,
  ******************************************************************************/
 
 /**
- * Implements hook_uc_cart_pane().
- */
-function uc_paypal_uc_cart_pane() {
-  $panes['uc_paypal_ec'] = array(
-    'title' => t('PayPal Express Checkout'),
-    'enabled' => FALSE,
-    'weight' => 1,
-    'body' => drupal_get_form('uc_paypal_ec_form') + array(
-      '#prefix' => '<div align="right">',
-      '#suffix' => '</div>',
-    ),
-  );
-
-  return $panes;
-}
-
-/**
  * Implements hook_uc_payment_gateway().
  */
 function uc_paypal_uc_payment_gateway() {
@@ -708,74 +691,6 @@ function uc_paypal_ec_checkout($form, &$form_state) {
   exit();
 }
 
-/**
- * Returns the form for Express Checkout Shortcut Flow.
- *
- * @see uc_paypal_ec_form_submit()
- */
-function uc_paypal_ec_form($form, &$form_state) {
-  if (!variable_get('uc_cap_uc_paypal_ec_enabled', FALSE)) {
-    return;
-  }
-
-  $form['submit'] = array(
-    '#type' => 'image_button',
-    '#src' => 'https://www.paypal.com/en_US/i/btn/btn_xpressCheckoutsm.gif',
-    '#title' => t('Checkout with PayPal.'),
-  );
-
-  return $form;
-}
-
-/**
- * Submit handler for uc_paypal_ec_form().
- *
- * @see uc_paypal_ec_form()
- */
-function uc_paypal_ec_form_submit($form, &$form_state) {
-  global $user;
-  $items = uc_cart_get_contents();
-
-  if (!is_array($items) || count($items) == 0) {
-    drupal_set_message(t('You do not have any items in your shopping cart.'));
-    return;
-  }
-
-  list($desc, $subtotal) = _uc_paypal_product_details($items);
-
-  $order = uc_order_new($user->uid);
-
-  $nvp_request = array(
-    'METHOD' => 'SetExpressCheckout',
-    'RETURNURL' => url('cart/echeckout/review', array('absolute' => TRUE)),
-    'CANCELURL' => url('uc_paypal/wps/cancel', array('absolute' => TRUE)),
-    'AMT' => uc_currency_format($subtotal, FALSE, FALSE, '.'),
-    'CURRENCYCODE' => variable_get('uc_paypal_wpp_currency', 'USD'),
-    'PAYMENTACTION' => variable_get('uc_paypal_wpp_payment_action', 'Sale'),
-    'DESC' => substr($desc, 0, 127),
-    'INVNUM' => $order->order_id . '-' . REQUEST_TIME,
-    'REQCONFIRMSHIPPING' => variable_get('uc_paypal_ec_rqconfirmed_addr', 0),
-    'BUTTONSOURCE' => 'Ubercart_ShoppingCart_EC_US',
-    'NOTIFYURL' => url('uc_paypal/ipn/' . $order->order_id, array('absolute' => TRUE)),
-    'LANDINGPAGE' => variable_get('uc_paypal_ec_landingpage_style', 'Billing'),
-  );
-
-  $order->products = $items;
-  uc_order_save($order);
-
-  $nvp_response = uc_paypal_api_request($nvp_request, variable_get('uc_paypal_wpp_server', 'https://api-3t.sandbox.paypal.com/nvp'));
-
-  $_SESSION['cart_order'] = $order->order_id;
-  $_SESSION['TOKEN'] = $nvp_response['TOKEN'];
-
-  if (strpos(variable_get('uc_paypal_wpp_server', 'https://api-3t.sandbox.paypal.com/nvp'), 'sandbox') > 0) {
-    $sandbox = 'sandbox.';
-  }
-
-  header('Location: https://www.' . $sandbox . 'paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=' . $_SESSION['TOKEN']);
-  exit();
-}
-
 function uc_paypal_ec_submit_form_submit($form, &$form_state) {
   $order = uc_order_load($_SESSION['cart_order']);
 
diff --git a/payment/uc_paypal/uc_paypal.uc_cart.inc b/payment/uc_paypal/uc_paypal.uc_cart.inc
new file mode 100644
index 0000000..42a66ef
--- /dev/null
+++ b/payment/uc_paypal/uc_paypal.uc_cart.inc
@@ -0,0 +1,86 @@
+<?php
+
+/**
+ * Implements hook_uc_cart_pane().
+ */
+function uc_paypal_uc_cart_pane() {
+  $panes['uc_paypal_ec'] = array(
+    'title' => t('PayPal Express Checkout'),
+    'enabled' => FALSE,
+    'weight' => 1,
+    'body' => drupal_get_form('uc_paypal_ec_form') + array(
+      '#prefix' => '<div align="right">',
+      '#suffix' => '</div>',
+    ),
+  );
+
+  return $panes;
+}
+
+/**
+ * Returns the form for Express Checkout Shortcut Flow.
+ *
+ * @see uc_paypal_ec_form_submit()
+ */
+function uc_paypal_ec_form($form, &$form_state) {
+  if (!variable_get('uc_cap_uc_paypal_ec_enabled', FALSE)) {
+    return;
+  }
+
+  $form['submit'] = array(
+    '#type' => 'image_button',
+    '#src' => 'https://www.paypal.com/en_US/i/btn/btn_xpressCheckoutsm.gif',
+    '#title' => t('Checkout with PayPal.'),
+  );
+
+  return $form;
+}
+
+/**
+ * Submit handler for uc_paypal_ec_form().
+ *
+ * @see uc_paypal_ec_form()
+ */
+function uc_paypal_ec_form_submit($form, &$form_state) {
+  global $user;
+  $items = uc_cart_get_contents();
+
+  if (!is_array($items) || count($items) == 0) {
+    drupal_set_message(t('You do not have any items in your shopping cart.'));
+    return;
+  }
+
+  list($desc, $subtotal) = _uc_paypal_product_details($items);
+
+  $order = uc_order_new($user->uid);
+
+  $nvp_request = array(
+    'METHOD' => 'SetExpressCheckout',
+    'RETURNURL' => url('cart/echeckout/review', array('absolute' => TRUE)),
+    'CANCELURL' => url('uc_paypal/wps/cancel', array('absolute' => TRUE)),
+    'AMT' => uc_currency_format($subtotal, FALSE, FALSE, '.'),
+    'CURRENCYCODE' => variable_get('uc_paypal_wpp_currency', 'USD'),
+    'PAYMENTACTION' => variable_get('uc_paypal_wpp_payment_action', 'Sale'),
+    'DESC' => substr($desc, 0, 127),
+    'INVNUM' => $order->order_id . '-' . REQUEST_TIME,
+    'REQCONFIRMSHIPPING' => variable_get('uc_paypal_ec_rqconfirmed_addr', 0),
+    'BUTTONSOURCE' => 'Ubercart_ShoppingCart_EC_US',
+    'NOTIFYURL' => url('uc_paypal/ipn/' . $order->order_id, array('absolute' => TRUE)),
+    'LANDINGPAGE' => variable_get('uc_paypal_ec_landingpage_style', 'Billing'),
+  );
+
+  $order->products = $items;
+  uc_order_save($order);
+
+  $nvp_response = uc_paypal_api_request($nvp_request, variable_get('uc_paypal_wpp_server', 'https://api-3t.sandbox.paypal.com/nvp'));
+
+  $_SESSION['cart_order'] = $order->order_id;
+  $_SESSION['TOKEN'] = $nvp_response['TOKEN'];
+
+  if (strpos(variable_get('uc_paypal_wpp_server', 'https://api-3t.sandbox.paypal.com/nvp'), 'sandbox') > 0) {
+    $sandbox = 'sandbox.';
+  }
+
+  header('Location: https://www.' . $sandbox . 'paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=' . $_SESSION['TOKEN']);
+  exit();
+}
diff --git a/shipping/uc_quote/uc_quote.module b/shipping/uc_quote/uc_quote.module
index 755f6f4..5428889 100644
--- a/shipping/uc_quote/uc_quote.module
+++ b/shipping/uc_quote/uc_quote.module
@@ -93,6 +93,7 @@ function uc_quote_theme() {
     ),
     'uc_cart_pane_quotes' => array(
       'render element' => 'form',
+      'file' => 'uc_quote.uc_cart.inc',
     ),
     'uc_quote_returned_rates' => array(
       'render element' => 'form',
@@ -305,31 +306,6 @@ function uc_quote_process_checkout_address($element, $form_state) {
  ******************************************************************************/
 
 /**
- * Implements hook_uc_cart_pane().
- */
-function uc_quote_uc_cart_pane($items) {
-  if (arg(0) == 'cart') {
-    if (!variable_get('uc_cap_quotes_enabled', FALSE) || (variable_get('uc_cart_delivery_not_shippable', TRUE) && !uc_cart_is_shippable())) {
-      return array();
-    }
-
-    $body = drupal_get_form('uc_cart_pane_quotes', $items);
-  }
-  else {
-    $body = '';
-  }
-
-  $panes['quotes'] = array(
-    'title' => t('Shipping quotes'),
-    'enabled' => FALSE,
-    'weight' => 5,
-    'body' => $body,
-  );
-
-  return $panes;
-}
-
-/**
  * Defines the shipping quote checkout pane.
  */
 function uc_quote_uc_checkout_pane() {
@@ -521,88 +497,6 @@ function uc_quote_get_default_shipping_address($nid) {
 }
 
 /**
- * Cart pane callback.
- *
- * @see theme_uc_cart_pane_quotes()
- * @ingroup forms
- */
-function uc_cart_pane_quotes($form, &$form_state, $items) {
-  global $user;
-
-  $order = new UcOrder();
-  $order->uid = $user->uid;
-  $order->delivery_country = isset($form_state['values']['delivery_country']) ? $form_state['values']['delivery_country'] : uc_store_default_country();
-  $order->delivery_zone = isset($form_state['values']['delivery_zone']) ? $form_state['values']['delivery_zone'] : '';
-  $order->delivery_postal_code = isset($form_state['values']['delivery_postal_code']) ? $form_state['values']['delivery_postal_code'] : '';
-  $order->products = $items;
-
-  $form['address'] = array(
-    '#type' => 'uc_address',
-    '#default_value' => array(
-      'delivery_country' => $order->delivery_country,
-      'delivery_zone' => $order->delivery_zone,
-      'delivery_postal_code' => $order->delivery_postal_code,
-    ),
-    '#required' => TRUE,
-    '#key_prefix' => 'delivery',
-  );
-
-  $form['get_quote'] = array(
-    '#type' => 'button',
-    '#value' => t('Calculate'),
-    '#ajax' => array(
-      'callback' => 'uc_quote_cart_returned_rates',
-      'wrapper' => 'quote',
-    ),
-  );
-  $form['page'] = array(
-    '#type' => 'hidden',
-    '#value' => 'cart',
-  );
-
-  module_load_include('inc', 'uc_quote', 'uc_quote.pages');
-  $quotes = uc_quote_assemble_quotes($order);
-
-  $quote_options = array();
-  if (!empty($quotes)) {
-    foreach ($quotes as $method => $data) {
-      foreach ($data as $accessorial => $quote) {
-        $key = $method . '---' . $accessorial;
-
-        if (isset($quote['rate'])) {
-          $quote_options[$key] = t('!label: !price', array('!label' => $quote['option_label'], '!price' => $quote['format']));
-        }
-      }
-    }
-  }
-
-  $form['quote'] = array(
-    '#theme' => 'item_list',
-    '#items' => $quote_options,
-    '#prefix' => '<div id="quote"><div class="solid-border">',
-    '#suffix' => '</div></div>',
-  );
-
-  return $form;
-}
-
-/**
- * Displays the formatted quote cart pane.
- *
- * @ingroup themeable
- */
-function theme_uc_cart_pane_quotes($variables) {
-  $form = $variables['form'];
-
-  $output = '<div class="solid-border">';
-  $output .= '<p><strong>' . t('Estimated shipping cost:') . '</strong></p>';
-  $output .= drupal_render_children($form);
-  $output .= '</div>';
-
-  return $output;
-}
-
-/**
  * Shipping quote checkout pane callback.
  *
  * Selects a quoting method based on the enabled methods' weight and the types
diff --git a/shipping/uc_quote/uc_quote.uc_cart.inc b/shipping/uc_quote/uc_quote.uc_cart.inc
new file mode 100644
index 0000000..429e602
--- /dev/null
+++ b/shipping/uc_quote/uc_quote.uc_cart.inc
@@ -0,0 +1,113 @@
+<?php
+
+/**
+ * @file
+ * Cart hook implementations for shipping quotes.
+ */
+
+/**
+ * Implements hook_uc_cart_pane().
+ */
+function uc_quote_uc_cart_pane($items) {
+  if (arg(0) == 'cart') {
+    if (!variable_get('uc_cap_quotes_enabled', FALSE) || (variable_get('uc_cart_delivery_not_shippable', TRUE) && !uc_cart_is_shippable())) {
+      return array();
+    }
+
+    $body = drupal_get_form('uc_cart_pane_quotes', $items);
+  }
+  else {
+    $body = '';
+  }
+
+  $panes['quotes'] = array(
+    'title' => t('Shipping quotes'),
+    'enabled' => FALSE,
+    'weight' => 5,
+    'body' => $body,
+  );
+
+  return $panes;
+}
+
+/**
+ * Cart pane callback.
+ *
+ * @see theme_uc_cart_pane_quotes()
+ * @ingroup forms
+ */
+function uc_cart_pane_quotes($form, &$form_state, $items) {
+  global $user;
+
+  $order = new UcOrder();
+  $order->uid = $user->uid;
+  $order->delivery_country = isset($form_state['values']['delivery_country']) ? $form_state['values']['delivery_country'] : uc_store_default_country();
+  $order->delivery_zone = isset($form_state['values']['delivery_zone']) ? $form_state['values']['delivery_zone'] : '';
+  $order->delivery_postal_code = isset($form_state['values']['delivery_postal_code']) ? $form_state['values']['delivery_postal_code'] : '';
+  $order->products = $items;
+
+  $form['address'] = array(
+    '#type' => 'uc_address',
+    '#default_value' => array(
+      'delivery_country' => $order->delivery_country,
+      'delivery_zone' => $order->delivery_zone,
+      'delivery_postal_code' => $order->delivery_postal_code,
+    ),
+    '#required' => TRUE,
+    '#key_prefix' => 'delivery',
+  );
+
+  $form['get_quote'] = array(
+    '#type' => 'button',
+    '#value' => t('Calculate'),
+    '#ajax' => array(
+      'callback' => 'uc_quote_cart_returned_rates',
+      'wrapper' => 'quote',
+    ),
+  );
+  $form['page'] = array(
+    '#type' => 'hidden',
+    '#value' => 'cart',
+  );
+
+  module_load_include('inc', 'uc_quote', 'uc_quote.pages');
+  $quotes = uc_quote_assemble_quotes($order);
+
+  $quote_options = array();
+  if (!empty($quotes)) {
+    foreach ($quotes as $method => $data) {
+      foreach ($data as $accessorial => $quote) {
+        $key = $method . '---' . $accessorial;
+
+        if (isset($quote['rate'])) {
+          $quote_options[$key] = t('!label: !price', array('!label' => $quote['option_label'], '!price' => $quote['format']));
+        }
+      }
+    }
+  }
+
+  $form['quote'] = array(
+    '#theme' => 'item_list',
+    '#items' => $quote_options,
+    '#prefix' => '<div id="quote"><div class="solid-border">',
+    '#suffix' => '</div></div>',
+  );
+
+  return $form;
+}
+
+/**
+ * Displays the formatted quote cart pane.
+ *
+ * @ingroup themeable
+ */
+function theme_uc_cart_pane_quotes($variables) {
+  $form = $variables['form'];
+
+  $output = '<div class="solid-border">';
+  $output .= '<p><strong>' . t('Estimated shipping cost:') . '</strong></p>';
+  $output .= drupal_render_children($form);
+  $output .= '</div>';
+
+  return $output;
+}
diff --git a/uc_cart/uc_cart.module b/uc_cart/uc_cart.module
index de71cf8..8ac8959 100644
--- a/uc_cart/uc_cart.module
+++ b/uc_cart/uc_cart.module
@@ -131,6 +131,15 @@ function uc_cart_menu() {
 }
 
 /**
+ * Implements hook_hook_info().
+ */
+function uc_cart_hook_info() {
+  $hooks['uc_cart_pane']['group'] = 'uc_cart';
+
+  return $hooks;
+}
+
+/**
  * Implements hook_image_default_styles().
  */
 function uc_cart_image_default_styles() {
@@ -199,9 +208,11 @@ function uc_cart_theme() {
     ),
     'uc_cart_view_form' => array(
       'render element' => 'form',
+      'file' => 'uc_cart.uc_cart.inc',
     ),
     'uc_cart_view_price' => array(
       'render element' => 'form',
+      'file' => 'uc_cart.uc_cart.inc',
     ),
     'uc_address_pane' => array(
       'render element' => 'form',
@@ -753,29 +764,6 @@ function uc_cart_uc_message() {
 }
 
 /**
- * Implements hook_uc_cart_pane().
- */
-function uc_cart_uc_cart_pane($items) {
-  $body = array();
-
-  if (!is_null($items)) {
-    $body = drupal_get_form('uc_cart_view_form', $items) + array(
-      '#prefix' => '<div id="cart-form-pane">',
-      '#suffix' => '</div>',
-    );
-  }
-
-  $panes['cart_form'] = array(
-    'title' => t('Default cart form'),
-    'enabled' => TRUE,
-    'weight' => 0,
-    'body' => $body,
-  );
-
-  return $panes;
-}
-
-/**
  * Implements hook_uc_checkout_pane().
  */
 function uc_cart_uc_checkout_pane() {
@@ -876,262 +864,6 @@ function theme_uc_empty_cart() {
   return '<p>' . t('There are no products in your shopping cart.') . '</p>';
 }
 
-/**
- * Display a page allowing the customer to view the contents of his or her cart.
- *
- * Handles simple or complex objects. Some cart items may have a list of
- * products that they represent. These are displayed but are not able to
- * be changed by the customer.
- *
- * @see uc_cart_view_form_submit()
- * @see theme_uc_cart_view_form()
- * @see theme_uc_cart_view_price()
- * @see uc_cart_view_table()
- * @ingroup forms
- */
-function uc_cart_view_form($form, &$form_state, $items = NULL) {
-  $form['items'] = array(
-    '#type' => 'tapir_table',
-    '#tree' => TRUE,
-  );
-
-  $i = 0;
-  foreach ($items as $item) {
-    module_invoke_all('uc_cart_item', 'view', $item);
-    $display_item = module_invoke($item->module, 'uc_cart_display', $item);
-    if (!empty($display_item)) {
-      $form['items'][$i] = $display_item;
-      $form['items'][$i]['image'] = uc_product_get_picture($display_item['nid']['#value'], 'uc_cart');
-
-      $description = $display_item['title']['#markup'] . $display_item['description']['#markup'];
-      $form['items'][$i]['desc']['#markup'] = $description;
-
-      $form['items'][$i]['cart_item_id'] = array(
-        '#type' => 'hidden',
-        '#value' => $item->cart_item_id,
-      );
-
-      if (isset($form['items'][$i]['remove'])) {
-        // Backward compatibility with old checkbox method.
-        if ($form['items'][$i]['remove']['#type'] == 'checkbox') {
-          $form['items'][$i]['remove'] = array('#type' => 'submit', '#value' => t('Remove'));
-        }
-
-        $form['items'][$i]['remove']['#name'] = 'remove-' . $i;
-      }
-
-      $form['items'][$i]['title']['#type'] = 'value';
-      $form['items'][$i]['description']['#type'] = 'value';
-
-      if (empty($display_item['qty'])) {
-        $form['items'][$i]['qty'] = array(
-          '#type' => 'hidden',
-          '#value' => 0,
-        );
-      }
-
-      $form['items'][$i]['total'] = array(
-        '#theme' => 'uc_price',
-        '#price' => $display_item['#total'],
-      );
-      $i++;
-    }
-  }
-
-  $form['items'] = tapir_get_table('uc_cart_view_table', $form['items']);
-
-  $form['actions'] = array('#type' => 'actions');
-
-  // If the continue shopping element is enabled...
-  if (($cs_type = variable_get('uc_continue_shopping_type', 'link')) !== 'none') {
-    // Setup the text used for the element.
-    $cs_text = variable_get('uc_continue_shopping_text', '') ? variable_get('uc_continue_shopping_text', '') : t('Continue shopping');
-
-    // Add the element to the form based on the element type.
-    if (variable_get('uc_continue_shopping_type', 'link') == 'link') {
-      $form['continue_shopping'] = array(
-        '#markup' => l($cs_text, uc_cart_continue_shopping_url()),
-      );
-    }
-    elseif (variable_get('uc_continue_shopping_type', 'link') == 'button') {
-      $form['actions']['continue_shopping'] = array(
-        '#type' => 'submit',
-        '#value' => $cs_text,
-      );
-      $form['continue_shopping_text'] = array(
-        '#type' => 'hidden',
-        '#value' => $cs_text,
-      );
-    }
-  }
-
-  // Add the control buttons for updating and proceeding to checkout.
-  $form['actions']['update'] = array(
-    '#type' => 'submit',
-    '#value' => t('Update cart'),
-  );
-  if (variable_get('uc_checkout_enabled', TRUE)) {
-    $form['actions']['checkout'] = array(
-      '#type' => 'submit',
-      '#value' => t('Checkout'),
-    );
-  }
-
-  return $form;
-}
-
-/**
- * Form submission handler for uc_cart_view_form().
- *
- * @see uc_cart_view_form()
- */
-function uc_cart_view_form_submit($form, &$form_state) {
-  // Remove the cart order variable if the customer came here during checkout.
-  if (isset($_SESSION['cart_order'])) {
-    unset($_SESSION['cart_order']);
-  }
-
-  // If a remove button was clicked, set the quantity for that item to 0.
-  if (substr($form_state['triggering_element']['#name'], 0, 7) == 'remove-') {
-    $item = substr($form_state['triggering_element']['#name'], 7);
-    $form_state['values']['items'][$item]['qty'] = 0;
-    drupal_set_message(t('<strong>!product-title</strong> removed from your shopping cart.', array('!product-title' => $form['items'][$item]['title']['#markup'])));
-  }
-
-  // Update the items in the shopping cart based on the form values.
-  uc_cart_update_item_object((object)$form_state['values']);
-
-  // Specify the appropriate redirect based on the button used to submit.
-  switch ($form_state['triggering_element']['#value']) {
-    // Continue shopping button.
-    case variable_get('uc_continue_shopping_text', t('Continue shopping')):
-      $form_state['redirect'] = uc_cart_continue_shopping_url();
-      break;
-
-    // Update cart button.
-    case t('Update cart'):
-      // No redirect.  Just display a message and preserve the last URL.
-      drupal_set_message(t('Your cart has been updated.'));
-      break;
-
-    // Checkout button.
-    case t('Checkout'):
-      $form_state['redirect'] = variable_get('uc_checkout_enabled', TRUE) ? 'cart/checkout' : 'cart';
-      break;
-  }
-}
-
-/**
- * Themes the uc_cart_view_form().
- *
- * @see uc_cart_view_form()
- * @ingroup themeable
- */
-function theme_uc_cart_view_form($variables) {
-  $form = $variables['form'];
-
-  drupal_add_css(drupal_get_path('module', 'uc_cart') . '/uc_cart.css');
-
-  $output = '<div id="cart-form-products">'
-          . drupal_render($form['items']) . '</div>';
-
-  foreach (element_children($form['items']) as $i) {
-    foreach (array('title', 'options', 'remove', 'image', 'qty') as $column) {
-      $form['items'][$i][$column]['#printed'] = TRUE;
-    }
-    $form['items'][$i]['#printed'] = TRUE;
-  }
-
-  // Add the continue shopping element and cart submit buttons.
-  if (($type = variable_get('uc_continue_shopping_type', 'link')) != 'none') {
-    // Render the continue shopping element into a variable.
-    $cs_element = drupal_render($form['continue_shopping']);
-
-    // Add the element with the appropriate markup based on the display type.
-    if ($type == 'link') {
-      $output .= '<div id="cart-form-buttons"><div id="continue-shopping-link">'
-               . $cs_element . '</div>' . drupal_render_children($form) . '</div>';
-    }
-    elseif ($type == 'button') {
-      $output .= '<div id="cart-form-buttons"><div id="update-checkout-buttons">'
-               . drupal_render_children($form) . '</div><div id="continue-shopping-button">'
-               . $cs_element . '</div></div>';
-    }
-  }
-  else {
-    $output .= '<div id="cart-form-buttons">' . drupal_render_children($form) . '</div>';
-  }
-
-  return $output;
-}
-
-/**
- * Displays the total price of the cart items.
- *
- * @see uc_cart_view_form()
- * @ingroup themeable
- */
-function theme_uc_cart_view_price($variables) {
-  return uc_currency_format($variables['form']['#markup']);
-}
-
-/**
- * Lists the products in the cart in a TAPIr table.
- */
-function uc_cart_view_table($table) {
-  $table['#attributes'] = array('width' => '100%');
-
-  $table['#columns'] = array(
-    'remove' => array(
-      'cell' => t('Remove'),
-      'weight' => 0,
-    ),
-    'image' => array(
-      'cell' => t('Products'),
-      'weight' => 1,
-    ),
-    'desc' => array(
-      'cell' => '',
-      'weight' => 2,
-    ),
-    'qty' => array(
-      'cell' => t('Qty.'),
-      'weight' => 3,
-    ),
-    'total' => array(
-      'cell' => t('Total'),
-      'weight' => 4,
-    ),
-  );
-
-  $subtotal = 0;
-  foreach (element_children($table) as $i) {
-    $subtotal += $table[$i]['#total'];
-
-    $table[$i]['remove']['#cell_attributes'] = array('align' => 'center', 'class' => array('remove'));
-    $table[$i]['image']['#cell_attributes'] = array('class' => array('image'));
-    $table[$i]['desc']['#cell_attributes'] = array('class' => array('desc'));
-    $table[$i]['qty']['#cell_attributes'] = array('class' => array('qty'));
-    $table[$i]['total']['#cell_attributes'] = array('class' => array('price'));
-    $table[$i]['#attributes'] = array('valign' => 'top');
-  }
-
-  $table[] = array(
-    'total' => array(
-      '#theme' => 'uc_price',
-      '#prefix' => '<strong>' . t('Subtotal:') . '</strong> ',
-      '#price' => $subtotal,
-      '#cell_attributes' => array(
-        'colspan' => 'full',
-        'align' => 'right',
-        'class' => array('subtotal'),
-      ),
-    ),
-  );
-
-  return $table;
-}
-
 
 /*******************************************************************************
  * Module and Helper Functions
diff --git a/uc_cart/uc_cart.uc_cart.inc b/uc_cart/uc_cart.uc_cart.inc
new file mode 100644
index 0000000..8d47885
--- /dev/null
+++ b/uc_cart/uc_cart.uc_cart.inc
@@ -0,0 +1,285 @@
+<?php
+
+/**
+ * @file
+ * Cart hook implementations.
+ */
+
+/**
+ * Implements hook_uc_cart_pane().
+ */
+function uc_cart_uc_cart_pane($items) {
+  $body = array();
+
+  if (!is_null($items)) {
+    $body = drupal_get_form('uc_cart_view_form', $items) + array(
+      '#prefix' => '<div id="cart-form-pane">',
+      '#suffix' => '</div>',
+    );
+  }
+
+  $panes['cart_form'] = array(
+    'title' => t('Default cart form'),
+    'enabled' => TRUE,
+    'weight' => 0,
+    'body' => $body,
+  );
+
+  return $panes;
+}
+
+/**
+ * Display a page allowing the customer to view the contents of his or her cart.
+ *
+ * Handles simple or complex objects. Some cart items may have a list of
+ * products that they represent. These are displayed but are not able to
+ * be changed by the customer.
+ *
+ * @see uc_cart_view_form_submit()
+ * @see theme_uc_cart_view_form()
+ * @see theme_uc_cart_view_price()
+ * @see uc_cart_view_table()
+ * @ingroup forms
+ */
+function uc_cart_view_form($form, &$form_state, $items = NULL) {
+  $form['items'] = array(
+    '#type' => 'tapir_table',
+    '#tree' => TRUE,
+  );
+
+  $i = 0;
+  foreach ($items as $item) {
+    module_invoke_all('uc_cart_item', 'view', $item);
+    $display_item = module_invoke($item->module, 'uc_cart_display', $item);
+    if (!empty($display_item)) {
+      $form['items'][$i] = $display_item;
+      $form['items'][$i]['image'] = uc_product_get_picture($display_item['nid']['#value'], 'uc_cart');
+
+      $description = $display_item['title']['#markup'] . $display_item['description']['#markup'];
+      $form['items'][$i]['desc']['#markup'] = $description;
+
+      $form['items'][$i]['cart_item_id'] = array(
+        '#type' => 'hidden',
+        '#value' => $item->cart_item_id,
+      );
+
+      if (isset($form['items'][$i]['remove'])) {
+        // Backward compatibility with old checkbox method.
+        if ($form['items'][$i]['remove']['#type'] == 'checkbox') {
+          $form['items'][$i]['remove'] = array('#type' => 'submit', '#value' => t('Remove'));
+        }
+
+        $form['items'][$i]['remove']['#name'] = 'remove-' . $i;
+      }
+
+      $form['items'][$i]['title']['#type'] = 'value';
+      $form['items'][$i]['description']['#type'] = 'value';
+
+      if (empty($display_item['qty'])) {
+        $form['items'][$i]['qty'] = array(
+          '#type' => 'hidden',
+          '#value' => 0,
+        );
+      }
+
+      $form['items'][$i]['total'] = array(
+        '#theme' => 'uc_price',
+        '#price' => $display_item['#total'],
+      );
+      $i++;
+    }
+  }
+
+  $form['items'] = tapir_get_table('uc_cart_view_table', $form['items']);
+
+  $form['actions'] = array('#type' => 'actions');
+
+  // If the continue shopping element is enabled...
+  if (($cs_type = variable_get('uc_continue_shopping_type', 'link')) !== 'none') {
+    // Setup the text used for the element.
+    $cs_text = variable_get('uc_continue_shopping_text', '') ? variable_get('uc_continue_shopping_text', '') : t('Continue shopping');
+
+    // Add the element to the form based on the element type.
+    if (variable_get('uc_continue_shopping_type', 'link') == 'link') {
+      $form['continue_shopping'] = array(
+        '#markup' => l($cs_text, uc_cart_continue_shopping_url()),
+      );
+    }
+    elseif (variable_get('uc_continue_shopping_type', 'link') == 'button') {
+      $form['actions']['continue_shopping'] = array(
+        '#type' => 'submit',
+        '#value' => $cs_text,
+      );
+      $form['continue_shopping_text'] = array(
+        '#type' => 'hidden',
+        '#value' => $cs_text,
+      );
+    }
+  }
+
+  // Add the control buttons for updating and proceeding to checkout.
+  $form['actions']['update'] = array(
+    '#type' => 'submit',
+    '#value' => t('Update cart'),
+  );
+  if (variable_get('uc_checkout_enabled', TRUE)) {
+    $form['actions']['checkout'] = array(
+      '#type' => 'submit',
+      '#value' => t('Checkout'),
+    );
+  }
+
+  return $form;
+}
+
+/**
+ * Form submission handler for uc_cart_view_form().
+ *
+ * @see uc_cart_view_form()
+ */
+function uc_cart_view_form_submit($form, &$form_state) {
+  // Remove the cart order variable if the customer came here during checkout.
+  if (isset($_SESSION['cart_order'])) {
+    unset($_SESSION['cart_order']);
+  }
+
+  // If a remove button was clicked, set the quantity for that item to 0.
+  if (substr($form_state['triggering_element']['#name'], 0, 7) == 'remove-') {
+    $item = substr($form_state['triggering_element']['#name'], 7);
+    $form_state['values']['items'][$item]['qty'] = 0;
+    drupal_set_message(t('<strong>!product-title</strong> removed from your shopping cart.', array('!product-title' => $form['items'][$item]['title']['#markup'])));
+  }
+
+  // Update the items in the shopping cart based on the form values.
+  uc_cart_update_item_object((object)$form_state['values']);
+
+  // Specify the appropriate redirect based on the button used to submit.
+  switch ($form_state['triggering_element']['#value']) {
+    // Continue shopping button.
+    case variable_get('uc_continue_shopping_text', t('Continue shopping')):
+      $form_state['redirect'] = uc_cart_continue_shopping_url();
+      break;
+
+    // Update cart button.
+    case t('Update cart'):
+      // No redirect.  Just display a message and preserve the last URL.
+      drupal_set_message(t('Your cart has been updated.'));
+      break;
+
+    // Checkout button.
+    case t('Checkout'):
+      $form_state['redirect'] = variable_get('uc_checkout_enabled', TRUE) ? 'cart/checkout' : 'cart';
+      break;
+  }
+}
+
+/**
+ * Themes the uc_cart_view_form().
+ *
+ * @see uc_cart_view_form()
+ * @ingroup themeable
+ */
+function theme_uc_cart_view_form($variables) {
+  $form = $variables['form'];
+
+  drupal_add_css(drupal_get_path('module', 'uc_cart') . '/uc_cart.css');
+
+  $output = '<div id="cart-form-products">'
+          . drupal_render($form['items']) . '</div>';
+
+  foreach (element_children($form['items']) as $i) {
+    foreach (array('title', 'options', 'remove', 'image', 'qty') as $column) {
+      $form['items'][$i][$column]['#printed'] = TRUE;
+    }
+    $form['items'][$i]['#printed'] = TRUE;
+  }
+
+  // Add the continue shopping element and cart submit buttons.
+  if (($type = variable_get('uc_continue_shopping_type', 'link')) != 'none') {
+    // Render the continue shopping element into a variable.
+    $cs_element = drupal_render($form['continue_shopping']);
+
+    // Add the element with the appropriate markup based on the display type.
+    if ($type == 'link') {
+      $output .= '<div id="cart-form-buttons"><div id="continue-shopping-link">'
+               . $cs_element . '</div>' . drupal_render_children($form) . '</div>';
+    }
+    elseif ($type == 'button') {
+      $output .= '<div id="cart-form-buttons"><div id="update-checkout-buttons">'
+               . drupal_render_children($form) . '</div><div id="continue-shopping-button">'
+               . $cs_element . '</div></div>';
+    }
+  }
+  else {
+    $output .= '<div id="cart-form-buttons">' . drupal_render_children($form) . '</div>';
+  }
+
+  return $output;
+}
+
+/**
+ * Displays the total price of the cart items.
+ *
+ * @see uc_cart_view_form()
+ * @ingroup themeable
+ */
+function theme_uc_cart_view_price($variables) {
+  return uc_currency_format($variables['form']['#markup']);
+}
+
+/**
+ * Lists the products in the cart in a TAPIr table.
+ */
+function uc_cart_view_table($table) {
+  $table['#attributes'] = array('width' => '100%');
+
+  $table['#columns'] = array(
+    'remove' => array(
+      'cell' => t('Remove'),
+      'weight' => 0,
+    ),
+    'image' => array(
+      'cell' => t('Products'),
+      'weight' => 1,
+    ),
+    'desc' => array(
+      'cell' => '',
+      'weight' => 2,
+    ),
+    'qty' => array(
+      'cell' => t('Qty.'),
+      'weight' => 3,
+    ),
+    'total' => array(
+      'cell' => t('Total'),
+      'weight' => 4,
+    ),
+  );
+
+  $subtotal = 0;
+  foreach (element_children($table) as $i) {
+    $subtotal += $table[$i]['#total'];
+
+    $table[$i]['remove']['#cell_attributes'] = array('align' => 'center', 'class' => array('remove'));
+    $table[$i]['image']['#cell_attributes'] = array('class' => array('image'));
+    $table[$i]['desc']['#cell_attributes'] = array('class' => array('desc'));
+    $table[$i]['qty']['#cell_attributes'] = array('class' => array('qty'));
+    $table[$i]['total']['#cell_attributes'] = array('class' => array('price'));
+    $table[$i]['#attributes'] = array('valign' => 'top');
+  }
+
+  $table[] = array(
+    'total' => array(
+      '#theme' => 'uc_price',
+      '#prefix' => '<strong>' . t('Subtotal:') . '</strong> ',
+      '#price' => $subtotal,
+      '#cell_attributes' => array(
+        'colspan' => 'full',
+        'align' => 'right',
+        'class' => array('subtotal'),
+      ),
+    ),
+  );
+
+  return $table;
+}
