diff --git TODO.txt TODO.txt
deleted file mode 100644
index d5cf75f..0000000
--- TODO.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-$Id$
-
-API
-* Handle update/delete cases cleanly (currently inefficient)
-
-Search
-* Paged searching
-* Advanced search options
-* Properly themed search results
-
-Theming
-* Document variables
-
-Functionality
-* Wish lists (separate module?
-* Related Books block for nodes (separate module?)
-* Reading List module (separate module?)
diff --git aat_legacy/aat_legacy.d5-migrate.inc aat_legacy/aat_legacy.d5-migrate.inc
deleted file mode 100644
index 2b11b52..0000000
--- aat_legacy/aat_legacy.d5-migrate.inc
+++ /dev/null
@@ -1,66 +0,0 @@
-<?php
-// $Id$
-/**
- * @file
- * Migration for the amazonnode and related item links from D5 amazontools.
- */
-
-/**
- * Batch Operation Callback
- */
-function _aat_legacy_migrate_field_from_d5($item, &$context) {
-  if (!isset($context['sandbox']['progress'])) {
-    $context['sandbox']['progress'] = 0;
-    $context['sandbox']['current_node'] = 0;
-
-    if ($node = _aat_legacy_migrate_from_d5($item['nid'], $item['ntype'])) {
-      $context['results'][$node->nid] = $node->title;
-
-      $context['sandbox']['progress']++;
-      $context['sandbox']['current_node'] = $node->nid;
-      $context['message'] = t('Processing nid <a href="!url">%nid</a>, %title', array('!url' => url("node/$node->nid"), '%nid' => $node->nid, '%title' => $node->title));
-    }
-  }
-}
-/**
- * Batch 'finished' callback
- */
-function _aat_legacy_migrate_fields_finished($success, $results, $operations) {
-  if ($success) {
-    $message = t('%count legacy fields (amazonnodes and links) were imported.', array('%count' => count($results)));
-    $message .= theme('item_list', $results);
-  }
-  else {
-    // An error occurred.
-    // $operations contains the operations that remained unprocessed.
-    $error_operation = reset($operations);
-    $message = t('An error occurred while processing %op.  with arguments = %args.', array('%op' => $error_operation[0], '%args' => print_r($error_operation[0], TRUE)));
-  }
-  drupal_set_message($message);
-}
-
-/**
- * Process one node.
- * @param $nid
- *   The nid to which we are to add values.
- * @param $type
- *   The ntype field from amazonnode table: the content type we're working with.
- * @return
- *   the updated node.
- */
-function _aat_legacy_migrate_from_d5($nid, $type) {
-  $results = db_query("SELECT asin, ntype FROM {amazonnode} an WHERE an.nid = %d and an.ntype = '%s'", $nid, $type);
-  $dirty = FALSE;
-  $node = node_load($nid);
-
-  while ($asin = db_fetch_object($results)) {
-    // if (!in_array($asin->asin, array_keys(array_values($node->field_legacy_asin)))) {
-    $node->field_legacy_asin[]['asin'] = $asin->asin;
-    // }
-  }
-  node_save($node);
-  $sql = "DELETE FROM {amazonnode} WHERE nid = %d AND ntype = '%s'";
-  db_query($sql, $nid, $type);
-
-  return $node;
-}
\ No newline at end of file
diff --git aat_legacy/aat_legacy.info aat_legacy/aat_legacy.info
deleted file mode 100644
index ea7f0eb..0000000
--- aat_legacy/aat_legacy.info
+++ /dev/null
@@ -1,8 +0,0 @@
-; $Id$
-name = Amazon legacy importer
-description = This module is used only to import legacy Drupal 5 Amazontools data. After upgrade it should be disabled.
-package = Amazon
-dependencies[] = amazon
-dependencies[] = asin
-core = 6.x
-php = 5.2
diff --git aat_legacy/aat_legacy.install aat_legacy/aat_legacy.install
deleted file mode 100644
index a76649e..0000000
--- aat_legacy/aat_legacy.install
+++ /dev/null
@@ -1,10 +0,0 @@
-<?php
-// $Id $
-
-function aat_legacy_install() {
-  drupal_set_message(t("The AAT Legacy module is only for importing legacy data. After data is imported, this module can be disabled."));
-}
-
-function aat_legacy_uninstall() {
-
-}
\ No newline at end of file
diff --git aat_legacy/aat_legacy.module aat_legacy/aat_legacy.module
deleted file mode 100644
index 0ffb08b..0000000
--- aat_legacy/aat_legacy.module
+++ /dev/null
@@ -1,169 +0,0 @@
-<?php
-// $Id$
-
-/**
- * Implementation of hook_menu.
- */
-function aat_legacy_menu() {
-  $items['admin/settings/aat_legacy'] = array(
-    'title' => "Amazontools Legacy Import",
-    'page callback' => 'drupal_get_form',
-    'access arguments' => array('administer site configuration'),
-    'page arguments' => array('aat_legacy_import_form')
-  );
-  return $items;
-}
-
-/**
- * Form to start the import process.
- */
-function aat_legacy_import_form() {
-  $form = array();
-  $form['explanation'] = array(
-    '#type' => 'markup',
-    '#prefix' => "<div>",
-    '#value' => t("Here you can import legacy Drupal 5 items from Amazon Tools. This may take a long time. It may be safely restarted."),
-    '#suffix' => "</div>",
-  );
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t("Start import"),
-  );
-  return $form;
-}
-
-function aat_legacy_import_form_submit($form_state, &$form_value) {
-  aat_legacy_import_data();
-}
-
-
-/**
- * Create a CCK field for each node type that had Amazon link in D5.
- * Then populate it.
- */
-function aat_legacy_import_data() {
-  $ret = array();
-  $result = db_query("SELECT DISTINCT type FROM node_type nt, amazonnode an where nt.type = an.ntype");
-  // Build a list of fields that need data updating.
-  module_load_install('content');
-  module_load_include('inc', 'content', 'includes/content.admin');
-  module_load_include('inc', 'content', 'includes/content.crud');
-
-  $field = aat_legacy_legacy_field_description();
-
-  // First attach the new field to the content type.
-  $types = array();
-  while ($type_ary = db_fetch_array($result)) {
-    $ntype = $type_ary['type'];
-    $types[] = $ntype;
-    $instance = content_field_instance_read(array('type_name' => $ntype, 'field_name' => 'field_legacy_asin'));
-    if (empty($instance)) {
-      drupal_set_message(t("Adding field_legacy_asin to node type %ntype", array('%ntype' => $ntype)));
-      $field['type_name'] = $ntype;
-      content_field_instance_create($field);
-    }
-    else {
-      drupal_set_message(t("field_legacy_asin already exists in node type %ntype; not creating it.", array('%ntype' => $ntype)));
-    }
-  }
-
-  // Now batch-import the data from those items.
-  if (!empty($types)) {
-    $operations = array();
-    $sql = "SELECT DISTINCT(nid) nid, ntype  FROM {amazonnode} WHERE ntype IN (" . db_placeholders($types, 'varchar') . ") ORDER BY nid ASC";
-    $result = db_query($sql, $types);
-    while ($item = db_fetch_object($result)) {
-      $operations[] = array('_aat_legacy_migrate_field_from_d5', array(array('nid' => $item->nid, 'ntype' => $item->ntype)));
-    }
-    $batch = array(
-      'title' => t('Migrating amazonnode field values into field_legacy_asin CCK fields'),
-      'operations' => $operations,
-      'finished' => '_aat_legacy_migrate_fields_finished',
-      'init_message' => t('Beginning migration of legacy_asin fields.'),
-      'progress_message' => t('Processed @current out of @total.'),
-      'error_message' => t('AAT Legacy field update encountered an error.'),
-      'file' => drupal_get_path('module', 'aat_legacy') .'/aat_legacy.d5-migrate.inc',
-    );
-    batch_set($batch);
-  }
-  if (empty($operations)) {
-    drupal_set_message(t("You have no items remaining to import. You may now disable the Amazon Legacy Importer module (aat_legacy)."));
-  }
-
-}
-
-/**
- * Just returns field description for field_legacy_asin.
- */
-function aat_legacy_legacy_field_description() {
-  return   array (
-    'label' => 'Legacy ASIN',
-    'field_name' => 'field_legacy_asin',
-    'type' => 'asin',
-    'widget_type' => 'asin_text',
-    'change' => 'Change basic information',
-    'weight' => '31',
-    'description' => '',
-    'default_value' =>
-  array (
-  0 =>
-  array (
-        'asin' => '',
-  ),
-  ),
-    'default_value_php' => '',
-    'default_value_widget' => NULL,
-    'required' => 0,
-    'multiple' => '1',
-    'op' => 'Save field settings',
-    'module' => 'asin',
-    'widget_module' => 'asin',
-    'columns' =>
-  array (
-      'asin' =>
-  array (
-        'type' => 'varchar',
-        'length' => 32,
-        'not null' => false,
-  ),
-  ),
-    'display_settings' =>
-  array (
-      'label' =>
-  array (
-        'format' => 'above',
-        'exclude' => 0,
-  ),
-  5 =>
-  array (
-        'format' => 'default',
-        'exclude' => 0,
-  ),
-      'teaser' =>
-  array (
-        'format' => 'default',
-        'exclude' => 0,
-  ),
-      'full' =>
-  array (
-        'format' => 'default',
-        'exclude' => 0,
-  ),
-  4 =>
-  array (
-        'format' => 'default',
-        'exclude' => 0,
-  ),
-  2 =>
-  array (
-        'format' => 'default',
-        'exclude' => 0,
-  ),
-  3 =>
-  array (
-        'format' => 'default',
-        'exclude' => 0,
-  ),
-  ),
-  );
-}
diff --git amazon-inline-item.tpl.php amazon-inline-item.tpl.php
index e3fbb62..a6f9904 100644
--- amazon-inline-item.tpl.php
+++ amazon-inline-item.tpl.php
@@ -1,6 +1,6 @@
 <?php
 $alt_theme = 'amazon_inline_item_' . _amazon_clean_type($item['producttypename']);
-if ($output = theme($alt_theme, $item)) {
+if ($output = theme($alt_theme, array('item' => $item))) {
   print $output;
 }
 else {
diff --git amazon.admin.inc amazon.admin.inc
index ca1cb70..3445f8d 100644
--- amazon.admin.inc
+++ amazon.admin.inc
@@ -1,6 +1,6 @@
 <?php
 
-function amazon_settings_form($form_state) {
+function amazon_settings_form($form, &$form_state) {
   $cache = amazon_data_cache();
   $options = array();
   foreach ($cache['locales'] as $locale => $data) {
@@ -41,7 +41,7 @@ function amazon_settings_form($form_state) {
   $form['amazon_aws_access_key'] = array(
     '#type' => 'textfield',
     '#title' => t('Amazon AWS Access Key ID'),
-    '#description' => t('You must sign up for an Amazon AWS account to use the Product Advertising Service. See !more_info for information and a registration form.',array('!more_info'=>l(t('the AWS home page'),'https://aws-portal.amazon.com/gp/aws/developer/account/index.html?ie=UTF8&action=access-key',array('html'=>TRUE)))),
+    '#description' => t('You must sign up for an Amazon AWS account to use the Product Advertising Service. See !more_info for information and a registration form.', array('!more_info' => l(t('the AWS home page'), 'https://aws-portal.amazon.com/gp/aws/developer/account/index.html?ie=UTF8&action=access-key', array('html' => TRUE)))),
     '#default_value' => variable_get('amazon_aws_access_key', ''),
     '#required' => TRUE,
   );
@@ -49,18 +49,18 @@ function amazon_settings_form($form_state) {
   $form['amazon_aws_secret_access_key'] = array(
     '#type' => 'textfield',
     '#title' => t('Amazon AWS Secret Access Key'),
-    '#description' => t('You must sign up for an Amazon AWS account to use the Product Advertising Service. See !more_info for information and a registration form.',array('!more_info'=>l(t('the AWS home page'),'https://aws-portal.amazon.com/gp/aws/developer/account/index.html?ie=UTF8&action=access-key',array('html'=>TRUE)))),
-    '#default_value' => variable_get('amazon_aws_secret_access_key',""),
+    '#description' => t('You must sign up for an Amazon AWS account to use the Product Advertising Service. See !more_info for information and a registration form.', array('!more_info' => l(t('the AWS home page'), 'https://aws-portal.amazon.com/gp/aws/developer/account/index.html?ie=UTF8&action=access-key', array('html' => TRUE)))),
+    '#default_value' => variable_get('amazon_aws_secret_access_key', ""),
     '#required' => TRUE,
   );
 
   // Now add the Javascript that does the fancy hide/show effects.
-  drupal_add_js(drupal_get_path('module', 'amazon') .'/amazon.admin.js');
+  drupal_add_js(drupal_get_path('module', 'amazon') . '/amazon.admin.js');
 
   return system_settings_form($form);
 }
 
-function amazon_storage_settings_form() {
+function amazon_storage_settings_form($form, &$form_state) {
 
   $period = drupal_map_assoc(array(3600, 7200, 14400, 21600, 43200, 86400), 'format_interval');
   $form['details']['amazon_refresh_schedule'] = array(
@@ -77,20 +77,23 @@ function amazon_storage_settings_form() {
     '#default_value' => variable_get('amazon_core_data', array('creators', 'images')),
     '#options' => array(
       'creators' => t('Book authors, film actors, etc.'),
-      'images' => t('Product images'),
+      'images' => t('Product image links'),
       'editorial_reviews' => t('Editorial reviews'),
       'customer_reviews' => t('Customer reviews'),
     ),
   );
 
   // Now add the Javascript that does the fancy hide/show effects.
-  drupal_add_js(drupal_get_path('module', 'amazon') .'/amazon.admin.js');
+  drupal_add_js(drupal_get_path('module', 'amazon') . '/amazon.admin.js');
 
   return system_settings_form($form);
 }
 
-
-function amazon_test_form($form_state) {
+/**
+ * Form for testing a single ASIN.
+ *
+ */
+function amazon_test_form($form, &$form_state) {
   $form = array();
 
   $form['asin'] = array(
@@ -105,11 +108,11 @@ function amazon_test_form($form_state) {
   );
 
   if (isset($form_state['amazon_item'])) {
-    $markup = theme('amazon_item', $form_state['amazon_item'], 'details');
-    $markup .= '<pre>'. print_r($form_state['amazon_item'], TRUE) .'</pre>';
+    $markup = theme('amazon_item', array('item' => $form_state['amazon_item'], 'style' => 'default'));
+    $markup .= '<pre>' . print_r($form_state['amazon_item'], TRUE) . '</pre>';
     $form['item_data'] = array(
       '#type' => 'markup',
-      '#value' => $markup,
+      '#markup' => $markup,
       '#weight' => 10,
     );
   }
@@ -131,7 +134,8 @@ function amazon_test_form_submit($form, &$form_state) {
     // causes a serialization operation. Whoops.
     $form_state['amazon_item'] = $item;
     $form_state['rebuild'] = TRUE;
-  } else {
+  }
+  else {
     drupal_set_message(t("Test failed for this ASIN. Please check the !link for messages.", array('!link' => l(t("error log"), 'admin/reports/dblog'))));
   }
 }
diff --git amazon.admin.js amazon.admin.js
index 1dfc277..5f9579a 100644
--- amazon.admin.js
+++ amazon.admin.js
@@ -1,24 +1,28 @@
-// $Id$
+//$Id$
+Drupal.behaviors.amazon = {
+    attach: {
 
-jQuery(document).ready(function(){ jQuery("#edit-amazon-associate-setting").bind("change", function() {
-  if (this.value == 'custom') {
-    $("#amazon-associate-id-wrapper").show('fast');
-  }
-  else {
-    $("#amazon-associate-id-wrapper").hide('fast');
-  }
-  return false;
-})
-});
-
-jQuery(document).ready(
-  function(){ jQuery("#edit-amazon-cache").bind("change", function() {
-  if (this.checked == true) {
-    $("#amazon-storage-details").show('fast');
-  }
-  else {
-    $("#amazon-storage-details").hide('fast');
-  }
-  return false;
+  jQuery(document).ready(function(){ jQuery("#edit-amazon-associate-setting").bind("change", function() {
+    if (this.value == 'custom') {
+      $("#amazon-associate-id-wrapper").show('fast');
+    }
+    else {
+      $("#amazon-associate-id-wrapper").hide('fast');
+    }
+    return false;
   })
-});
+  });
+
+  jQuery(document).ready(
+      function(){ jQuery("#edit-amazon-cache").bind("change", function() {
+        if (this.checked == true) {
+          $("#amazon-storage-details").show('fast');
+        }
+        else {
+          $("#amazon-storage-details").hide('fast');
+        }
+        return false;
+      })
+      });
+}
+};
\ No newline at end of file
diff --git amazon.info amazon.info
index 959fe18..6e73357 100644
--- amazon.info
+++ amazon.info
@@ -1,5 +1,24 @@
 name = Amazon API
-description = Provides integration with the Amazon Ecommerce APIs.
+description = Provides integration with the Amazon Product Advertising API.
 package = Amazon
-core = 6.x
+core = 7.x
 php = 5.2
+
+files[] = amazon-inline-item.tpl.php
+files[] = amazon-item-detail.tpl.php
+files[] = amazon-item-details.tpl.php
+files[] = amazon-item-thumbnail.tpl.php
+files[] = amazon-item.tpl.php
+files[] = amazon-views-view-row-item.tpl.php
+files[] = amazon.admin.inc
+files[] = amazon.install
+files[] = amazon.module
+files[] = amazon.theme.inc
+files[] = includes/amazon.views.inc
+files[] = includes/amazon_views_plugin_row_amazon_view.inc
+files[] = includes/views_handler_field_amazon_date.inc
+files[] = includes/views_handler_field_amazon_image.inc
+files[] = includes/views_handler_field_amazon_participant.inc
+files[] = includes/views_handler_field_amazon_title.inc
+files[] = includes/views_handler_filter_amazon_node_module.inc
+files[] = includes/views_handler_filter_string_compare.inc
diff --git amazon.install amazon.install
index 0518d15..dd54281 100644
--- amazon.install
+++ amazon.install
@@ -1,4 +1,10 @@
 <?php
+/**
+ * @file
+ * Install, update and uninstall functions for the amazon module.
+ *
+ */
+
 // $Id$
 
 /**
@@ -12,7 +18,8 @@ function amazon_install() {
  * Implements hook_uninstall().
  */
 function amazon_uninstall() {
-  drupal_uninstall_schema('amazon');
+  // TODO The drupal_(un)install_schema functions are called automatically in D7.;
+  // drupal_uninstall_schema('amazon');
   $variables = preg_split('/\s+/',
     "amazon_media_data
     amazon_locale
@@ -33,16 +40,16 @@ function amazon_uninstall() {
  * @return unknown_type
  */
 function amazon_requirements($phase) {
-  $secret_access_key=variable_get('amazon_aws_secret_access_key',"");
-  $api_key = variable_get('amazon_aws_access_key',"");
+  $secret_access_key = variable_get('amazon_aws_secret_access_key', "");
+  $api_key = variable_get('amazon_aws_access_key', "");
   $requirement = array();
   if (empty($secret_access_key) || empty($api_key)) {
-    drupal_set_message(t("The Amazon API must be configured with an Access Key ID and an Amazon AWS Secret Access Key to function. Go to !settings.",array("!settings"=>l(t("Amazon API Setttings"),'admin/settings/amazon'))));
+    drupal_set_message(t("The Amazon API must be configured with an Access Key ID and an Amazon AWS Secret Access Key to function. Go to !settings.", array("!settings" => l(t("Amazon API Setttings"), 'admin/settings/amazon'))));
     $requirement['title'] = t("Amazon AWS Secret Access Key");
     $requirement['severity'] = REQUIREMENT_WARNING;
     $requirement['value'] = t("Not Set");
-    $requirement['description'] = t("The Amazon API must be configured with an Access Key ID and an Amazon AWS Secret Access Key to function. Go to !settings.",array("!settings"=>l(t("Amazon API Setttings"),'admin/settings/amazon')));
-    return array('amazon_aws_secret_access_key',$requirement);
+    $requirement['description'] = t("The Amazon API must be configured with an Access Key ID and an Amazon AWS Secret Access Key to function. Go to !settings.", array("!settings" => l(t("Amazon API Setttings"), 'admin/settings/amazon')));
+    return array('amazon_aws_secret_access_key', $requirement);
   }
 
   return NULL;
@@ -130,7 +137,7 @@ function amazon_schema() {
       'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE),
       'vid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE),
       'asin' => array('type' => 'varchar', 'length' => 64, 'not null' => TRUE),
-      'notes' => array('type' => 'text','not null' => FALSE),
+      'notes' => array('type' => 'text', 'not null' => FALSE),
       'module' => array('type' => 'varchar', 'length' => 64, 'not null' => TRUE, 'default' => 'amazon'),
       'delta' => array('type' => 'int', 'default' => 0),
     ),
@@ -147,171 +154,12 @@ function amazon_schema() {
 }
 
 /**
- * Update variables from legacy AAT module where possible. Add mpn field.
- */
-function amazon_update_6001() {
-  $ret = array();
-  db_add_column($ret, 'amazon_item', 'mpn', 'varchar(128)');
-
-  // If the access key is not set, and there is a D5 amazontools access key, use it.
-  $d6_aws_access_key = variable_get('amazon_aws_access_key', "");
-  if (empty($d6_aws_access_key)) {
-    $old_access_key = variable_get('amazon_awsaccess_key', "");
-    if (!empty($old_access_key)) {
-      variable_set('amazon_aws_access_key', $old_access_key);
-      variable_del('amazon_awsaccess_key');
-      $ret[] = array('success' => TRUE, 'query' => 'Updated Amazon AWS Access Key from D5 AAT');
-    }
-  }
-  // Bring over the d5 associate id if possible.
-  $d6_associate_id = variable_get("amazon_custom_associate_id", "");
-  if (empty($d6_associate_id)) {
-    $associate_id = variable_get("amazon_associate_id", "");
-    if (!empty($associate_id)) {
-      variable_set('amazon_custom_associate_id', $associate_id);
-      variable_set('amazon_associate_setting', 'custom');
-      variable_del("amazon_associate_id");
-      $ret[] = array('success' => TRUE, 'query' => 'Updated Amazon Associate ID from D5 AAT');
-    }
-  }
-  if (is_numeric(variable_get('amazon_locale',"US"))) {
-    variable_del('amazon_locale');
-    drupal_set_message(t("The Amazon locale setting was invalid. Please visit the <a href='!url'>Amazon settings page</a> to correct it.", array('!url' => url('admin/settings/amazon'))));
-  }
-
-  return $ret;
-}
-
-function amazon_update_6002() {
-  $ret = array();
-  // Make sure that primary keys are correct
-  db_drop_primary_key($ret, 'amazon_item_image');
-  db_add_primary_key($ret, 'amazon_item_image', array('asin', 'size'));
-  return $ret;
-}
-
-/**
- * http://drupal.org/node/426786 - Allow longer image url fields.
- */
-function amazon_update_6003() {
-  $ret = array();
-  db_change_field($ret, 'amazon_item_image', 'url', 'url',
-    array('type' => 'varchar', 'length' => 128, 'not null' => TRUE));
-  return $ret;
-}
-
-/**
- * Ugly hack for those updating from amazon module in D5.
- */
-function amazon_update_6004() {
-  $ret = array();
-
-  if (!db_table_exists('amazon_item')) {
-    drupal_install_schema('amazon');
-    $ret[] = array('success' => TRUE, 'query' => 'Force-installed Amazon module tables after botched D5 upgrade.');
-  }
-
-  return $ret;
-}
-
-function amazon_update_6005() {
-  $ret = array();
-  db_change_field($ret, 'amazon_item', 'detailpageurl', 'detailpageurl',
-    array('type' => 'text'));
-  db_change_field($ret, 'amazon_item', 'brand', 'brand',
-    array('type' => 'varchar', 'length' => 64));
-  db_change_field($ret, 'amazon_item', 'publisher', 'publisher',
-    array('type' => 'varchar', 'length' => 64));
-  db_change_field($ret, 'amazon_item', 'manufacturer', 'manufacturer',
-    array('type' => 'varchar', 'length' => 64));
-  db_change_field($ret, 'amazon_item', 'studio', 'studio',
-    array('type' => 'varchar', 'length' => 64));
-  db_change_field($ret, 'amazon_item', 'label', 'label',
-    array('type' => 'varchar', 'length' => 64));
-  db_change_field($ret, 'amazon_item', 'binding', 'binding',
-    array('type' => 'varchar', 'length' => 64));
-  db_change_field($ret, 'amazon_item', 'releasedate', 'releasedate',
-    array('type' => 'varchar', 'length' => 64));
-  db_change_field($ret, 'amazon_item', 'productgroup', 'productgroup',
-    array('type' => 'varchar', 'length' => 255));
-  db_change_field($ret, 'amazon_item', 'producttypename', 'producttypename',
-    array('type' => 'varchar', 'length' => 255));
-
-  return $ret;
-}
-
-function amazon_update_6006() {
-  $ret = array();
-  db_add_field($ret, 'amazon_item', 'invalid_asin', array('type' => 'int', 'default' => 0));
-  return $ret;
-}
-
-function amazon_update_6007() {
-  $ret = array();
-  if (variable_get('amazon_associate_setting', 'associate') == 'author') {
-    variable_del('amazon_associate_setting');  // go with the default.
-    $ret[] = array('success' => TRUE, 'query' => t('Replaced "author" Amazon associate setting with the default.'));
-  }
-  return $ret;
-}
-
-/**
- * Change listpriceamount field to numeric. It's not floating anyway.
- */
-function amazon_update_6008() {
-  $ret = array();
-  db_change_field($ret, 'amazon_item', 'listpriceamount', 'listpriceamount',
-    array('type' => 'numeric'));
-  return $ret;
-}
-
-/**
- * Change key on amazon_item_node (again).
- *
- * It looks like nid should be the correct portion of the key, since there
- * is no vid coming in. In fact... There should be no vid.
- *
- */
-function amazon_update_6009() {
-  $ret = array();
-  db_drop_primary_key($ret, 'amazon_item_node');
-  db_add_primary_key($ret, 'amazon_item_node', array('nid', 'asin', 'module'));
-  return $ret;
-}
-
-
-/**
- * Change key on editorial reviews, since it shouldn't be primary.
- */
-function amazon_update_6010() {
-  $ret = array();
-  db_drop_primary_key($ret, 'amazon_item_editorial_review');
-  db_add_index($ret, 'amazon_item_editorial_review', 'amazon_item_editorial_review', array('asin'));
-  return $ret;
-}
-
-/**
- * Add Customer Reviews table so we can handle that.
- * @return unknown_type
- */
-function amazon_update_6011() {
-  $schema = amazon_schema();
-  if (!db_table_exists('amazon_item_customer_review')) {
-    db_create_table($ret, 'amazon_item_customer_review', $schema['amazon_item_customer_review']);
-  }
-  return $ret;
-}
-
-/**
- * Add new elements to the amazon_item table: Lowest price, etc.
- * @return unknown_type
+ * Fix messed up type for currency code in update 6012.
  */
-function amazon_update_6012() {
-  db_add_field($ret, 'amazon_item', 'lowestpriceamount', array('type' => 'numeric'));
-  db_add_field($ret, 'amazon_item', 'lowestpricecurrencycode', array('type' => 'numeric'));
-  db_add_field($ret, 'amazon_item', 'lowestpriceformattedprice', array('type' => 'varchar', 'length' => 32));
-  db_add_field($ret, 'amazon_item', 'amazonpriceamount', array('type' => 'numeric'));
-  db_add_field($ret, 'amazon_item', 'amazonpricecurrencycode', array('type' => 'numeric'));
-  db_add_field($ret, 'amazon_item', 'amazonpriceformattedprice', array('type' => 'varchar', 'length' => 32));
-  return $ret;
+function amazon_update_7100() {
+  db_change_field('amazon_item', 'lowestpricecurrencycode', 'lowestpricecurrencycode',
+    array('type' => 'varchar', 'length' => 32));
+  db_change_field('amazon_item', 'amazonpricecurrencycode', 'amazonpricecurrencycode',
+    array('type' => 'varchar', 'length' => 32));
+  return(t("Updated currency code column types"));
 }
diff --git amazon.module amazon.module
index a0a0db5..9a8c093 100644
--- amazon.module
+++ amazon.module
@@ -21,7 +21,7 @@ define('AMAZON_IMAGE_SIZES', 'SmallImage,MediumImage,LargeImage');
  */
 function amazon_menu() {
   $items = array();
-  $items['admin/settings/amazon'] = array(
+  $items['admin/config/amazon'] = array(
     'title' => 'Amazon API',
     'description' => 'Global settings for the Amazon Ecommerce API.',
     'page callback' => 'drupal_get_form',
@@ -31,7 +31,7 @@ function amazon_menu() {
     'access arguments' => array('administer amazon'),
     'type' => MENU_NORMAL_ITEM
   );
-  $items['admin/settings/amazon/storage'] = array(
+  $items['admin/config/amazon/storage'] = array(
     'title' => 'Storage',
     'description' => 'Local data storage settings for Amazon products.',
     'page callback' => 'drupal_get_form',
@@ -41,7 +41,7 @@ function amazon_menu() {
     'access arguments' => array('administer amazon'),
     'type' => MENU_LOCAL_TASK
   );
-  $items['admin/settings/amazon/test'] = array(
+  $items['admin/config/amazon/test'] = array(
     'title' => 'Test',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('amazon_test_form'),
@@ -50,14 +50,7 @@ function amazon_menu() {
     'access arguments' => array('administer amazon'),
     'type' => MENU_LOCAL_TASK
   );
-  $items['admin/settings/amazon/upgrade'] = array(
-    'page callback' => '_amazon_upgrade',
-    'file' => 'amazon.admin.inc',
-    'access callback' => 'user_access',
-    'access arguments' => array('administer amazon'),
-    'type' => MENU_CALLBACK
-  );
-  $items['admin/settings/amazon/api'] = array(
+  $items['admin/config/amazon/api'] = array(
     'title' => 'Settings',
     'weight' => -10,
     'type' => MENU_DEFAULT_LOCAL_TASK
@@ -67,10 +60,15 @@ function amazon_menu() {
 }
 
 /**
- * Implementation of hook_perm
+ * Implementation of hook_permission
  */
-function amazon_perm() {
-  return array('administer amazon');
+function amazon_permission() {
+  return array(
+    'administer amazon' =>  array(
+      'title' => t('Administer Amazon module'),
+      'description' => t('Configure and test Amazon module.'),
+  ),
+  );
 }
 
 /**
@@ -79,19 +77,19 @@ function amazon_perm() {
 function amazon_theme() {
   $templates = array(
     'amazon_item' => array(
-      'arguments' => array('item' => array(), 'style' => 'default'),
+      'variables' => array('item' => array(), 'style' => 'default'),
       'pattern' => 'amazon_item__',
       'template' => 'amazon-item',
     ),
     'amazon_inline_item' => array(
-      'arguments' => array('item' => array()),
+      'variables' => array('item' => array()),
       'template' => 'amazon-inline-item',
       // Re-use the existing infrastructure.
       'preprocess functions' => 'amazon_preprocess_amazon_item',
     ),
     // Allows use of whatever is provided in preprocessed $variables.
     'amazon_detail' => array(
-      'arguments' => array('item' => array(), 'detail' => NULL),
+      'variables' => array('item' => array(), 'detail' => NULL),
       'template' => 'amazon-item-detail',
       'preprocess functions' => array('amazon_preprocess_amazon_item'),
     ),
@@ -103,13 +101,12 @@ function amazon_theme() {
 /**
  * hook_preprocess: amazon_item.
  */
-function amazon_preprocess_amazon_item(&$variables) {
+function amazon_preprocess_amazon_item(&$variables, $theme_type) {
 
   $item = $variables['item'];
-
   // Do a quick cycle through the simple keys on the item, check_plain() them,
   // and stick them in the variables collection.
-  foreach($item as $key => $value) {
+  foreach ($item as $key => $value) {
     if (is_string($value)) {
       $variables[$key] = filter_xss($value);
     }
@@ -117,10 +114,25 @@ function amazon_preprocess_amazon_item(&$variables) {
 
   $variables['type'] = _amazon_clean_type($item['producttypename']);
   $variables['detailpageurl'] = check_url($item['detailpageurl']);
-  $variables['editorialreview'] = !empty($item['editorialreviews']) ? check_markup($item['editorialreviews'][0]['content']) : '';
-  $variables['customerreview'] = !empty($item['customerreviews']) ? check_markup($item['customerreviews'][0]['content']) : '';
+  $variables['editorialreview'] = !empty($item['editorialreviews']) ? filter_xss($item['editorialreviews'][0]['content']) : '';
+  if (!empty($item['customerreviews'])) {
+    foreach ($item['customerreviews'] as &$review) {
+      $review['content'] = filter_xss($review['content']);
+      $review['summary'] = filter_xss($review['summary']);
+    }
+  }
+  $variables['customerreview'] = !empty($item['customerreviews']) ? filter_xss($item['customerreviews'][0]['content']) : '';
   $variables['invalid_asin'] = !empty($item['invalid_asin']) ? 1 : 0;
 
+  $variables['detailpageurl'] = check_url($variables['detailpageurl']);
+
+  if (!empty($variables['customerreviews'])) {
+    foreach($variables['customerreviews'] as $key => $review) {
+      $variables['customerreviews'][$key] = filter_xss($variables['customerreviews'][$key]);
+    }
+  }
+  $variables['invalid_asin'] = !empty($variables['invalid_asin']) ? 1 : 0;
+
   if (!empty($variables['theatricalreleasedate'])) {
     $date = explode('-', $variables['theatricalreleasedate']);
     $variables['releaseyear'] = $date[0];
@@ -142,7 +154,7 @@ function amazon_preprocess_amazon_item(&$variables) {
     $variables['participants'] = filter_xss(filter_xss(implode(', ', $item['participants'])));
     $participant_types = split(',', AMAZON_PARTICIPANT_TYPES);
 
-    foreach($participant_types as $participant_type) {
+    foreach ($participant_types as $participant_type) {
       $participant_type = strtolower($participant_type);
       if (!empty($item[$participant_type])) {
         if (is_string($item[$participant_type])) {
@@ -165,8 +177,8 @@ function amazon_preprocess_amazon_item(&$variables) {
 
   // Handle supported image resolutions.
   if (isset($item['imagesets'])) {
-    foreach($item['imagesets'] as $key => $image) {
-      $variables[$key] = theme('image', $image['url'], t('Image of') . ' ' . check_plain($item['title']), check_plain($item['title']), array('height' => $image['height'], 'width' => $image['width']), FALSE);
+    foreach ($item['imagesets'] as $key => $image) {
+      $variables[$key] = theme('image', array('path' => $image['url'], 'alt' => t('Image of') . ' ' . check_markup($item['title']), 'title' => check_markup($item['title']), 'attributes' => array('height' => $image['height'], 'width' => $image['width']), 'getsize' => FALSE));
       $variables["{$key}url"] = check_url($image['url']);
       $variables["{$key}height"] = check_plain($image['height']);
       $variables["{$key}width"] = check_plain($image['width']);
@@ -174,13 +186,19 @@ function amazon_preprocess_amazon_item(&$variables) {
   }
   $variables['image'] = !empty($variables['mediumimage']) ? $variables['mediumimage'] : '';
 
+  $variables['attributes_array'] = array();
+  $variables['title_attributes_array'] = array();
+  $variables['content_attributes_array'] = array();
+  if (!empty($variables['detail']) && $theme_type == 'amazon_detail') {
+    $variables['classes_array'] = array("amazon-item", "amazon-item-detail-{$variables['detail']}");
+  }
   if (!empty($variables['style'])) {
     $variables['classes'] = _amazon_item_classes($item) . ' amazon-item-' . check_plain($variables['style']);
 
     // A set of more specific templates to use when displaying items.
     $variables['template_files'][] = 'amazon-item-' . $variables['style'];
     $variables['template_files'][] = 'amazon-item-' . strtolower($variables['type']);
-    $variables['template_files'][] = 'amazon-item-' . strtolower($variables['type']) .'-'. $variables['style'];
+    $variables['template_files'][] = 'amazon-item-' . strtolower($variables['type']) . '-' . $variables['style'];
 
     if (!empty($item['view']) && !empty($item['view']->name)) {
       $vars['template_files'][] = 'amazon-item-view-' . $item['view']->name;
@@ -196,7 +214,7 @@ function _amazon_clean_type($type) {
 }
 
 function _amazon_item_classes($item) {
-  return 'amazon-item amazon-item-'. str_replace('_', '-', _amazon_clean_type($item['producttypename']));
+  return 'amazon-item amazon-item-' . str_replace('_', '-', _amazon_clean_type($item['producttypename']));
 }
 
 
@@ -223,37 +241,37 @@ function amazon_http_request($operation, $parameters = array(), $locale = NULL)
   if (!empty($parameters_after_hook)) {
     $parameters = $parameters_after_hook;
   }
-  $parameters += array('Timestamp' => gmdate("Y-m-d\TH:i:s"). 'Z');
+  $parameters += array('Timestamp' => gmdate("Y-m-d\TH:i:s") . 'Z');
   uksort($parameters, 'strnatcmp');
 
   $params = array();
-  foreach($parameters as $key => $value) {
+  foreach ($parameters as $key => $value) {
     if (is_array($value)) {
       $value = implode(',', $value);
     }
     $param = str_replace("%7E", "~", rawurlencode($key));
     $value = str_replace("%7E", "~", rawurlencode($value));
-    $params[] = $param .'='. $value;
+    $params[] = $param . '=' . $value;
   }
-  $secret_access_key=variable_get('amazon_aws_secret_access_key',"");
+  $secret_access_key = variable_get('amazon_aws_secret_access_key', "");
   if ($secret_access_key == "") {
-    watchdog('amazon',"No Secret Access Key configured. You must configure one at Admin->Settings->Amazon API",NULL,'error');
+    watchdog('amazon', "No Secret Access Key configured. You must configure one at Admin->Settings->Amazon API", NULL, 'error');
     drupal_set_message(t("Amazon Module: No Secret Access Key is configured. Please contact your site administrator"));
     return FALSE;
   }
   // Thanks for signature creation code from http://mierendo.com/software/aws_signed_query/
-  $query_string = implode('&',$params);
+  $query_string = implode('&', $params);
   $parsed_url = parse_url($locale_data['url']);
-  $host=strtolower($parsed_url['host']);
-  $string_to_sign="GET\n$host\n{$parsed_url['path']}\n$query_string";
+  $host = strtolower($parsed_url['host']);
+  $string_to_sign = "GET\n$host\n{$parsed_url['path']}\n$query_string";
 
   $signature = base64_encode(hash_hmac('sha256', $string_to_sign, $secret_access_key, TRUE));
   $signature = str_replace("%7E", "~", rawurlencode($signature));
   $query_string .= "&Signature=$signature";
 
-  $url = $locale_data['url'] .'?'. $query_string;
+  $url = $locale_data['url'] . '?' . $query_string;
   // Make the request and return a SimpleXML object.
-  $results = drupal_http_request($url, array(), 'GET');
+  $results = drupal_http_request($url, array('method' => 'GET'));
   if ($results->code == 200) {
     $xml = new SimpleXMLElement($results->data);
     return $xml;
@@ -261,11 +279,12 @@ function amazon_http_request($operation, $parameters = array(), $locale = NULL)
   if ($results->code >= 400 && $results->code < 500) {
     try {
       $xml = new SimpleXMLElement($results->data);
-    } catch (Exception $e) {
-      watchdog('amazon', "Error handling results: http_code=%http_code, data=%data.",array('%http_code' => $results->code, '%data' => (string)$results->data) );
+    }
+    catch (Exception $e) {
+      watchdog('amazon', "Error handling results: http_code=%http_code, data=%data.", array('%http_code' => $results->code, '%data' => (string) $results->data) );
       return FALSE;
     }
-    watchdog('amazon', "HTTP code %http_code accessing Amazon's AWS service: %code, %message", array('%http_code' => $results->code, '%code' => (string)$xml->Error->Code, '%message' => (string)$xml->Error->Message));
+    watchdog('amazon', "HTTP code %http_code accessing Amazon's AWS service: %code, %message", array('%http_code' => $results->code, '%code' => (string) $xml->Error->Code, '%message' => (string) $xml->Error->Message));
     return FALSE;
   }
   watchdog('amazon', "Error accessing Amazon AWS web service. HTTP result code=%code, error=%error", array('%code' => $results->code, '%error' => $results->error));
@@ -315,10 +334,10 @@ function amazon_item_lookup($item_ids = array(), $force_lookup = FALSE) {
  *   Array of cleaned XML structures keyed by ASIN.
  */
 function amazon_item_lookup_from_web($item_ids = array()) {
-  $amazon_limit = 10;  // Amazon will accept no more than 10 items
+  $amazon_limit = 10; // Amazon will accept no more than 10 items
   $asins = array();
   $results = array();
-  $item_ids = array_filter($item_ids);  // Remove any empty items.
+  $item_ids = array_filter($item_ids); // Remove any empty items.
   foreach ($item_ids as $asin) {
     if (!empty($asin)) {
       $asins[] = $asin;
@@ -348,22 +367,30 @@ function _amazon_item_batch_lookup_from_web($item_ids = array()) {
     );
     $results = amazon_http_request('ItemLookup', $params);
     if (!empty($results->Items->Request->Errors)) {
-      foreach($results->Items->Request->Errors->Error as $error) {
-        $code = (string)$error->Code;
-        $message = (string)$error->Message;
+      foreach ($results->Items->Request->Errors->Error as $error) {
+        $code = (string) $error->Code;
+        $message = (string) $error->Message;
         $matches = array();
         // Find and extract the failing ASIN, so we can mark it in the db.
         if (preg_match('/^([^ ]+) is not a valid value for ItemId/', $message, $matches)) {
           $error_asin = $matches[1];
-          $query = "update {amazon_item} set invalid_asin = TRUE where asin = '%s'";
-          db_query($query, $error_asin);
+          try {
+            $result = db_update('amazon_item')
+            ->fields(array('invalid_asin' => TRUE))
+            ->condition('asin', $error_asin)
+            ->execute();
+          }
+          catch(Exception $e) {
+            amazon_db_error_watchdog('Failed to update invalid_asin=TRUE on amazon_item.', $e);
+          }
+
         }
-        watchdog('amazon','Error retrieving Amazon item %code, message: %message.', array('%code' => $code, '%message' => $message), WATCHDOG_WARNING);
+        watchdog('amazon', 'Error retrieving Amazon item %code, message: %message.', array('%code' => $code, '%message' => $message), WATCHDOG_WARNING);
       }
     }
     $items = array();
     if (!empty($results->Items->Item)) {
-      foreach($results->Items->Item as $xml) {
+      foreach ($results->Items->Item as $xml) {
         $item = amazon_item_clean_xml($xml);
         amazon_item_insert($item);
         $items["{$item['asin']}"] = $item;
@@ -383,12 +410,12 @@ function _amazon_item_batch_lookup_from_web($item_ids = array()) {
  */
 function amazon_item_lookup_from_db($item_ids = array()) {
   if (!empty($item_ids)) {
-    $sql  = "SELECT * FROM {amazon_item} ai WHERE ai.asin IN (";
-    $sql .= implode(',', array_fill(0, count($item_ids), "'%s'")) .') ';
-    $sql .= 'AND ai.timestamp > %d';
-    $results = db_query($sql, $item_ids, time() - variable_get('amazon_refresh_schedule', 86400));
+    $timestamp = REQUEST_TIME - variable_get('amazon_refresh_schedule', 86400);
+    $result = db_query('SELECT * from {amazon_item} WHERE asin IN (:asins) AND timestamp > :timestamp',
+      array('asins' => $item_ids, 'timestamp' => $timestamp),
+      array('fetch' => PDO::FETCH_ASSOC));
     $items = array();
-    while ($item = db_fetch_array($results)) {
+    foreach ($result as $item) {
       _amazon_load_child_data($item);
       $item += module_invoke_all('amazon_item_load', $item);
       $items["{$item['asin']}"] = $item;
@@ -404,24 +431,38 @@ function amazon_item_lookup_from_db($item_ids = array()) {
  *   Amazon data structure.
  */
 function _amazon_load_child_data(&$item) {
-  $result = db_query("SELECT type, participant FROM {amazon_item_participant} WHERE asin = '%s'", $item['asin']);
-  while ($participant = db_fetch_array($result)) {
+  $result = db_query('SELECT type, participant FROM {amazon_item_participant} WHERE asin = :asin',
+  array('asin' => $item['asin']),
+  array('fetch' => PDO::FETCH_ASSOC));
+  foreach ($result as $participant) {
     unset($participant['asin']);
     $item[$participant['type']][] = $participant['participant'];
     $item['participants'][] = $participant['participant'];
   }
 
-  $result = db_query("SELECT * FROM {amazon_item_image} WHERE asin = '%s'", $item['asin']);
-  while ($image = db_fetch_array($result)) {
+  $result = db_query('SELECT * FROM {amazon_item_image} WHERE asin = :asin',
+  array('asin' => $item['asin']),
+  array('fetch' => PDO::FETCH_ASSOC));
+  foreach ($result as $image) {
     unset($image['asin']);
     $item['imagesets'][$image['size']] = $image;
   }
 
-  $result = db_query("SELECT * FROM {amazon_item_editorial_review} WHERE asin = '%s'", $item['asin']);
-  while ($review = db_fetch_array($result)) {
+  $result = db_query('SELECT * FROM {amazon_item_editorial_review} WHERE asin = :asin',
+  array('asin' => $item['asin']),
+  array('fetch' => PDO::FETCH_ASSOC));
+  foreach ($result as $review) {
     unset($review['asin']);
     $item['editorialreviews'][] = $review;
   }
+  $result = db_query('SELECT * FROM {amazon_item_customer_review} WHERE asin = :asin',
+  array('asin' => $item['asin']),
+  array('fetch' => PDO::FETCH_ASSOC));
+  foreach ($result as $review) {
+    unset($review['asin']);
+    $item['customerreviews'][] = $review;
+  }
+
 }
 
 /**
@@ -435,41 +476,40 @@ function _amazon_load_child_data(&$item) {
 function amazon_item_clean_xml($xml) {
   $metadata = amazon_data_cache();
   $item = array();
-
   // Pull the absolute basic information Amazon keeps at the top level
   // of the XML tree, cast to string, and move on.
-  $item['asin'] = (string)$xml->ASIN;
+  $item['asin'] = (string) $xml->ASIN;
   if (empty($item['isbn'])) {
-    $item['isbn'] = (string)$xml->ItemAttributes->ISBN;
+    $item['isbn'] = (string) $xml->ItemAttributes->ISBN;
   }
   if (empty($item['ean'])) {
-    $item['ean'] = (string)$xml->ItemAttributes->EAN;
+    $item['ean'] = (string) $xml->ItemAttributes->EAN;
   }
-  $item['salesrank'] = (string)$xml->SalesRank;
-  $item['detailpageurl'] = (string)$xml->DetailPageURL;
+  $item['salesrank'] = (string) $xml->SalesRank;
+  $item['detailpageurl'] = (string) $xml->DetailPageURL;
 
   if (!empty($xml->ItemAttributes->ListPrice)) {
-    $item['listpriceamount'] = (string)$xml->ItemAttributes->ListPrice->Amount;
-    $item['listpricecurrencycode'] = (string)$xml->ItemAttributes->ListPrice->CurrencyCode;
-    $item['listpriceformattedprice'] = (string)$xml->ItemAttributes->ListPrice->FormattedPrice;
+    $item['listpriceamount'] = (string) $xml->ItemAttributes->ListPrice->Amount;
+    $item['listpricecurrencycode'] = (string) $xml->ItemAttributes->ListPrice->CurrencyCode;
+    $item['listpriceformattedprice'] = (string) $xml->ItemAttributes->ListPrice->FormattedPrice;
   }
   if (!empty($xml->OfferSummary->LowestNewPrice)) {
-    $item['lowestpriceamount'] = (string)$xml->OfferSummary->LowestNewPrice->Amount;
-    $item['lowestpricecurrencycode'] = (string)$xml->OfferSummary->LowestNewPrice->CurrencyCode;
-    $item['lowestpriceformattedprice'] = (string)$xml->OfferSummary->LowestNewPrice->FormattedPrice;
+    $item['lowestpriceamount'] = (string) $xml->OfferSummary->LowestNewPrice->Amount;
+    $item['lowestpricecurrencycode'] = (string) $xml->OfferSummary->LowestNewPrice->CurrencyCode;
+    $item['lowestpriceformattedprice'] = (string) $xml->OfferSummary->LowestNewPrice->FormattedPrice;
   }
   // Note that this one assumes we've searched with Merchant = Amazon.
   // Otherwise we can do an xpath search looking for the actual amazon listing.
-  if (!empty($xml->Offers->Offer[0]->OfferListing->Price) && (string)$xml->Offers->Offer[0]->Merchant->MerchantId == 'ATVPDKIKX0DER') {
-    $item['amazonpriceamount'] = (string)$xml->Offers->Offer[0]->OfferListing->Price->Amount;
-    $item['amazonpricecurrencycode'] = (string)$xml->Offers->Offer[0]->OfferListing->Price->CurrencyCode;
-    $item['amazonpriceformattedprice'] = (string)$xml->Offers->Offer[0]->OfferListing->Price->FormattedPrice;
+  if (!empty($xml->Offers->Offer[0]->OfferListing->Price) && (string) $xml->Offers->Offer[0]->Merchant->MerchantId == 'ATVPDKIKX0DER') {
+    $item['amazonpriceamount'] = (string) $xml->Offers->Offer[0]->OfferListing->Price->Amount;
+    $item['amazonpricecurrencycode'] = (string) $xml->Offers->Offer[0]->OfferListing->Price->CurrencyCode;
+    $item['amazonpriceformattedprice'] = (string) $xml->Offers->Offer[0]->OfferListing->Price->FormattedPrice;
   }
 
   $participant_types = split(',', AMAZON_PARTICIPANT_TYPES);
 
   // Pull in the basics of the ItemAttributes collection.
-  foreach((array)($xml->ItemAttributes) as $key => $value) {
+  foreach ((array) ($xml->ItemAttributes) as $key => $value) {
     if (is_string($value) && !in_array($key, $participant_types)) {
       $key = strtolower($key);
       $item[$key] = $value;
@@ -479,9 +519,9 @@ function amazon_item_clean_xml($xml) {
   // Handle the Authors/Artists/Etc.
   foreach ($participant_types as $key) {
     if (isset($xml->ItemAttributes->$key)) {
-      foreach($xml->ItemAttributes->$key as $value) {
-        $item[strtolower($key)][] = (string)$value;
-        $item['participants'][] = (string)$value;
+      foreach ($xml->ItemAttributes->$key as $value) {
+        $item[strtolower($key)][] = (string) $value;
+        $item['participants'][] = (string) $value;
       }
     }
   }
@@ -491,12 +531,12 @@ function amazon_item_clean_xml($xml) {
   // and ignore the rest for now.
   $supported_sizes = split(',', AMAZON_IMAGE_SIZES);
   if (isset($xml->ImageSets->ImageSet)) {
-    foreach((array)$xml->ImageSets->ImageSet as $key => $data) {
+    foreach ((array) $xml->ImageSets->ImageSet as $key => $data) {
       if (in_array($key, $supported_sizes)) {
         $item['imagesets'][strtolower($key)] = array(
-          'url' => (string)$data->URL,
-          'height' => (string)$data->Height,
-          'width' => (string)$data->Width,
+          'url' => (string) $data->URL,
+          'height' => (string) $data->Height,
+          'width' => (string) $data->Width,
         );
       }
     }
@@ -504,22 +544,22 @@ function amazon_item_clean_xml($xml) {
 
   // Handle the editorial reviews.
   if (isset($xml->EditorialReviews)) {
-    foreach($xml->EditorialReviews->EditorialReview as $data) {
+    foreach ($xml->EditorialReviews->EditorialReview as $data) {
       $item['editorialreviews'][] = array(
-        'source' => (string)$data->Source,
-        'content' => (string)$data->Content,
+        'source' => (string) $data->Source,
+        'content' => (string) $data->Content,
       );
     }
   }
 
   // And the customer reviews.
   if (isset($xml->CustomerReviews)) {
-    foreach($xml->CustomerReviews->Review as $data) {
+    foreach ($xml->CustomerReviews->Review as $data) {
       $item['customerreviews'][] = array(
-        'rating' => (string)$data->Rating,
-        'date' => (string)$data->Date,
-        'summary' => (string)$data->Summary,
-        'content' => (string)$data->Content,
+        'rating' => (string) $data->Rating,
+        'date' => (string) $data->Date,
+        'summary' => (string) $data->Summary,
+        'content' => (string) $data->Content,
       );
     }
   }
@@ -528,7 +568,7 @@ function amazon_item_clean_xml($xml) {
   // that would otherwise be ignored. We can't use module_invoke_all, as it
   // would lose the reference.
   foreach (module_implements('amazon_item_clean_xml') as $module) {
-    $function = $module .'_amazon_item_clean_xml';
+    $function = $module . '_amazon_item_clean_xml';
     $function($item, $xml);
   }
   return $item;
@@ -542,24 +582,48 @@ function amazon_item_clean_xml($xml) {
  *   No return value.
  */
 function amazon_item_insert($item) {
+  static $item_keys = NULL;
+  if (empty($item_keys)) {
+    require_once('amazon.install');
+    $schema = amazon_schema();
+    $item_keys = $schema['amazon_item']['fields'];
+  }
   // We have boatloads of data to insert in here, so we're going to
   // cheat and blow away the old entries first.
   amazon_item_delete($item['asin']);
 
   $metadata = amazon_data_cache();
 
-  $item['timestamp'] = time();
-  drupal_write_record('amazon_item', $item);
+  $item['timestamp'] = REQUEST_TIME;
+
+  // The db_insert needs fields that match exactly to the database,
+  // so we'll intersect with what the actual schema says.
+  $db_item = array_intersect_key($item, $item_keys);
+  try {
+    db_insert('amazon_item')
+    ->fields($db_item)
+    ->execute();
+  }
+  catch (Exception $e) {
+    amazon_db_error_watchdog("Failed to insert item into amazon_item table", $e);
+  }
 
   // Handle the various credits for a product, including Artist, Author,
   // Actor, etc. We map these to a separate table.
   if (in_array('creators', variable_get('amazon_core_data', array('creators', 'images')))) {
     $participant_types = split(',', AMAZON_PARTICIPANT_TYPES);
     foreach ($participant_types as $type) {
-      if (isset($item[strtolower($type)])){
-        foreach((array)$item[strtolower($type)] as $participant) {
+      if (isset($item[strtolower($type)])) {
+        foreach ((array) $item[strtolower($type)] as $participant) {
           $item_participant = array('asin' => $item['asin'], 'type' => strtolower($type), 'participant' => $participant);
-          drupal_write_record('amazon_item_participant', $item_participant);
+          try {
+            db_insert('amazon_item_participant')
+            ->fields($item_participant)
+            ->execute();
+          }
+          catch (Exception $e) {
+            amazon_db_error_watchdog("Failed to insert item into amazon_item_participant table", $e);
+          }
         }
       }
     }
@@ -568,9 +632,16 @@ function amazon_item_insert($item) {
   // Save the product images if they exist.
   if (in_array('images', variable_get('amazon_core_data', array('creators', 'images')))) {
     if (isset($item['imagesets'])) {
-      foreach($item['imagesets'] as $size => $data) {
+      foreach ($item['imagesets'] as $size => $data) {
         $image = array('asin' => $item['asin'], 'size' => $size, 'height' => $data['height'], 'width' => $data['width'], 'url' => $data['url']);
-        drupal_write_record('amazon_item_image', $image);
+        try {
+          db_insert('amazon_item_image')
+          ->fields($image)
+          ->execute();
+        }
+        catch (Exception $e) {
+          amazon_db_error_watchdog("Failed to insert item into amazon_item_image table", $e);
+        }
       }
     }
   }
@@ -578,18 +649,33 @@ function amazon_item_insert($item) {
   // Save the editorial reviews if they exist.
   if (in_array('editorial_reviews', variable_get('amazon_core_data', array('creators', 'images')))) {
     if (isset($item['editorialreviews'])) {
-      foreach($item['editorialreviews'] as $data) {
+      foreach ($item['editorialreviews'] as $data) {
         $review = array('asin' => $item['asin'], 'source' => $data['source'], 'content' => $data['content']);
-        drupal_write_record('amazon_item_editorial_review', $review);
+        try {
+          db_insert('amazon_item_editorial_review')
+          ->fields($review)
+          ->execute();
+        }
+        catch (Exception $e) {
+          amazon_db_error_watchdog("Failed to insert item into amazon_item_editorial_review table", $e);
+        }
       }
     }
   }
   // Save the customer reviews if they exist.
   if (in_array('customer_reviews', variable_get('amazon_core_data', array('creators', 'images')))) {
     if (isset($item['customerreviews'])) {
-      foreach($item['customerreviews'] as $data) {
+      foreach ($item['customerreviews'] as $data) {
         $review = array('asin' => $item['asin'], 'rating' => $data['rating'], 'date' => $data['date'], 'summary' => $data['summary'], 'content' => $data['content']);
-        drupal_write_record('amazon_item_customer_review', $review);
+        try {
+          db_insert('amazon_item_customer_review')
+          ->fields($review)
+          ->execute();
+        }
+        catch (Exception $e) {
+          amazon_db_error_watchdog("Failed to insert item into amazon_item_editorial_review table", $e);
+        }
+
       }
     }
   }
@@ -605,11 +691,21 @@ function amazon_item_insert($item) {
  */
 function amazon_item_delete($asin) {
   module_invoke_all('amazon_item_delete', $asin);
-  db_query("DELETE FROM {amazon_item} WHERE asin = '%s'", $asin);
-  db_query("DELETE FROM {amazon_item_participant} WHERE asin = '%s'", $asin);
-  db_query("DELETE FROM {amazon_item_image} WHERE asin = '%s'", $asin);
-  db_query("DELETE FROM {amazon_item_editorial_review} WHERE asin = '%s'", $asin);
-  db_query("DELETE FROM {amazon_item_customer_review} WHERE asin = '%s'", $asin);
+  db_delete('amazon_item')
+  ->condition('asin', $asin)
+  ->execute();
+  db_delete('amazon_item_participant')
+  ->condition('asin', $asin)
+  ->execute();
+  db_delete('amazon_item_image')
+  ->condition('asin', $asin)
+  ->execute();
+  db_delete('amazon_item_editorial_review')
+  ->condition('asin', $asin)
+  ->execute();
+  db_delete('amazon_item_customer_review')
+  ->condition('asin', $asin)
+  ->execute();
 }
 
 /**
@@ -623,7 +719,7 @@ function amazon_item_delete($asin) {
  *   after removing dashes.
  */
 function amazon_convert_to_asin($input) {
-  $input = preg_replace('/-/','',$input); // Remove dashes.
+  $input = preg_replace('/-/', '', $input); // Remove dashes.
   if (preg_match('/^https?:/', $input)) {
     $parts = preg_split('/\//', $input);
     $asin = $parts[5]; // 6th section of split, right after /dp/
@@ -654,7 +750,7 @@ function amazon_ean_to_asin($ean) {
   );
   $results = amazon_http_request('ItemLookup', $params);
   if (!empty($results->Items->Item->ASIN)) {
-    $asin = (string)$results->Items->Item->ASIN;
+    $asin = (string) $results->Items->Item->ASIN;
   }
   return $asin;
 }
@@ -664,30 +760,34 @@ function amazon_ean_to_asin($ean) {
 
 function amazon_item_node_save($asin, $node, $module = 'amazon', $weight = 0) {
   amazon_item_node_delete($asin, $nid, $module);
-  db_query("INSERT INTO {amazon_item_node} (asin, vid, nid, module, weight) VALUES ('%s', %d, '%s', %d)", $asin, $nid, $module, $weight);
+  try {
+    $id = db_insert('amazon_item_node')
+    ->fields(array(
+          'asin' => $asin,
+          'nid' => $nid,
+          'module' => $module,
+          'weight' => $weight,
+    ))
+    ->execute();
+  } catch(Exception $e) {
+    amazon_db_error_watchdog('Failed to save amazon_item_node.', $e);
+  }
 }
 
 function amazon_item_node_delete($asin = NULL, $nid = NULL, $module = NULL) {
-  $sql = "DELETE FROM {amazon_item_node} WHERE 1 = 1";
-  $params = array();
+  $delete = db_delete('amazon_item_node');
   if (isset($asin)) {
-    $sql = " AND asin = '%s'";
-    $params[] = $asin;
+    $delete = $delete->condition('asin', $asin);
   }
 
   if (isset($nid)) {
-    $sql = " AND nid = %d";
-    $params[] = $nid;
+    $delete = $delete->condition('nid', $nid);
   }
 
   if (isset($module)) {
-    $sql = " AND module = '%s'";
-    $params[] = $module;
-  }
-
-  if (count($params)) {
-    db_query($sql, $params);
+    $delete = $delete->condition('module', $module);
   }
+  $delete->execute();
 }
 
 
@@ -759,14 +859,14 @@ function amazon_get_associate_id() {
 function amazon_cron() {
   // Here, we're going to chug through all the existing ASINs and update them.
   // We'll grab 50 at a time to avoid thrashing things.
-  $sql = "SELECT asin FROM {amazon_item} WHERE timestamp < %d";
-  $result = db_query_range($sql, time() - variable_get('amazon_refresh_schedule', 86400), 0, 50);
-  $asins = array();
-
-  while($item = db_fetch_array($result)) {
-    $asins[] = $item['asin'];
-  }
-
+  $per_cron_limit = 50;
+  $needs_update_time = REQUEST_TIME - variable_get('amazon_refresh_schedule', 86400);
+  $result = db_select('amazon_item', NULL, array('fetch' => PDO::FETCH_ASSOC))
+            ->fields('amazon_item', array('asin'))
+            ->condition('timestamp', $needs_update_time, '<')
+            ->range(0, $per_cron_limit)
+            ->execute();
+  $asins = $result->FetchCol();
   if (!empty($asins)) {
     if ($items = amazon_item_lookup_from_web($asins)) {
       foreach ($items as $item) {
@@ -780,6 +880,7 @@ function amazon_cron() {
   }
 }
 
+//D6FIX: hook_token_info
 function amazon_token_list($type = 'all') {
   if ($type == 'amazon_item' || $type == 'all') {
     $tokens['amazon_item']['asin'] = t('Product ID');
@@ -802,9 +903,10 @@ function amazon_token_list($type = 'all') {
   }
 }
 
+//D6FIX: hook_tokens()
 function amazon_token_values($type, $object = NULL, $options = array()) {
   if ($type == 'amazon_item' || $type == 'all') {
-    $item = (array)$object;
+    $item = (array) $object;
     $values['asin'] = check_plain($item['asin']);
     $values['isbn'] = check_plain($item['isbn']);
     $values['ean'] = check_plain($item['ean']);
@@ -851,10 +953,10 @@ function template_preprocess_amazon_views_view_row_item(&$vars) {
     $item['view'] = $vars['view'];
     $vars['amazon_item'] = $item;
     if ($options['display_format'] == 'inline') {
-      $vars['content'] = theme('amazon_item_inline', $item, $options['display_format']);
+      $vars['content'] = theme('amazon_item_inline', array('item' => $item, 'style' => $options['display_format']));
     }
     else {
-      $vars['content'] = theme('amazon_item', $item, $options['display_format']);
+      $vars['content'] = theme('amazon_item', array('item' => $item, 'style' => $options['display_format']));
     }
   }
 }
@@ -862,3 +964,18 @@ function template_preprocess_amazon_views_view_row_item(&$vars) {
 function amazon_init() {
   drupal_add_css(drupal_get_path('module', 'amazon') . '/amazon.css');
 }
+
+/**
+ * Have watchdog emit complete errors about a database exception.
+ *
+ * @param $msg
+ *   The message explaining the error.
+ *   The message should not be localized, as it will be passed to watchdog().
+ * @param $e
+ *   The exception which was caught
+ *
+ */
+function amazon_db_error_watchdog($msg, $e) {
+  watchdog('amazon', "$msg: Message = %message, query= %query",
+    array('%message' => $e->getMessage(), '%query' => $e->query_string));
+}
\ No newline at end of file
diff --git amazon_examples/amazon_examples.defaults.inc amazon_examples/amazon_examples.defaults.inc
deleted file mode 100644
index 1f57c07..0000000
--- amazon_examples/amazon_examples.defaults.inc
+++ /dev/null
@@ -1,66 +0,0 @@
-<?php
-
-/**
- * Helper to implementation of hook_content_default_fields().
- */
-function _amazon_examples_content_default_fields() {
-  $fields = array();
-
-  // Exported field: field_asin
-  $fields[] = array(
-    'field_name' => 'field_asin',
-    'type_name' => 'amazon_example',
-    'display_settings' => array(
-      'label' => array(
-        'format' => 'above',
-        'exclude' => 0,
-      ),
-      'teaser' => array(
-        'format' => 'default',
-        'exclude' => 0,
-      ),
-      'full' => array(
-        'format' => 'default',
-        'exclude' => 0,
-      ),
-      '4' => array(
-        'format' => 'default',
-        'exclude' => 0,
-      ),
-      '2' => array(
-        'format' => 'default',
-        'exclude' => 0,
-      ),
-      '3' => array(
-        'format' => 'default',
-        'exclude' => 0,
-      ),
-    ),
-    'widget_active' => '1',
-    'type' => 'asin',
-    'required' => '1',
-    'multiple' => '0',
-    'module' => 'asin',
-    'active' => '1',
-    'widget' => array(
-      'default_value' => array(
-        '0' => array(
-          'asin' => '',
-        ),
-      ),
-      'default_value_php' => NULL,
-      'label' => 'ASIN',
-      'weight' => '-4',
-      'description' => 'Enter a 10-digit ASIN that identifies an Amazon item. ',
-      'type' => 'asin_text',
-      'module' => 'asin',
-    ),
-  );
-
-  // Translatables
-  array(
-    t('ASIN'),
-  );
-
-  return $fields;
-}
diff --git amazon_examples/amazon_examples.features.inc amazon_examples/amazon_examples.features.inc
deleted file mode 100644
index 65d3f87..0000000
--- amazon_examples/amazon_examples.features.inc
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-
-/**
- * Implementation of hook_content_default_fields().
- */
-function amazon_examples_content_default_fields() {
-  module_load_include('inc', 'amazon_examples', 'amazon_examples.defaults');
-  $args = func_get_args();
-  return call_user_func_array('_amazon_examples_content_default_fields', $args);
-}
-
-/**
- * Implementation of hook_node_info().
- */
-function amazon_examples_node_info() {
-  module_load_include('inc', 'amazon_examples', 'amazon_examples.features.node');
-  $args = func_get_args();
-  return call_user_func_array('_amazon_examples_node_info', $args);
-}
-
-/**
- * Implementation of hook_views_default_views().
- */
-function amazon_examples_views_default_views() {
-  module_load_include('inc', 'amazon_examples', 'amazon_examples.features.views');
-  $args = func_get_args();
-  return call_user_func_array('_amazon_examples_views_default_views', $args);
-}
diff --git amazon_examples/amazon_examples.features.node.inc amazon_examples/amazon_examples.features.node.inc
deleted file mode 100644
index 24c0c49..0000000
--- amazon_examples/amazon_examples.features.node.inc
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-
-/**
- * Helper to implementation of hook_node_info().
- */
-function _amazon_examples_node_info() {
-  $items = array(
-    'amazon_example' => array(
-      'name' => t('Amazon Example'),
-      'module' => 'features',
-      'description' => t('This is just an example content type to show how Amazon module can be used with CCK fields. A single CCK field is provided. You can populate a few nodes and then see how views work and how these are displayed.  A sample view that uses this CCK type is provided.'),
-      'has_title' => '1',
-      'title_label' => t('Title'),
-      'has_body' => '0',
-      'body_label' => '',
-      'min_word_count' => '0',
-      'help' => '',
-    ),
-  );
-  return $items;
-}
diff --git amazon_examples/amazon_examples.features.views.inc amazon_examples/amazon_examples.features.views.inc
deleted file mode 100644
index 3f5dc9d..0000000
--- amazon_examples/amazon_examples.features.views.inc
+++ /dev/null
@@ -1,291 +0,0 @@
-<?php
-
-/**
- * Helper to implementation of hook_views_default_views().
- */
-function _amazon_examples_views_default_views() {
-  $views = array();
-
-  // Exported view: amazon_example_view
-  $view = new view;
-  $view->name = 'amazon_example_view';
-  $view->description = 'Amazon Example View';
-  $view->tag = 'examples';
-  $view->view_php = '';
-  $view->base_table = 'node';
-  $view->is_cacheable = FALSE;
-  $view->api_version = 2;
-  $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
-  $handler = $view->new_display('default', 'Defaults', 'default');
-  $handler->override_option('relationships', array(
-    'field_asin_asin' => array(
-      'label' => 'field_asin_asin',
-      'required' => 1,
-      'id' => 'field_asin_asin',
-      'table' => 'node_data_field_asin',
-      'field' => 'field_asin_asin',
-      'relationship' => 'none',
-    ),
-  ));
-  $handler->override_option('fields', array(
-    'nid' => array(
-      'id' => 'nid',
-      'table' => 'node',
-      'field' => 'nid',
-    ),
-    'asin' => array(
-      'label' => 'ASIN',
-      'alter' => array(
-        'alter_text' => 0,
-        'text' => '',
-        'make_link' => 0,
-        'path' => '',
-        'link_class' => '',
-        'alt' => '',
-        'prefix' => '',
-        'suffix' => '',
-        'help' => '',
-        'trim' => 0,
-        'max_length' => '',
-        'word_boundary' => 1,
-        'ellipsis' => 1,
-        'strip_tags' => 0,
-        'html' => 0,
-      ),
-      'exclude' => 0,
-      'id' => 'asin',
-      'table' => 'amazon_item',
-      'field' => 'asin',
-      'relationship' => 'field_asin_asin',
-    ),
-    'title' => array(
-      'label' => 'Title',
-      'alter' => array(
-        'alter_text' => 0,
-        'text' => '',
-        'make_link' => 0,
-        'path' => '',
-        'link_class' => '',
-        'alt' => '',
-        'prefix' => '',
-        'suffix' => '',
-        'help' => '',
-        'trim' => 0,
-        'max_length' => '',
-        'word_boundary' => 1,
-        'ellipsis' => 1,
-        'strip_tags' => 0,
-        'html' => 0,
-      ),
-      'link_format' => 'plain',
-      'exclude' => 0,
-      'id' => 'title',
-      'table' => 'amazon_item',
-      'field' => 'title',
-      'relationship' => 'field_asin_asin',
-    ),
-    'detailpageurl' => array(
-      'label' => 'Detail page URL',
-      'alter' => array(
-        'alter_text' => 0,
-        'text' => '',
-        'make_link' => 0,
-        'path' => '',
-        'link_class' => '',
-        'alt' => '',
-        'prefix' => '',
-        'suffix' => '',
-        'help' => '',
-        'trim' => 0,
-        'max_length' => '',
-        'word_boundary' => 1,
-        'ellipsis' => 1,
-        'strip_tags' => 0,
-        'html' => 0,
-      ),
-      'exclude' => 1,
-      'id' => 'detailpageurl',
-      'table' => 'amazon_item',
-      'field' => 'detailpageurl',
-      'relationship' => 'field_asin_asin',
-      'override' => array(
-        'button' => 'Override',
-      ),
-    ),
-    'listpriceformattedprice' => array(
-      'id' => 'listpriceformattedprice',
-      'table' => 'amazon_item',
-      'field' => 'listpriceformattedprice',
-    ),
-    'publisher' => array(
-      'id' => 'publisher',
-      'table' => 'amazon_item',
-      'field' => 'publisher',
-    ),
-    'publicationdate' => array(
-      'label' => 'Publication date',
-      'alter' => array(
-        'alter_text' => 0,
-        'text' => '',
-        'make_link' => 0,
-        'path' => '',
-        'link_class' => '',
-        'alt' => '',
-        'prefix' => '',
-        'suffix' => '',
-        'help' => '',
-        'trim' => 0,
-        'max_length' => '',
-        'word_boundary' => 1,
-        'ellipsis' => 1,
-        'strip_tags' => 0,
-        'html' => 0,
-      ),
-      'date_format' => 'default',
-      'custom_date_format' => '',
-      'exclude' => 0,
-      'id' => 'publicationdate',
-      'table' => 'amazon_book',
-      'field' => 'publicationdate',
-      'relationship' => 'field_asin_asin',
-    ),
-    'product_image' => array(
-      'label' => 'Image URL',
-      'alter' => array(
-        'alter_text' => 0,
-        'text' => '',
-        'make_link' => 0,
-        'path' => '',
-        'link_class' => '',
-        'alt' => '',
-        'prefix' => '',
-        'suffix' => '',
-        'help' => '',
-        'trim' => 0,
-        'max_length' => '',
-        'word_boundary' => 1,
-        'ellipsis' => 1,
-        'strip_tags' => 0,
-        'html' => 0,
-      ),
-      'image_size' => 'mediumimage',
-      'link_format' => 'plain',
-      'exclude' => 1,
-      'id' => 'product_image',
-      'table' => 'amazon_item_image',
-      'field' => 'product_image',
-      'relationship' => 'field_asin_asin',
-      'presentation_format' => 'plain_url',
-    ),
-    'nothing' => array(
-      'label' => 'Custom: Example Link to Image',
-      'alter' => array(
-        'text' => 'Example link/image: <a href="[detailpageurl]"><img src="[product_image]"></a>',
-        'make_link' => 0,
-        'path' => '',
-        'link_class' => '',
-        'alt' => '',
-        'prefix' => '',
-        'suffix' => '',
-        'help' => '',
-        'trim' => 0,
-        'max_length' => '',
-        'word_boundary' => 1,
-        'ellipsis' => 1,
-        'strip_tags' => 0,
-        'html' => 0,
-      ),
-      'exclude' => 0,
-      'id' => 'nothing',
-      'table' => 'views',
-      'field' => 'nothing',
-      'relationship' => 'none',
-    ),
-  ));
-  $handler->override_option('filters', array(
-    'status' => array(
-      'operator' => '=',
-      'value' => '1',
-      'group' => '0',
-      'exposed' => FALSE,
-      'expose' => array(
-        'operator' => FALSE,
-        'label' => '',
-      ),
-      'id' => 'status',
-      'table' => 'node',
-      'field' => 'status',
-      'relationship' => 'none',
-    ),
-    'type' => array(
-      'operator' => 'in',
-      'value' => array(
-        'amazon_example' => 'amazon_example',
-      ),
-      'group' => '0',
-      'exposed' => FALSE,
-      'expose' => array(
-        'operator' => FALSE,
-        'label' => '',
-      ),
-      'id' => 'type',
-      'table' => 'node',
-      'field' => 'type',
-      'relationship' => 'none',
-    ),
-  ));
-  $handler->override_option('access', array(
-    'type' => 'none',
-  ));
-  $handler->override_option('cache', array(
-    'type' => 'none',
-  ));
-  $handler->override_option('header', 'This is an example view that you can experiment with. 
-
-If you see no results, it\'s because you have to create some nodes first. Go to Create Content-&gt;Amazon Example and create a node or two. Try using these ASINs: 0596515804, 1430209895, 0470429038.');
-  $handler->override_option('header_format', '1');
-  $handler->override_option('header_empty', 1);
-  $handler->override_option('use_ajax', TRUE);
-  $handler->override_option('use_pager', '1');
-  $handler->override_option('style_plugin', 'table');
-  $handler->override_option('style_options', array(
-    'grouping' => '',
-    'override' => 1,
-    'sticky' => 0,
-    'order' => 'asc',
-    'columns' => array(
-      'asin' => 'asin',
-      'nid' => 'nid',
-    ),
-    'info' => array(
-      'asin' => array(
-        'sortable' => 0,
-        'separator' => '',
-      ),
-      'nid' => array(
-        'sortable' => 0,
-        'separator' => '',
-      ),
-    ),
-    'default' => '-1',
-  ));
-  $handler = $view->new_display('page', 'Page', 'page_1');
-  $handler->override_option('path', 'amazon_example_view');
-  $handler->override_option('menu', array(
-    'type' => 'normal',
-    'title' => 'Amazon Example View',
-    'description' => '',
-    'weight' => '0',
-    'name' => 'navigation',
-  ));
-  $handler->override_option('tab_options', array(
-    'type' => 'none',
-    'title' => '',
-    'description' => '',
-    'weight' => 0,
-  ));
-
-  $views[$view->name] = $view;
-
-  return $views;
-}
diff --git amazon_examples/amazon_examples.info amazon_examples/amazon_examples.info
deleted file mode 100644
index a4e5676..0000000
--- amazon_examples/amazon_examples.info
+++ /dev/null
@@ -1,14 +0,0 @@
-core = "6.x"
-dependencies[] = "amazon"
-dependencies[] = "amazon_media"
-dependencies[] = "asin"
-dependencies[] = "features"
-dependencies[] = "views"
-description = "Provides Amazon module CCK type and view as a demo"
-features[content][] = "amazon_example-field_asin"
-features[node][] = "amazon_example"
-features[views][] = "amazon_example_view"
-name = "Amazon Examples"
-package = "Amazon"
-project = "amazon_examples"
-version = "6.x-1.0-beta9"
diff --git amazon_examples/amazon_examples.module amazon_examples/amazon_examples.module
deleted file mode 100644
index 0ce1b04..0000000
--- amazon_examples/amazon_examples.module
+++ /dev/null
@@ -1,3 +0,0 @@
-<?php
-
-include_once('amazon_examples.features.inc');
diff --git amazon_filter/amazon_filter.info amazon_filter/amazon_filter.info
index d42b6f0..205783d 100644
--- amazon_filter/amazon_filter.info
+++ amazon_filter/amazon_filter.info
@@ -2,4 +2,6 @@ name = Amazon Filter
 description = Lets writers use the [amazon] tag to embed Amazon product information in text.
 package = "Amazon"
 dependencies[] = amazon
-core = 6.x
+core = 7.x
+
+files[] = amazon_filter.module
diff --git amazon_filter/amazon_filter.module amazon_filter/amazon_filter.module
index afbcfa5..b575811 100644
--- amazon_filter/amazon_filter.module
+++ amazon_filter/amazon_filter.module
@@ -6,9 +6,9 @@
  */
 
 /**
- * Implementation of hook_filter_tips().
+ * Implements of hook_filter_tips().
  */
-function amazon_filter_filter_tips($delta, $format, $long = FALSE) {
+function _amazon_filter_tips($filter, $format, $long = FALSE) {
   if ($long) {
     return t('Get Amazon product data using [amazon ASIN selector], for example, [amazon 0399155341 thumbnail],
     [amazon 0399155341 full], or [amazon 0399155341 inline].
@@ -25,33 +25,32 @@ function amazon_filter_filter_tips($delta, $format, $long = FALSE) {
     For example, [amazon 0596515804 title] will provide the title of the item, and
     [amazon 0596515804 largeimage] will be replaced with an img tag giving the large image.
     A complete description of filters is <a href="http://drupal.org/node/595464#filters">on the Amazon module handbook page</a>.');
-  } else {
+  }
+  else {
     return t('Link to Amazon products with: [amazon product_id inline|full|thumbnail|datadescriptor]. Example: [amazon 1590597559 thumbnail] or [amazon 1590597559 author]. Details are <a href="http://drupal.org/node/595464#filters" target="_blank">on the Amazon module handbook page</a>.');
   }
 }
 
 /**
- * Implementation of hook_filter().
+ * Implements hook_filter_info().
  */
-function amazon_filter_filter($op, $delta = 0, $format = -1, $text = '') {
-  if ($op == 'list') {
-    return array(0 => t('Amazon filter'));
-  }
-
-  switch ($delta) {
-    case 0:
-      switch ($op) {
-        case 'description':
-          return t('Lets writers use the [amazon] tag to embed Amazon product information in text.');
-        case 'prepare':
-          return $text;
-        case 'process':
-          return _amazon_filter_process_text($text);
-      }
-      break;
-  }
+function amazon_filter_info() {
+  $filters['amazon'] = array(
+    'title' => t('Amazon filter'),
+    'description' => t('Provides access to many types of Amazon data. Simplest usage: [amazon ASIN inline], for example [amazon 0596515804 inline].'),
+    'process callback'  => '_amazon_filter_process_text',
+    'tips callback' => '_amazon_filter_tips',
+  );
+  return $filters;
 }
 
+/**
+ * Actual filter processing function - changes [amazon <whatever>] in text.
+ * @param $text
+ *   Text to be transformed.
+ * @return
+ *   The transformed text.
+ */
 function _amazon_filter_process_text($text) {
   $pattern = "/\[amazon +(.*?)(?: +(.*?))?\]/";
   $matches = array();
@@ -71,19 +70,23 @@ function _amazon_filter_process_text($text) {
         switch ($action) {
           case "":
           case 'inline':
-            $replace[] = theme('amazon_inline_item', $item);
+            $replace[] = theme('amazon_inline_item', array('item' =>$item));
             break;
 
-          case 'thumbnail': // Handle themeable cases, like thumbnail, full.
+          case 'thumbnail':
+ // Handle themeable cases, like thumbnail, full.
           case 'full':
-            $replace[] = theme('amazon_item', $item, $action);
+            $replace[] = theme('amazon_item', array('item' => $item, 'style' => $action));
             break;
 
-          default:  // Allow to use anything found in the item.
-            $replace[] = theme('amazon_detail', $item, $action);
+          default:
+ // Allow to use anything found in the item.
+            $replace[] = theme('amazon_detail', array('item' => $item, 'detail' => $action));
             break;
         }
-      } else { // error case
+      }
+      else {
+ // error case
         $replace[] = "<!-- The Amazon product '$asin' could not be found.-->";
       }
     }
diff --git amazon_media/amazon_media.info amazon_media/amazon_media.info
index 425206d..e7d0bad 100644
--- amazon_media/amazon_media.info
+++ amazon_media/amazon_media.info
@@ -2,5 +2,14 @@ name = Amazon media
 description = Stores extended Amazon product information for books, music, DVDs, and software.
 package = Amazon
 dependencies[] = amazon
-core = 6.x
+core = 7.x
 php = 5.2
+
+files[] = amazon-item-book-details.tpl.php
+files[] = amazon-item-dvd-details.tpl.php
+files[] = amazon-item-software-details.tpl.php
+files[] = amazon-item-video-games-details.tpl.php
+files[] = amazon_media.install
+files[] = amazon_media.module
+files[] = amazon_media.theme.inc
+files[] = amazon_media.views.inc
diff --git amazon_media/amazon_media.install amazon_media/amazon_media.install
index 7471556..9de7d3c 100644
--- amazon_media/amazon_media.install
+++ amazon_media/amazon_media.install
@@ -1,4 +1,10 @@
 <?php
+/**
+ * @file
+ * Install, update and uninstall functions for the amazon_media module.
+ *
+ */
+
 // $Id$
 
 function amazon_media_install() {
@@ -64,22 +70,3 @@ function amazon_media_uninstall() {
   db_query("DROP TABLE {amazon_software}");
 }
 
-
-function amazon_media_update_6001() {
-  $ret = array();
-
-  $field = array('type' => 'varchar', 'length' => 64);
-  db_change_field($ret, 'amazon_dvd', 'audiencerating', 'theatricalreleasedate', $field);
-
-  return $ret;
-}
-
-/**
- * Add the isbn and ean fields to a book item.
- */
-function amazon_media_update_6002() {
-  $ret = array();
-  db_add_field($ret, 'amazon_book', 'isbn', array('type' => 'varchar', 'length' => 20));
-  db_add_field($ret, 'amazon_book', 'ean', array('type' => 'varchar', 'length' => 20));
-  return $ret;
-}
\ No newline at end of file
diff --git amazon_media/amazon_media.module amazon_media/amazon_media.module
index 5eaec4a..328b993 100644
--- amazon_media/amazon_media.module
+++ amazon_media/amazon_media.module
@@ -1,21 +1,31 @@
 <?php
+// $Id$
+/**
+ * @file
+ *   Provides additional behaviors and data type for amazon items which are
+ *   DVDs, software, video games, music, etc.
+ */
 
+/**
+ * Implements hook_theme().
+ *
+ */
 function amazon_media_theme() {
   $templates = array(
     'amazon_inline_item_dvd' => array(
-      'arguments' => array('item' => array()),
+      'variables' => array('item' => array()),
       'file' => 'amazon_media.theme.inc',
     ),
     'amazon_inline_item_software' => array(
-      'arguments' => array('item' => array()),
+      'variables' => array('item' => array()),
       'file' => 'amazon_media.theme.inc',
     ),
     'amazon_inline_item_video_games' => array(
-      'arguments' => array('item' => array()),
+      'variables' => array('item' => array()),
       'file' => 'amazon_media.theme.inc',
     ),
     'amazon_inline_item_console_video_games' => array(
-      'arguments' => array('item' => array()),
+      'variables' => array('item' => array()),
       'function' => 'theme_amazon_inline_item_video_games',
       'file' => 'amazon_media.theme.inc',
     ),
@@ -31,7 +41,7 @@ function amazon_media_theme_registry_alter(&$theme_registry) {
   if (!empty($theme_registry['amazon_item'])) {
     // We'll try our best to avoid stepping on theme template files.
     // God, how I hate template inheritance.
-    if (count($theme_registry['amazon_item']['theme paths']) > 1) {
+    if (!empty($theme_registry['amazon_item']['theme_paths']) && count($theme_registry['amazon_item']['theme paths']) > 1) {
       $theme = array_pop($theme_registry['amazon_item']['theme paths']);
     }
     $theme_registry['amazon_item']['theme paths'][] = drupal_get_path('module', 'amazon_media');
@@ -41,6 +51,11 @@ function amazon_media_theme_registry_alter(&$theme_registry) {
   }
 }
 
+/**
+ * Implements hook_preprocess.
+ *
+ * @param $variables
+ */
 function amazon_media_preprocess_amazon_item(&$variables) {
   if (!empty($variables['theatricalreleasedate'])) {
     $date = explode('-', $variables['theatricalreleasedate']);
@@ -66,65 +81,91 @@ function amazon_media_preprocess_amazon_item(&$variables) {
   );
 }
 
-
+/**
+ * Load and return additional information for an ASINI item.
+ * @param $item
+ *   The item requiring additions.
+ * @return
+ *   The added array elements, as an array.
+ */
 function amazon_media_amazon_item_load($item) {
-  switch ($item['producttypename']) {
-    case 'ABIS_BOOK':
-      $additions = db_fetch_array(db_query("SELECT * FROM {amazon_book} WHERE asin = '%s'", $item['asin']));
-      break;
-    case 'VIDEO_DVD':
-    case 'ABIS_DVD':
-      $additions = db_fetch_array(db_query("SELECT * FROM {amazon_dvd} WHERE asin = '%s'", $item['asin']));
-      break;
-    case 'ABIS_MUSIC':
-      $additions = db_fetch_array(db_query("SELECT * FROM {amazon_music} WHERE asin = '%s'", $item['asin']));
-      break;
-    case 'CONSOLE_VIDEO_GAMES':
-    case 'VIDEO_GAMES':
-    case 'SOFTWARE':
-      $additions = db_fetch_array(db_query("SELECT * FROM {amazon_software} WHERE asin = '%s'", $item['asin']));
-      break;
-  }
-  if (isset($additions)) {
-    return $additions;
-  }
+  $table = amazon_media_get_table_name($item);
+  $additions = db_query("SELECT * FROM {$table} WHERE asin = :asin",
+    array('asin' => $item['asin']))->fetchAssoc();
+  return $additions;
+}
+
+/**
+ * Given an item, return the name of the table it's associated with.
+ * @param $item
+ *   populated amazon_item with $item['producttypename'] populated.
+ * @return
+ *   the name of the associated table.
+ */
+function amazon_media_get_table_name($item) {
+  static $names = array('ABIS_BOOK' => 'amazon_book',
+    'VIDEO_DVD' => 'amazon_dvd',
+    'ABIS_DVD' => 'amazon_dvd',
+    'ABIS_MUSIC' => 'amazon_music',
+    'CONSOLE_VIDEO_GAMES' => 'amazon_software',
+    'VIDEO_GAMES' => 'amazon_software',
+    'SOFTWARE' => 'amazon_software',
+  );
+  return $names[$item['producttypename']];
 }
 
+/**
+ * Insert the associated information into the related table.
+ * @param $item
+ *   Populated amazon item record.
+ */
 function amazon_media_amazon_item_insert($item) {
-  switch ($item['producttypename']) {
-    case 'ABIS_BOOK':
-      drupal_write_record('amazon_book', $item);
-      break;
-    case 'VIDEO_DVD':
-    case 'ABIS_DVD':
-      drupal_write_record('amazon_dvd', $item);
-      break;
-    case 'ABIS_MUSIC':
-      // Often the artist is an array.
-      if (!empty($item['artist']) && is_array($item['artist'])) {
-        $item['artist'] = join(",", $item['artist']);
-      }
-      drupal_write_record('amazon_music', $item);
-      break;
-    case 'CONSOLE_VIDEO_GAMES':
-    case 'VIDEO_GAMES':
-    case 'SOFTWARE':
-      drupal_write_record('amazon_software', $item);
-      break;
+  static $item_keys = NULL;
+  if (empty($item_keys)) {
+    require_once('amazon_media.install');
+    $schema = amazon_media_schema();
+    $item_keys = $schema;
+  }
+  $table = amazon_media_get_table_name($item);
+
+  // We need to present a record that only has the items in it used by
+  // this table.
+  $db_item = array_intersect_key($item, $item_keys[$table]['fields']);
+
+  try {
+    db_insert($table)
+    ->fields($db_item)
+    ->execute();
+  }
+  catch (Exception $e) {
+    amazon_db_error_watchdog("Failed to insert item into amazon table", $e);
   }
 }
 
+/**
+ * Delete a record using the asin as key.
+ * @param $asin
+ *   the asin to delete.
+ */
 function amazon_media_amazon_item_delete($asin) {
   // This is pretty inefficient; we're going to thrash these tables
   // every time a product gets deleted or updated. We'll solve it later.
-  db_query("DELETE FROM {amazon_book} WHERE asin = '%s'", $asin);
-  db_query("DELETE FROM {amazon_dvd} WHERE asin = '%s'", $asin);
-  db_query("DELETE FROM {amazon_music} WHERE asin = '%s'", $asin);
-  db_query("DELETE FROM {amazon_software} WHERE asin = '%s'", $asin);
+  db_delete('amazon_book')
+    ->condition('asin', $asin)
+  ->execute();
+  db_delete('amazon_dvd')
+    ->condition('asin', $asin)
+  ->execute();
+  db_delete('amazon_music')
+    ->condition('asin', $asin)
+  ->execute();
+  db_delete('amazon_software')
+    ->condition('asin', $asin)
+  ->execute();
 }
 
 /**
- * Implementation of hook_views_api.
+ * Implements hook_views_api.
  */
 function amazon_media_views_api() {
   return array('api' => 2);
diff --git amazon_media/amazon_media.theme.inc amazon_media/amazon_media.theme.inc
index 782b32d..25dffef 100644
--- amazon_media/amazon_media.theme.inc
+++ amazon_media/amazon_media.theme.inc
@@ -1,36 +1,54 @@
 <?php
+// $Id$
+
+/**
+ * Implements theme_ with specialty dvd.
+ *
+ * @param $item
+ *   fully populated amazon item.
+ * @param $style
+ *   'full', 'thumbnail', or whatever.
+ */
 
 function theme_amazon_item__dvd($item, $style = 'default') {
   $output = '';
+  $type = $item['type'];
   switch ($style) {
     case 'full':
-      $output .= '<div class="'. _amazon_item_classes($item) .' amazon-item-full">';
-      $output .= theme('image', $item['imagesets']['mediumimage']['url'], t('Cover image'), check_markup($item['title']), NULL, FALSE);
-      $output .= '<h3>'. l(check_plain($item['title']), $item['detailpageurl'], array('attributes' => array('rel' => 'nofollow'))) .'</h3>';
+      $output .= '<div class="' . _amazon_item_classes($type) . ' amazon-item-full">';
+      $output .= theme('image', array('path' => $item['imagesets']['mediumimage']['url'], 'alt' => t('Cover image'), 'title' => check_markup($item['title']), 'attributes' => array(), 'getsize' => FALSE));
+      $output .= '<h3>' . l(check_plain($item['title']), $item['detailpageurl'], array('attributes' => array('rel' => 'nofollow'))) . '</h3>';
       $output .= '</div>';
       break;
     case 'thumbnail':
-      $output .= '<div class="'. _amazon_item_classes($item) .' amazon-item-thumbnail">';
-      $output .= theme('image', $item['imagesets']['mediumimage']['url'], t('Cover image'), check_markup($item['title']), NULL, FALSE);
+      $output .= '<div class="' . _amazon_item_classes($type) . ' amazon-item-thumbnail">';
+      $output .= theme('image', array('path' => $item['imagesets']['mediumimage']['url'], 'alt' => t('Cover image'), 'title' => check_markup($item['title']), 'attributes' => array(), 'getsize' => FALSE));
       $output .= '</div>';
       break;
     default:
-      $output .= '<div class="'. _amazon_item_classes($item) .'">';
-      $output .= theme('image', $item['imagesets']['smallimage']['url'], t('Cover image'), check_markup($item['title']), NULL, FALSE);
+      $output .= '<div class="' . _amazon_item_classes($type) . '">';
+      $output .= theme('image', array('path' => $item['imagesets']['smallimage']['url'], 'alt' => t('Cover image'), 'title' => check_markup($item['title']), 'attributes' => array(), 'getsize' => FALSE));
       $date = split('-', $item['theatricalreleasedate']);
-      $output .= '<h3>'. l(check_markup($item['title']), $item['detailpageurl'], array('attributes' => array('rel' => 'nofollow'))) .' ('. check_plain($date[0]) .')</h3>';
-      $output .= '<div><strong>'. t('Director') .':</strong> '. implode(', ', $item['director']) .'</div>';
-      $output .= '<div><strong>'. t('Rating') .':</strong> '. $item['audiencerating'] .'</div>';
-      $output .= '<div><strong>'. t('Running time') .':</strong> '. $item['runningtime'] .' '. t('minutes') .'</div>';
+      $output .= '<h3>' . l(check_markup($item['title']), $item['detailpageurl'], array('attributes' => array('rel' => 'nofollow'))) . ' (' . check_plain($date[0]) . ')</h3>';
+      $output .= '<div><strong>' . t('Director') . ':</strong> ' . implode(', ', $item['director']) . '</div>';
+      $output .= '<div><strong>' . t('Rating') . ':</strong> ' . $item['audiencerating'] . '</div>';
+      $output .= '<div><strong>' . t('Running time') . ':</strong> ' . $item['runningtime'] . ' ' . t('minutes') . '</div>';
       $output .= '</div>';
       break;
   }
   return $output;
 }
 
+/**
+ * Theme with inline item dvd.
+ * @param $item
+ * @return
+ *   rendered output.
+ */
 function theme_amazon_inline_item_dvd($item) {
+  $type = $item['type'];
   $date = split('-', $item['theatricalreleasedate']);
-  $output = '<span class="'. _amazon_item_classes($item) .' amazon-item-inline">';
+  $output = '<span class="' . _amazon_item_classes($type) . ' amazon-item-inline">';
   $output .= l($item['title'] . ' (' . $date[0] . ')', $item['detailpageurl'], array('attributes' => array('rel' => 'nofollow')));
   $output .= '</span>';
   return $output;
@@ -38,7 +56,7 @@ function theme_amazon_inline_item_dvd($item) {
 
 
 function theme_amazon_inline_item_software($item) {
-  $output = '<span class="'. _amazon_item_classes($item) .' amazon-item-inline">';
+  $output = '<span class="' . _amazon_item_classes($item) . ' amazon-item-inline">';
   $output .= l($item['title'] . ' (' . $item['operatingsystem'] . ')', $item['detailpageurl'], array('attributes' => array('rel' => 'nofollow')));
   $output .= '</span>';
   return $output;
@@ -46,7 +64,7 @@ function theme_amazon_inline_item_software($item) {
 
 
 function theme_amazon_inline_item_video_games($item) {
-  $output = '<span class="'. _amazon_item_classes($item) .' amazon-item-inline">';
+  $output = '<span class="' . _amazon_item_classes($item) . ' amazon-item-inline">';
   $output .= l($item['title'] . ' (' . $item['hardwareplatform'] . ')', $item['detailpageurl'], array('attributes' => array('rel' => 'nofollow')));
   $output .= '</span>';
   return $output;
diff --git amazon_search/amazon_search.info amazon_search/amazon_search.info
index 6eaec9c..1791700 100644
--- amazon_search/amazon_search.info
+++ amazon_search/amazon_search.info
@@ -3,5 +3,7 @@ description = Provides an API for searching Amazon product information, and inte
 package = Amazon
 dependencies[] = amazon
 dependencies[] = search
-core = 6.x
+core = 7.x
 php = 5.2
+
+files[] = amazon_search.module
diff --git amazon_search/amazon_search.module amazon_search/amazon_search.module
index 877c531..4b90698 100644
--- amazon_search/amazon_search.module
+++ amazon_search/amazon_search.module
@@ -1,38 +1,66 @@
 <?php
 // $Id$
 
+/**
+ * @file
+ * Sets up hook_search for Amazon items.
+ *
+ */
+
+/**
+ * Implements hook_permission.
+ * @return unknown_type
+ */
+function amazon_search_permission() {
+  return array(
+    'access amazon search' =>  array(
+      'title' => t('Access Amazon Search'),
+      'description' => t('Perform searches on Amazon.'),
+  ),
+  );
+}
 
-function amazon_search_perm() {
-  return array('access amazon search');
+/**
+ * Implements hook_search_access().
+ */
+function amazon_search_search_access() {
+  return user_access('access amazon search');
 }
 
+function amazon_search_search_info() {
+  return array(
+    'title' => 'Amazon',
+    'path' => 'amazon_search',
+  );
+}
 /**
- * Implementation of hook_search(). Implements remote Amazon searching.
+ * Implements hook_search(). Implements remote Amazon searching.
  */
-function amazon_search_search($op = 'search', $keys = NULL, $skip_access_check = FALSE) {
-  switch ($op) {
-    case 'name':
-      if ($skip_access_check || user_access('access amazon search')) {
-        return t('Amazon.com');
-      }
-    case 'search':
-      if (user_access('access amazon search')) {
-        $products = array();
-        $items = amazon_search_simple_search($keys);
-        foreach ($items as $item) {
-          $products[] = array(
-            'title' => check_plain($item['title']),
+function amazon_search_search_execute($keys = NULL) {
+  $products = array();
+  $items = amazon_search_simple_search($keys);
+  foreach ($items as $item) {
+    $products[] = array(
+            'title' => filter_xss($item['title']),
             'link' => check_url($item['detailpageurl']),
             'type' => check_plain($item['productgroup']),
             'user' => isset($item['participants']) ? implode(', ', $item['participants']) : '',
-            'snippet' => isset($item['editorialreviews']) ? check_markup($item['editorialreviews'][0]['content']) : '',
-          );
-        }
-        return $products;
-      }
+            'snippet' => isset($item['editorialreviews']) ? filter_xss($item['editorialreviews'][0]['content']) : '',
+    );
   }
+  return $products;
 }
 
+/**
+ * Perform the search.
+ *
+ * @param $keywords
+ *   Keywords to be provided to Amazon.
+ * @param $parameters
+ *   Optional extra parameters to be passed to the Amazon API.
+ * @return
+ *   Array of Amazon items.
+ */
 function amazon_search_simple_search($keywords = '', $parameters = array()) {
   $parameters += array(
     'ResponseGroup' => 'ItemAttributes,EditorialReview',
@@ -43,9 +71,9 @@ function amazon_search_simple_search($keywords = '', $parameters = array()) {
 
   $items = array();
   $results = amazon_http_request('ItemSearch', $parameters);
-  foreach($results->Items->Item as $xml) {
+  foreach ($results->Items->Item as $xml) {
     $item = amazon_item_clean_xml($xml);
     $items[$item['asin']] = $item;
   }
   return $items;
-}
\ No newline at end of file
+}
diff --git asin/asin.d5-migrate.inc asin/asin.d5-migrate.inc
deleted file mode 100644
index 5f0fc51..0000000
--- asin/asin.d5-migrate.inc
+++ /dev/null
@@ -1,78 +0,0 @@
-<?php
-// $Id$
-
-/**
- * Batch Operation Callback
- */
-function _asin_migrate_field_from_d5($fields, &$context) {
-  if (!isset($context['sandbox']['progress'])) {
-    $context['sandbox']['progress'] = 0;
-    $context['sandbox']['current_node'] = 0;
-    
-    $sql = "SELECT COUNT(DISTINCT nid) FROM {amazonnode} WHERE ntype IN ";
-    $sql .= '(' . db_placeholders($fields, 'varchar') . ')';
-    
-    $context['sandbox']['max'] = db_result(db_query($sql, array_keys($fields)));
-  }
-  
-  $sql = "SELECT DISTINCT(nid) FROM {amazonnode} WHERE ntype IN (" . db_placeholders($fields, 'varchar') . ") ORDER BY nid ASC";
-  $params[] = $context['sandbox']['current_node'];
-  $nid_results = db_query_range($sql, array_keys($fields), 0, 20);
-  $nids = array();
-  while ($nid = db_fetch_object($nid_results)) {
-    $nids[] = $nid->nid;
-  }
-
-  foreach ($nids as $nid) {
-    if ($node = _asin_migrate_from_d5($nid, $fields)) {
-      $context['results'][$node->nid] = $node->title;
-  
-      $context['sandbox']['progress']++;
-      $context['sandbox']['current_node'] = $node->nid;
-      $context['message'] = t('Now processing %node', array('%node' => $node->title));
-    }
-  }
-  // Inform the batch engine that we are not finished,
-  // and provide an estimation of the completion level we reached.
-  if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
-    $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
-  }
-}
-
-/**
- * Batch 'finished' callback
- */
-function _asin_migrate_fields_finished($success, $results, $operations) {
-  if ($success) {
-    // Here we do something meaningful with the results.
-    $message = count($results) .' nodes migrated to new ASIN field structure.';
-    $message .= theme('item_list', $results);
-  }
-  else {
-    // An error occurred.
-    // $operations contains the operations that remained unprocessed.
-    $error_operation = reset($operations);
-    $message = 'An error occurred while processing '. $error_operation[0] .' with arguments :'. print_r($error_operation[0], TRUE);
-  }
-  drupal_set_message($message);
-}
-
-function _asin_migrate_from_d5($nid, $fields) {
-  $results = db_query("SELECT asin, ntype FROM {amazonnode} an WHERE an.nid = %d", $nid);
-  $dirty = FALSE;
-  $node = node_load($nid);
-
-  while ($asin = db_fetch_object($results)) {
-    if (array_key_exists($asin->ntype, $fields)) {
-      $node->{$asin->ntype}[]['asin'] = $asin->asin;
-    }
-  }
-
-  node_save($node);
-  $sql = "DELETE FROM {amazonnode} WHERE nid = %d AND ntype IN (" . db_placeholders($fields, 'varchar') . ")";
-  $params = array_keys($fields);
-  array_unshift($params, $nid);
-  db_query($sql, $params);
-
-  return $node;
-}
\ No newline at end of file
diff --git asin/asin.info asin/asin.info
index 9c016b6..65261a6 100644
--- asin/asin.info
+++ asin/asin.info
@@ -3,5 +3,9 @@ description = Provides a CCK field type for Amazon products.
 package = Amazon
 dependencies[] = amazon
 dependencies[] = content
-core = 6.x
+core = 7.x
 php = 5.2
+
+files[] = asin.d5-migrate.inc
+files[] = asin.install
+files[] = asin.module
diff --git asin/asin.install asin/asin.install
index dd361ce..02c910e 100644
--- asin/asin.install
+++ asin/asin.install
@@ -1,8 +1,14 @@
 <?php
+/**
+ * @file
+ * Install, update and uninstall functions for the asin module.
+ *
+ */
+
 
 // Updates happen in random order, whether or not the module is enabled,
 // so include critical code here just to be sure.
-include_once('./'. drupal_get_path('module', 'content') .'/content.module');
+include_once('./' . drupal_get_path('module', 'content') . '/content.module');
 
 /**
  * Implementation of hook_install().
@@ -36,92 +42,3 @@ function asin_disable() {
   content_notify('disable', 'asin');
 }
 
-
-/**
- * Database schema update from the ugly, borked D5 version.
- */
-function asin_update_6001() {
-  if ($abort = content_check_update('asin')) {
-    return $abort;
-  }
-
-  // The name of the widget type has changed from asin to asin_text.
-  $ret[] = update_sql("UPDATE {" . content_instance_tablename() . "} SET widget_type = 'asin_text' WHERE widget_type = 'asin'");
-  // All CCK fields are disabled by Content module during the D6 upgrade.
-  // Re-enable the 'asin' field.
-  content_associate_fields('asin');
-
-  // Build a list of fields that need data updating.
-  module_load_install('content');
-  module_load_include('inc', 'content', 'includes/content.admin');
-  module_load_include('inc', 'content', 'includes/content.crud');
-
-  $ret = array();
-  $fields = array();
-
-  content_clear_type_cache(TRUE);
-
-  // Grab the list of fields to update.
-  foreach (content_field_instance_read(NULL, TRUE) as $field) {
-    if ($field['type'] == 'asin' && $field['widget']['type'] == 'asin_text') {
-      $fields[] = $field;
-    }
-  }
-
-  content_clear_type_cache(TRUE);
-
-  // Update database storage (add data column, since the D5 version assumed all control).
-  foreach ($fields as $field) {
-    $new_field = $field;
-
-    // Setup the previous definition.
-    $field['columns'] = array();
-    // Setup the new.
-    $new_field['columns']['asin'] = array('type' => 'varchar', 'length' => 32, 'not null' => FALSE);
-    $field['widget']['type'] = 'asin_text';
-
-    content_alter_db($field, $new_field);
-    content_field_instance_update($field);
-
-    $ret[] = array('success' => TRUE, 'query' => 'Updated database schema and widget settings for ' . $field['field_name']);
-  }
-
-  content_clear_type_cache(TRUE);
-
-  return $ret;
-}
-
-/**
- * Migrate old data from the D5 version.
- */
-function asin_update_6002() {
-  module_load_install('content');
-  module_load_include('inc', 'content', 'includes/content.admin');
-  module_load_include('inc', 'content', 'includes/content.crud');
-
-  // Grab the list of fields to update.
-  $fields = array();
-  foreach (content_field_instance_read() as $field) {
-    if ($field['type'] == 'asin') {
-      $fields[$field['field_name']] = $field;
-    }
-  }
-
-
-  if (!empty($fields)) {
-    $batch = array(
-      'title' => t('Migrating ASIN CCK field values'),
-      'operations' => array(
-        array('_asin_migrate_field_from_d5', array($fields)),
-      ),
-      'finished' => '_asin_migrate_fields_finished',
-      'init_message' => t('Beginning ASIN migration.'),
-      'progress_message' => t('Processed @current out of @total.'),
-      'error_message' => t('ASIN CCK field update encountered an error.'),
-      'file' => drupal_get_path('module', 'asin') .'/asin.d5-migrate.inc',
-    );
-    batch_set($batch);
-  }
-
-  return array();
-}
\ No newline at end of file
diff --git asin/asin.module asin/asin.module
index 3230870..61210ca 100644
--- asin/asin.module
+++ asin/asin.module
@@ -64,16 +64,16 @@ function asin_field_settings($op, $field) {
       $table_alias = content_views_tablename($field);
 
       // Filter: Add a 'many to one' filter.
-      $copy = $data[$table_alias][$field['field_name'] .'_asin'];
+      $copy = $data[$table_alias][$field['field_name'] . '_asin'];
       $copy['title'] = t('@label (!name) - Allowed values', array('@label' => $field['widget']['label'], '!name' => $field['field_name']));
       $copy['filter']['handler'] = 'views_handler_filter_many_to_one';
       unset($copy['field'], $copy['argument'], $copy['sort']);
-      $data[$table_alias][$field['field_name'] .'_value_many_to_one'] = $copy;
+      $data[$table_alias][$field['field_name'] . '_value_many_to_one'] = $copy;
       // Argument : swap the handler to the 'many to one' operator.
-      $data[$table_alias][$field['field_name'] .'_value']['argument']['handler'] = 'views_handler_argument_many_to_one';
+      $data[$table_alias][$field['field_name'] . '_value']['argument']['handler'] = 'views_handler_argument_many_to_one';
 
       // Add a relationship for related node.
-      $data[$table_alias][$field['field_name'] .'_asin']['relationship'] = array(
+      $data[$table_alias][$field['field_name'] . '_asin']['relationship'] = array(
         'base' => 'amazon_item',
         'field' => $db_info['columns']['asin']['column'],
         'handler' => 'views_handler_relationship',
@@ -100,7 +100,7 @@ function asin_field($op, &$node, $field, &$items, $teaser, $page) {
       foreach ($items as $delta => $item) {
         if (is_array($item)) {
           if (!empty($item['asin']) && empty($results[$item['asin']])) {
-            form_set_error($field['field_name'] .']['. $delta .'][asin', t('%name : No Amazon product with the ASIN "%id" could be located.', array('%name' => $field['widget']['label'], '%id' => $item['asin'])));
+            form_set_error($field['field_name'] . '][' . $delta . '][asin', t('%name : No Amazon product with the ASIN "%id" could be located.', array('%name' => $field['widget']['label'], '%id' => $item['asin'])));
           }
         }
       }
@@ -201,7 +201,7 @@ function theme_asin_formatter_default($element) {
   $asins = array();
   if (!empty($asin)) {
     $asins = amazon_item_lookup("$asin");
-    return theme('amazon_item', $asins["$asin"]);
+    return theme('amazon_item', array('item' => $asins["$asin"]));
   }
 }
 
@@ -213,7 +213,7 @@ function theme_asin_formatter_thumbnail($element) {
   $asin = trim($element['#item']['asin']);
   if (!empty($asin)) {
     $asins = amazon_item_lookup("$asin");
-    return theme('amazon_item', $asins["$asin"], 'thumbnail');
+    return theme('amazon_item', array('item' => $asins["$asin"], 'style' => 'thumbnail'));
   }
 }
 
@@ -225,7 +225,7 @@ function theme_asin_formatter_details($element) {
   $asin = trim($element['#item']['asin']);
   if (!empty($asin)) {
     $asins = amazon_item_lookup(array($asin));
-    return theme('amazon_item', $asins["$asin"], 'details');
+    return theme('amazon_item', array('item' => $asins["$asin"], 'style' => 'details'));
   }
 }
 
@@ -236,11 +236,12 @@ function theme_asin_formatter_details($element) {
 function theme_asin_formatter_inline($element) {
   if ($asin = trim($element['#item']['asin'])) {
     $asins = amazon_item_lookup("$asin");
-    if (empty($asins[$asin])) { // DEBUG
+    if (empty($asins[$asin])) {
+ // DEBUG
       drupal_set_message("<pre>\$asins[$asin]=" . print_r($asins["$asin"], TRUE) .  "</pre>");
-      drupal_set_message("asin='$asin'; asins=".print_r($asins,TRUE));
+      drupal_set_message("asin='$asin'; asins=" . print_r($asins, TRUE));
     }
-    return theme('amazon_inline_item', $asins[$asin]);
+    return theme('amazon_inline_item', array('item' => $asins[$asin]));
   }
 }
 
@@ -369,12 +370,12 @@ function asin_text_validate($element, &$form_state) {
 
 
 function theme_asin_text($element) {
-  drupal_add_css(drupal_get_path('module', 'asin') .'/asin.css', 'module', 'all', FALSE);
+  drupal_add_css(drupal_get_path('module', 'asin') . '/asin.css', array('preprocess' => FALSE));
   $output = $element['#children'];
   if (!empty($element['#value']) && !empty($element['#value']['asin'])) {
     $asin = $element['#value']['asin'];
     if ($data = amazon_item_lookup(array($asin))) {
-      $output .= '<p class="asin-edit-title">'. check_plain($data[$asin]['title']) .'</p>';
+      $output .= '<p class="asin-edit-title">' . check_plain($data[$asin]['title']) . '</p>';
     }
   }
   return $output;
diff --git includes/amazon.views.inc includes/amazon.views.inc
index 474aec8..26ee056 100644
--- includes/amazon.views.inc
+++ includes/amazon.views.inc
@@ -138,8 +138,8 @@ function amazon_views_data() {
   _amazon_make_simple_text_field($data, 'amazon_item', 'amazonpriceformattedprice', 'Amazon price (formatted)', "Amazon's current price for the item.");
   _amazon_make_simple_boolean_field($data, 'amazon_item', 'invalid_asin', 'Invalid ASIN', 'If nonzero, the ASIN is invalid or discontinued by Amazon');
   unset($data['amazon_item']['listpriceformattedprice']['argument']);
-    unset($data['amazon_item']['lowestformattedprice']['argument']);
-    unset($data['amazon_item']['amazonpriceformattedprice']['argument']);
+  unset($data['amazon_item']['lowestformattedprice']['argument']);
+  unset($data['amazon_item']['amazonpriceformattedprice']['argument']);
 
   // Define the base group of this table. Fields that don't
   // have a group defined will go into this field by default.
diff --git includes/views_handler_field_amazon_date.inc includes/views_handler_field_amazon_date.inc
index ef8fdaa..0bd3e0e 100644
--- includes/views_handler_field_amazon_date.inc
+++ includes/views_handler_field_amazon_date.inc
@@ -10,7 +10,7 @@ class views_handler_field_amazon_date extends views_handler_field_date {
   function options_form(&$form, &$form_state) {
     parent::options_form($form, $form_state);
 
-    $time = time();
+    $time = REQUEST_TIME;
     $form['date_format']['#options'] = array(
       'default' => format_date($time, 'custom', 'Y-m-d'),
       'custom' => t('Custom'),
@@ -29,7 +29,7 @@ class views_handler_field_amazon_date extends views_handler_field_date {
       return theme('views_nodate');
     }
     else {
-      $time_diff = time() - $value; // will be positive for a datetime in the past (ago), and negative for a datetime in the future (hence)
+      $time_diff = REQUEST_TIME - $value; // will be positive for a datetime in the past (ago), and negative for a datetime in the future (hence)
       switch ($format) {
         case 'custom':
           return format_date($value, $format, $custom_format);
diff --git includes/views_handler_field_amazon_image.inc includes/views_handler_field_amazon_image.inc
index 9f2485b..24872b4 100644
--- includes/views_handler_field_amazon_image.inc
+++ includes/views_handler_field_amazon_image.inc
@@ -103,22 +103,24 @@ class views_handler_field_amazon_image extends views_handler_field {
 
     // Choose presentation style
     if ($this->options['presentation_format'] == 'markup') {
-      $image = theme('image', $values->{$this->table_alias . '_url'}, NULL, NULL, $attributes, FALSE);
-    } else {
+      $image = theme('image', array('path' => $values->{$this->table_alias . '_url'}, 'alt' => NULL, 'title' => NULL, 'attributes' => $attributes, 'getsize' => FALSE));
+    }
+    else {
       $image = $values->{$this->table_alias . '_url'};
     }
-    switch($this->options['link_format']) {
+    switch ($this->options['link_format']) {
       case 'plain':
         return $image;
         break;
       case 'node':
-        return l($image, 'node/'. $values->nid, array('html' => TRUE));
+        return l($image, 'node/' . $values->nid, array('html' => TRUE));
         break;
       case 'amazon':
         if (!empty($values->{$this->aliases['detailpageurl']})) {
           $urlfield = $values->{$this->aliases['detailpageurl']};
           return l($image, $urlfield, array('html' => TRUE));
-        } else {
+        }
+        else {
           return $image;
         }
         break;
diff --git includes/views_handler_field_amazon_title.inc includes/views_handler_field_amazon_title.inc
index 582244b..12e67a0 100644
--- includes/views_handler_field_amazon_title.inc
+++ includes/views_handler_field_amazon_title.inc
@@ -38,12 +38,12 @@ class views_handler_field_amazon_title extends views_handler_field {
 
   function render($values) {
     $title = check_plain($values->{$this->field_alias});
-    switch($this->options['link_format']) {
+    switch ($this->options['link_format']) {
       case 'plain':
         return $title;
         break;
       case 'node':
-        return l($title, 'node/'. $values->nid, array('html' => TRUE));
+        return l($title, 'node/' . $values->nid, array('html' => TRUE));
         break;
       case 'amazon':
         return l($title, check_url($values->{$this->table_alias . '_detailpageurl'}), array('html' => TRUE));
diff --git includes/views_handler_filter_amazon_node_module.inc includes/views_handler_filter_amazon_node_module.inc
index 6f0efd3..a77022a 100644
--- includes/views_handler_filter_amazon_node_module.inc
+++ includes/views_handler_filter_amazon_node_module.inc
@@ -24,52 +24,3 @@ class views_handler_filter_amazon_node_module extends views_handler_filter_in_op
   }
 }
 
-class views_handler_field_amazon_title extends views_handler_field {
-  function options(&$options) {
-    parent::options($options);
-    $options['link_format'] = 'amazon';
-  }
-
-  /**
-   * Override init function to provide generic option to link to node.
-   */
-  function init(&$view, &$data) {
-    parent::init($view, $data);
-    if (!empty($data['link_format']) && $data['link_format'] == 'amazon') {
-      $this->additional_fields[] = 'detailpageurl';
-    }
-  }
-
-  /**
-   * Provide link to node option
-   */
-  function options_form(&$form, &$form_state) {
-    $form['link_format'] = array(
-      '#title' => t('Link behavior'),
-      '#type' => 'radios',
-      '#options' => array(
-        'plain' => t('No link'),
-        'amazon' => t("A link to the product's Amazon page"),
-      ),
-      '#default_value' => !empty($this->options['link_format']) ? $this->options['link_format'] : 'plain',
-    );
-    if ($this->view->base_table == 'node') {
-      $form['link_format']['#options']['node'] = t('A link to the node the product is associated with');
-    }
-  }
-
-  function render($values) {
-    $title = check_plain($values->{$this->field_alias});
-    switch($this->options['link_format']) {
-      case 'plain':
-        return $title;
-        break;
-      case 'node':
-        return l($title, 'node/'. $values->nid, array('html' => TRUE));
-        break;
-      case 'amazon':
-        return l($title, check_url($values->{$this->table_alias . '_detailpageurl'}), array('html' => TRUE, 'attributes' => array('rel' => 'nofollow')));
-        break;
-    }
-  }
-}
diff --git includes/views_handler_filter_string_compare.inc includes/views_handler_filter_string_compare.inc
index 0fb7818..ba4a551 100644
--- includes/views_handler_filter_string_compare.inc
+++ includes/views_handler_filter_string_compare.inc
@@ -241,7 +241,7 @@ class views_handler_filter_string_compare extends views_handler_filter {
     foreach ($matches as $match) {
       $phrase = false;
       // Strip off phrase quotes
-      if ($match[2]{0} == '"') {
+      if ($match[2][0] == '"') {
         $match[2] = substr($match[2], 1, -1);
         $phrase = true;
       }
