diff --git a/includes/registration.entity.inc b/includes/registration.entity.inc
index 083e7ac..d450d42 100644
--- a/includes/registration.entity.inc
+++ b/includes/registration.entity.inc
@@ -9,7 +9,7 @@
  * Implements hook_entity_info().
  */
 function registration_entity_info() {
-  return array(
+  $entities =  array(
     'registration' => array(
       'module' => 'registration',
       'label' => t('Registration'),
@@ -24,15 +24,7 @@ function registration_entity_info() {
       'bundle keys' => array(
         'bundle' => 'type',
       ),
-      'bundles' => array(
-        'registration' => array(
-          'label' => 'Registration',
-          'admin' => array(
-            'path' => 'admin/structure/registration/manage',
-            'access arguments' => array('administer registration'),
-          ),
-        ),
-      ),
+      'bundles' => array(),
       'view modes' => array(
         'full' => array(
           'label' => t('Full Registration'),
@@ -43,6 +35,18 @@ function registration_entity_info() {
       'token type' => 'registration',
     ),
   );
+
+  foreach (registration_entity_types() as $type => $info) {
+    $entities['registration']['bundles'][$type] = array(
+      'label' => $info->name,
+      'admin' => array(
+        'path' => 'admin/structure/registration/types/' . $info->type . '/manage',
+        'access arguments' => array('administer registration'),
+      ),
+    );
+  }
+
+  return $entities;
 }
 
 function registration_uri($registration) {
@@ -104,6 +108,41 @@ function registration_entity_property_info_alter(&$info) {
 }
 
 /**
+ * Returns all the bundles for the registration entity.
+ */
+function registration_entity_types() {
+  $types = &drupal_static(__FUNCTION__);
+  if (empty($types)) {
+    // types array is empty, so lets load it
+    $types = array();
+    
+    $tq = db_select('registration_type', 'rt')->fields('rt')->execute();
+    foreach ($tq as $row) {
+      $types[$row->type] = $row;
+    }
+  }
+  return $types;
+}
+
+/**
+ * Resets the cached list of registration types.
+ */
+function registration_entity_types_reset() {
+  $registration_types = &drupal_static('registration_entity_types');
+  $registration_types = NULL;
+}
+
+/**
+ * Loads a registration type.
+ */
+function registration_type_load($type) {
+  $types = registration_entity_types();
+  //@todo This str_replace() seems odd, is it required and why? 
+  $type = str_replace('-', '_', $type);
+  return isset($types[$type]) ? $types[$type] : FALSE;
+}
+
+/**
  * Loads a registration by ID.
  */
 function registration_load($registration_id) {
diff --git a/registration.install b/registration.install
index d9a8e47..ad6be52 100644
--- a/registration.install
+++ b/registration.install
@@ -25,7 +25,19 @@ function registration_schema() {
         'not null' => TRUE,
         'default' => '',
       ),
-      'nid' => array(
+      'entity_type' => array(
+        'description' => 'The entity type that this registration is tied to.',
+        'type' => 'varchar',
+        'length' => 100,
+        'not null' => TRUE,
+      ),
+      'entity_bundle' => array(
+        'description' => 'The entity bundle that this registration is tied to.',
+        'type' => 'varchar',
+       'length' => 100,
+        'not null' => TRUE,
+      ),
+      'eid' => array(
         'description' => 'The id of the entity this registration is associated with.',
         'type' => 'int',
         'not null' => TRUE,
@@ -62,6 +74,12 @@ function registration_schema() {
         'not null' => TRUE,
         'default' => 0,
       ),
+      'status' => array(
+        'description' => 'The status of this registration.',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
     ),
     'indexes' => array(
       'registration_updated' => array('updated'),
@@ -79,7 +97,7 @@ function registration_schema() {
       ),
     ),
     'unique keys' => array(
-      'nid_mail' => array('nid', 'mail'), 
+      'eid_mail' => array('eid', 'mail'), 
     ), 
     'primary key' => array('registration_id'),
   );
@@ -140,6 +158,75 @@ function registration_schema() {
     'primary key' => array('nid'),
   );
 
+  $schema['registration_type'] = array(
+    'description' => 'Registration entity types.',
+    'fields' => array(
+      'type' => array(
+        'description' => 'Bundle (machine name) of the registration entity.',
+        'type' => 'varchar',
+        'length' => '50',
+        'not null' => TRUE,
+      ),
+      'name' => array(
+        'description' => 'Human readable name of the registration entity.',
+        'type' => 'varchar',
+        'length' => '100',
+        'not null' => TRUE,
+      ),
+      'description' => array(
+        'description' => 'Description of the registration entity.',
+        'type' => 'text',
+      ),
+      'created' => array(
+        'description' => 'Unix timestamp of creation date.',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'changed' => array(
+        'description' => 'Unix timestamp of changed date.',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'primary key' => array('type'),
+  );
+
+  $schema['registration_attach'] = array(
+    'description' => 'Mapping registration bundles to other entity bundles or entitys themselves',
+    'fields' => array(
+      'type' => array(
+        'description' => 'Bundle (machine name) of the registration entity.',
+        'type' => 'varchar',
+        'length' => '50',
+        'not null' => TRUE,
+      ),
+      'entity_type' => array(
+        'description' => 'The entity type we are attaching to.',
+        'type' => 'varchar',
+        'length' => '50',
+        'not null' => TRUE,
+      ),
+      'entity_bundle' => array(
+        'description' => 'The specific bundle we are attaching to.',
+        'type' => 'varchar',
+        'length' => '50',
+        'not null' => TRUE,
+      ),
+      'entity_id' => array(
+        'description' => 'The entity id our registration bundle is attached to',
+        'type' => 'int',
+      ),
+    ),
+  );
+
   return $schema;
 }
 
+/**
+ * @todo Update to add new table definitions if they don't exist.
+ * @todo Update to alter existing tables.
+ * Implementation of hook_update_N().
+ */
+
diff --git a/registration.module b/registration.module
index 75d2aa4..d127a71 100644
--- a/registration.module
+++ b/registration.module
@@ -11,18 +11,69 @@ module_load_include('inc', 'registration', 'includes/registration.entity');
  * Implements hook_menu().
  */
 function registration_menu() {
-  $items['admin/structure/registration/manage'] = array(
+  $items['admin/structure/registration'] = array(
     'title' => 'Registration',
-    'description' => 'Manage Registration structure',
+    'description' => 'Manage Registration settings and types',
     'page callback' => 'registration_admin_page',
     'access arguments' => array('administer registration'),
-    
   );
-  $items['admin/structure/registration/manage/settings'] = array(
+  //@todo review this menu item
+  $items['admin/structure/registration/status/%/%'] = array(
+    'title' => 'Enable Registrations',
+    'title callback' => 'registration_admin_form_title',
+    'title arguments' => array(4, 'Status', 5),
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('registration_status_form', 4, 5),
+    'access arguments' => array('administer registration'),
+  );
+//@todo review these too.
+  $items['admin/structure/registration/settings'] = array(
     'title' => 'Settings',
-    'description' => 'Manage Registration settings',
+    'description' => 'Manage Registration settings and types',
+    'access arguments' => array('administer registration'),
+    'page callback' => 'registration_admin_page',
     'type' => MENU_DEFAULT_LOCAL_TASK,
   );
+  $items['admin/structure/registration/types'] = array(
+    'title' => 'Types',
+    'description' => 'Manage Registration Types',
+    'type' => MENU_LOCAL_TASK,
+    'page callback' => 'registration_types_page',
+    'access arguments' => array('administer registration'),
+  );
+  $items['admin/structure/registration/types/add'] = array(
+    'title' => 'Add a Registration Type',
+    'type' => MENU_LOCAL_ACTION,
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('registration_type_form'),
+    'access arguments' => array('administer registration'),
+  );
+  $items['admin/structure/registration/types/%/edit'] = array(
+    'title' => 'edit',
+    'title callback' => 'registration_admin_form_title',
+    'title arguments' => array(4, 'Edit'),
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('registration_type_form', 4),
+    'access arguments' => array('administer registration'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['admin/structure/registration/types/%/delete'] = array(
+    'title' => 'delete',
+    'title callback' => 'registration_admin_form_title',
+    'title arguments' => array(4, 'Delete'),
+    'page callback' => 'registration_delete_type',
+    'page arguments' => array(4),
+    'access arguments' => array('administer registration'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['register/%/%/%'] = array(
+    'title callback' => 'registration_register_entity_title',
+    'title arguments' => array(1, 2, 3),
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('registration_register_entity_form', 1, 2, 3),
+    'access arguments' => array('add registration'),
+  );
+//@todo end
 
   $items['registration/%registration'] = array(
     'title callback' => 'registration_page_title',
@@ -109,19 +160,216 @@ function registration_menu() {
  * Implements hook_permission().
  */
 function registration_permission() {
-  return array(
+  $permissions = array(
     'administer registration' => array(
       'title' => t('Administer registration'),
       'description' => t('Perform administration tasks for Registrations.'),
       'restrict access' => TRUE,
     ),
-    'view registration' => array(
-      'title' => t('View registrations'),
+    'view any registration' => array(
+      'title' => t('View any registrations'),
     ),
-    'add registration' => array(
-      'title' => t('Add registrations'),
+    'add any registration' => array(
+      'title' => t('Add any registrations'),
     ),
   );
+ 
+//@todo review permissions.
+  foreach (registration_entity_types() as $type => $info) {
+    $permissions['create ' . $type . ' registration'] = array(
+      'title' => t('Create <em> ') . $info->name . t('</em> registrations'),
+    );
+    $permissions['edit ' . $type . ' registration'] = array(
+      'title' => t('Edit <em> ') . $info->name . t('</em> registrations'),
+    );
+    $permissions['delete ' . $type . ' registration'] = array(
+      'title' => t('Delete <em> ') . $info->name . t('</em> registrations'),
+    );
+    $permissions['view ' . $type . ' registration'] = array(
+      'title' => t('View <em> ') . $info->name . t('</em> registrations'),
+    );
+  }
+
+  return $permissions;
+}
+
+/**
+ * Implements hook_entity_view_alter().
+ */
+//@todo replace this with a better way of attaching the registration form to an appropriate target.
+function registration_entity_view_alter(&$build, $type) {
+  $types_to_alter = array();
+//@todo we don't want to use the variable system.
+  $types_to_alter_query = db_select('variable', 'v')->fields('v')->condition('name', 'registration_bundle:%', 'LIKE')->execute();
+  foreach ($types_to_alter_query as $row) {
+    $mtype = $row->name;
+    $mtype = substr($mtype, 20);
+    $types_to_alter[] = $mtype;
+  }
+  if (in_array($type . ':_' . $build['#bundle'], $types_to_alter)) {
+    // the type is in the types of entities to alter for registrations
+    $build['registration_register_form'] = drupal_get_form('registration_register_form', $type, $build['#bundle'], $build['#node']->nid);
+  }
+}
+
+/**
+ * Register button form callback.
+ *
+ * Shows a Register button for a registration enabled entity.
+ *
+ * If the user is already registered for this item, we instead show text to the
+ * user that they are already registered.
+ * @todo review these forms and make them extensible. Also move the code.
+ */
+function registration_register_form($form, &$form_state, $type, $bundle, $eid) {
+  global $user;
+  $form = array();
+  if ($user->uid != 0 && registration_check_email_registered($user->mail, $type, $bundle, $eid)) {
+    return array(
+      'already' => array(
+        '#type' => 'markup',
+        '#markup' => '<small>* ' . t('You are already registered for this item.') . ' *</small>',
+      ),
+    );
+  }
+  $form['eid'] = array(
+    '#type' => 'hidden',
+    '#value' => $eid,
+  );
+  $form['etype'] = array(
+    '#type' => 'hidden',
+    '#value' => $type,
+  );
+  $form['bundle'] = array(
+    '#type' => 'hidden',
+    '#value' => $bundle,
+  );
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => 'Register',
+  );
+  return $form;
+}
+
+/**
+ * Register button form submit.
+ *
+ * Loads up the complete registration form for the entity.
+ */
+function registration_register_form_submit($form, &$form_state) {
+  //@todo review. 
+  drupal_goto('register/' . $form_state['values']['etype'] . '/' . $form_state['values']['bundle'] . '/' . $form_state['values']['eid']);
+}
+
+function registration_check_email_registered($email, $entity_type, $entity_bundle, $entity_id) {
+  //@todo what?
+  return FALSE;
+}
+
+/**
+ * Registration form page title callback.
+ */
+function registration_register_entity_title($type, $bundle, $entityid) {
+  $entity = entity_load($type, array($entityid));
+  return t('Register for ') . $entity[$entityid]->title;
+}
+
+/**
+ * Form builder for registering for an entity. Adds bundle's fields to the form.
+ * @todo review this
+ */
+function registration_register_entity_form($form, &$form_state, $type, $bundle, $entityid) {
+  $entity = variable_get('registration_bundle:' . $type . ':_' . $bundle, FALSE);
+  $status = (int) variable_get('registration_status:' . $type . ':_' . $bundle, 0);
+  $form = array();
+  $form['entity_type'] = array(
+    '#type' => 'hidden',
+    '#value' => $type,
+  );
+  $form['entity_bundle'] = array(
+    '#type' => 'hidden',
+    '#value' => $bundle,
+  );
+  $form['entity_id'] = array(
+    '#type' => 'hidden',
+    '#value' => $entityid,
+  );
+  if ($status == 0) {
+    $form += array(
+      'invalid' => array(
+        '#type' => 'markup',
+        '#markup' => t('This item is not accepting registrations at this time.'),
+      ),
+      'actions' => array(
+        '#type' => 'actions',
+        'goback' => array(
+          '#type' => 'button',
+          '#value' => t('Go Back'),
+        ),
+      ),
+    );
+    return $form;
+  }
+  if (is_string($entity)) {
+    $etype = $entity;
+    $entity = entity_create('registration', array('type' => $etype));
+    $entity->entity_type = $type;
+    $entity->entity_bundle = $bundle;
+    $entity->eid = $entityid;
+    $form['registration'] = array(
+      '#type' => 'fieldset',
+      '#title' => 'Registration Information',
+    );
+    $form['registration']['entity'] = array(
+      '#type' => 'value',
+      '#value' => $entity,
+    );
+    $form['actions'] = array(
+      '#type' => 'actions',
+      'cancel' => array(
+       '#type' => 'button',
+       '#value' => t('Cancel'),
+      ),
+      'submit' => array(
+        '#type' => 'submit',
+        '#value' => t('Submit'),
+      ),
+    );
+    field_attach_form('registration', $entity, $form['registration'], $form_state);
+    return $form;
+  }
+}
+
+/**
+ * Registration form validation callback.
+ */
+function registration_register_entity_form_validate($form, &$form_state) {
+  $entityid = $form_state['values']['entity_id'];
+  $entitytype = $form_state['values']['entity_type'];
+  $entitybundle = $form_state['values']['entity_bundle'];
+  $registration = $form_state['values']['entity'];
+  field_attach_form_validate('registration', $registration, $form, $form_state);
+  return TRUE;
+}
+
+/**
+ * Registration form submit callback.
+ */
+function registration_register_entity_form_submit($form, &$form_state) {
+  global $user;
+  $entityid = $form_state['values']['entity_id'];
+  $entitytype = $form_state['values']['entity_type'];
+  $entitybundle = $form_state['values']['entity_bundle'];
+  $registration = $form_state['values']['entity'];
+  $registration->created = REQUEST_TIME;
+  $registration->updated = REQUEST_TIME;
+  $registration->user_uid = $user->uid;
+  $registration->author_uid = $user->uid;
+  $registration->status = 1;
+  entity_save('registration', $registration);
+  field_attach_submit('registration', $registration, $form['registration'], $form_state);
+  drupal_set_message(t('Your registration has been received.'));
+  drupal_goto($entitytype . '/' . $entityid);
 }
 
 /**
@@ -129,27 +377,43 @@ function registration_permission() {
  */
 function registration_admin_page() {
   $rows = array();
-  foreach (node_type_get_names() as $type => $name) {
-    $rows[] = array(
-      l($name, 'admin/structure/types/manage/' . $type),
-      (variable_get('registration_node_status_' . $type, 0)) ? t('Enabled') :
-      t('Disabled'),
-    );
+  $entities = entity_get_info();
+  // @todo review
+  foreach ($entities as $type => $data) {
+    if (!empty($data['bundles']) && $type != 'registration') {
+      $rows[] = array(
+        array(
+          'data' => '<b>' . $data['label'] . '</b>',
+          'colspan' => 2,
+        ),
+      );
+      foreach ($data['bundles'] as $bundle => $bundle_data) {
+        $link = $bundle_data['label'];
+        $status = variable_get('registration_status:' . $type . ':_' . $bundle, 0);
+        $usingtype = variable_get('registration_bundle:' . $type . ':_' . $bundle, '');
+        $status = ($status ? 'Enabled' : 'Disabled');
+        $status = l($status, 'admin/structure/registration/status/' . $type . '/' . $bundle) . ($status == 'Enabled' ? ' <small>(' . $usingtype . ')</small>' : '');
+        if (!empty($bundle_data['admin'])) {
+          if (!empty($bundle_data['admin']['real path'])) {
+            $link = l($bundle_data['label'], $bundle_data['admin']['real path']);
+          }
+          else {
+            $link = l($bundle_data['label'], $bundle_data['admin']['path']);
+          }
+        }
+        $rows[] = array($link, $status);
+      }
+    }
   }
 
-  $table = array(
-    'header' => array(t('Content type'), t('Registration status')),
-    'rows' => $rows,
+  // @todo render array?
+  // $out = theme('table', $table);
+  
+  return array(
+    '#theme' => 'table',
+    '#header' => array(t('Entity type'), t('Registration status')), 
+    '#rows' => $rows,
   );
-  $out = theme('table', $table);
-
-  return t('The following table lists the registration status for each content 
-    type. You can enable/disable registrations from the content type settings 
-    page. You can also !manage_fields and their !display_settings.', 
-    array(
-      '!manage_fields' => l('manage registration fields', 'admin/structure/registration/manage/fields'),
-      '!display_settings' => l('display settings', 'admin/structure/registration/manage/display'),
-    )) . $out;
 }
 
 /**
@@ -163,10 +427,10 @@ function registration_page_view($registration, $view_mode = 'full') {
  * Page title callback.
  */
 function registration_page_title($registration) {
-  // use the node title in the registration page title
-  if ($node = node_load($registration->nid)) {
-    return t('Registration for @title', array('@title' => $node->title));
-  }
+  // use the wode title in the registration page title
+  $entity = entity_load($registration->entity_type, array($registration->eid));
+  $entity = $entity[$registration->eid];
+  return t('Registration #@num for @entity', array('@num' => $registration->registration_id, '@entity' => $entity->title));
 }
 
 /**
@@ -184,21 +448,30 @@ function registration_form_node_type_form_alter(&$form, &$form_state) {
     '#collapsed' => FALSE,
   );
 
-  $form['registration']['registration_node_status'] = array(
+  //@todo rip out variable usage for storage
+  $form['registration']['registration_status:node:'] = array(
     '#type' => 'checkbox',
     '#title' => t('Enable registrations for this content type'),
-    '#default_value' => variable_get('registration_node_status_' . $type, 0),
+    '#default_value' => variable_get('registration_status:node:_' . $type, 0),
     '#description' => t('If enabled, users will be allowed to register for this 
       content type unless an administrator disbles registrations on specific 
       posts.'),
   );
+
+  $form['registration']['registration_bundle:node:'] = array(
+    '#type' => 'select',
+    '#title' => t('Registration Type'),
+    '#default_value' => variable_get('registration_bundle:node:' . $type, ''),
+    '#options' => registration_bundle_options(),
+  );
 }
 
 /**
  * Implements hook_node_type_delete().
  */
 function registration_node_type_delete($info) {
-  variable_del('registration_node_status' . $info->type);
+  variable_del('registration_status:node:_' . $info->type);
+  variable_del('registration_bundle:node:_' . $info->type);
 }
 
 /**
@@ -206,7 +479,7 @@ function registration_node_type_delete($info) {
  */
 function registration_register_page_access($node) {
   $ret = FALSE;
-  if (variable_get('registration_node_status_' . $node->type, 0)) {
+  if (variable_get('registration_status:node:_' . $node->type, 0)) {
     if (user_access('administer registration') || user_access('add registration')) {
       $settings = registration_node_settings($node->nid);
       if ($settings['status']) {
@@ -223,7 +496,7 @@ function registration_register_page_access($node) {
  */
 function registration_administer_registrations_access($node) {
   $ret = FALSE;
-  if (variable_get('registration_node_status_' . $node->type, 0)) {
+  if (variable_get('registration_status:node:_' . $node->type, 0)) {
     if (user_access('administer registration')) {
       $ret = TRUE;
     }
@@ -232,12 +505,12 @@ function registration_administer_registrations_access($node) {
   return $ret;
 }
 
-/**
+/*
  * Page callback for adding a registration.
  */
 function registration_register_page($node) {
   if (registration_has_room($node->nid)) {
-    $registration = entity_get_controller('registration')->create(array('type' => 'registration'));
+    $registration = entity_create('registration', array('type' => 'registration'));
     $registration->nid = $node->nid;
     return drupal_get_form('registration_form', $registration);
   }
@@ -249,7 +522,7 @@ function registration_register_page($node) {
 /**
  * Page callback for viewing registrations
  */
-function registration_registrations_page($node) {
+function registration_registrations_page($entity) {
   $header = array(
     array('data' => t('id'), 'field' => 'registration_id', 'type' => 'property', 
         'specifier' => 'registration_id'),
@@ -264,10 +537,13 @@ function registration_registrations_page($node) {
     array('data' => t('Actions')),
   );
   
+  //@todo pretty node hard coded to nodes right now.
   $query = new EntityFieldQuery;
   $result = $query
     ->entityCondition('entity_type', 'registration')
-    ->propertyCondition('nid', $node->nid)
+    ->propertyCondition('eid', $entity->nid)
+    ->propertyCondition('entity_type', 'node')
+    ->propertyCondition('entity_bundle', $entity->type)
     ->pager(20)
     ->tableSort($header)
     ->execute();
@@ -297,27 +573,24 @@ function registration_registrations_page($node) {
       );
     }
 
-    $settings = registration_node_settings($node->nid);
+    $settings = registration_node_settings($entity->nid);
         
-    $table = array(
-      'header' => $header,
-      'rows' => $rows,
-      'caption' => t('List of registrations for %title. !count of !capacity slots are filled.', 
-        array(
-          '%title' => $node->title,
-          '!count' => '<strong>' . registration_event_count($node->nid) . '</strong>', 
-          '!capacity' => '<strong>' . $settings['capacity'] . '</strong>'
-        ))
+    return array(
+      '#theme' => 'table',
+      '#header' => $header,
+      '#rows' => $rows,
+      '#caption' => t('List of registrations for %title. !count of !capacity slots are filled.',
+          array(
+            '%title' => $entity->title,
+            '!count' => '<strong>' . registration_event_count($entity->nid) . '</strong>',
+            '!capacity' => '<strong>' . $settings['capacity'] . '</strong>'
+          ))
     );
-
-    $out = theme('table', $table) . theme('pager');
   }
   else {
-    $out = t('There are no registratrants for %name', 
-        array('%name' => $node->title));
+    return  t('There are no registratrants for %name', 
+        array('%name' => $entity->title));
   }
-
-  return $out;
 }
 
 /**
@@ -344,22 +617,33 @@ function registration_has_room($nid) {
  *
  * @return int
  */
-function registration_event_count($nid) {
+function registration_event_count($eid) {
   $count = &drupal_static(__FUNCTION__, FALSE);
   if (!$count) {
-    $count = db_query("SELECT sum(count) FROM {registration} WHERE nid = :nid",
-      array(':nid' => $nid)
+    // @todo db_select().
+    $count = db_query("SELECT sum(count) FROM {registration} WHERE eid = :eid",
+      array(':eid' => $eid)
     )->fetchField();    
   }
   return $count;
 }
 
 /**
+ * Implements hook_entity_delete().
+ */
+function registration_entity_delete($entity, $type) {
+  //@todo clean?
+  $data = entity_extract_ids($type, $entity);
+  db_delete('registration')->condition('eid', $data[0]);
+}
+
+/**
  * Implements hook_node_delete().
  *   Delete registrations and settings for this node.
+ * @todo is this redundant?
  */
 function registration_node_delete($node) {
-  db_delete('registration')->condition('nid', $node->nid)->execute();
+  db_delete('registration')->condition('entity_type', 'node')->condition('type', $node->type)->condition('eid', $node->nid)->execute();
   db_delete('registration_node')->condition('nid', $node->nid)->execute();
 }
 
@@ -393,6 +677,9 @@ function registration_theme() {
     'registration' => array(
       'arguments' => array('registration' => NULL),
     ),
+    'registration_types' => array(
+      'arguments' => array('types' => NULL),
+    ),
   );
 }
 
@@ -405,11 +692,11 @@ function registration_theme() {
 function theme_registration($variables) {
   $registration = $variables['registration'];
   $output = '<div><label>' . t('Email') . '</label>' . $registration->mail . '</div>';
-  if ($node = node_load($registration->nid)) {
-    $output .= '<div><label>' . $node->type . "</label>" . l($node->title, 'node/' . $registration->nid) . '</div>';
-  }
+//  if ($node = node_load($registration->nid)) {
+//    $output .= '<div><label>' . $node->type . "</label>" . l($node->title, 'node/' . $registration->nid) . '</div>';
+//  }
 
-  $output .= '<div><label>' . t('Count') . '</label>' . $registration->count . '</div>';
+  $output = '<div><label>' . t('Count') . '</label>' . $registration->count . '</div>';
   $output .= '<div><label>' . t('Created') . '</label>' . format_date($registration->created) . '</div>';
 
   return $output;
@@ -543,3 +830,258 @@ function registration_cron() {
       ->execute();
   }
 }
+
+//@todo review the following code
+
+/**
+ * Form callback for adding or editing a registration type.
+ */
+function registration_type_form($form, &$form_state, $type = NULL) {
+  $name = '';
+  $machine = '';
+  $desc = '';
+  $op = 'new';
+  $mtype = FALSE;
+  $form = array();
+
+  if (is_string($type)) {
+    $mtype = registration_type_load($type);
+  }
+
+  if ($mtype) {
+    $name = $mtype->name;
+    $machine = $mtype->type;
+    $desc = $mtype->description;
+    $op = 'edit';
+    $form['bundle_old'] = array(
+      '#type' => 'hidden',
+      '#value' => $machine,
+    );
+  }
+
+  $form['pop'] = array(
+    '#type' => 'hidden',
+    '#default_value' => $op,
+    '#value' => $op,
+  );
+  $form['name'] = array(
+    '#type' => 'textfield',
+    '#title' => 'Name',
+    '#default_value' => $name,
+  );
+  $form['bundle'] = array(
+    '#type' => 'machine_name',
+    '#title' => 'Machine name',
+    '#machine_name' => array(
+      'exists' => 'registration_entity_type_exists',
+    ),
+    '#default_value' => $machine,
+  );
+  $form['description'] = array(
+    '#type' => 'textarea',
+    '#title' => 'Description',
+    '#default_value' => $desc,
+  );
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => 'Submit',
+  );
+
+  return $form;
+}
+
+/**
+ * Submit handler for adding or editing a registration type.
+ */
+function registration_type_form_submit($form, $form_state) {
+  $op = $form_state['values']['pop'];
+  $msg = '';
+  $record = (object) array(
+    'name' => $form_state['values']['name'],
+    'type' => $form_state['values']['bundle'],
+    'description' => $form_state['values']['description'],
+    'created' => REQUEST_TIME,
+    'changed' => REQUEST_TIME,
+  );
+  $ret = '';
+  switch ($op) {
+    case 'new':
+      $ret = drupal_write_record('registration_type', $record);
+      $msg = t(' created.');
+      field_attach_create_bundle('registration', $form_state['values']['bundle']);
+      break;
+    case 'edit':
+      unset($record->created);
+      $ret = drupal_write_record('registration_type', $record, array('type'));
+      $msg = t(' updated.');
+      field_attach_rename_bundle('registration', $form_state['values']['bundle_old'], $form_state['values']['bundle']);
+      break;
+  }
+  entity_info_cache_clear();
+  registration_entity_types_reset();
+  drupal_set_message(t('Registration entity <em>@type</em> has been @msg.'), array('@type' => $record->type, '@msg' => $msg));
+  drupal_goto('admin/structure/registration/types');
+}
+
+/**
+ * Machine name existence callback.
+ */
+function registration_entity_type_exists($type) {
+  $types = registration_entity_types();
+  if (array_key_exists($type, $types)) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/**
+ * Delete form callback.
+ *
+ * @todo Delete all registrations of that type.
+ * @todo Delete all variables that have this type as the registration entity.
+ * @todo Delete all fields associated with only this entity.
+ */
+function registration_delete_type($type) {
+  return "Delete $type";
+}
+
+/**
+ * Page callback to list all registration types.
+ */
+function registration_types_page() {
+  $header = array(t('Name'), t('Operations'));
+  $rows = array();
+  foreach (registration_entity_types() as $type => $info) {
+    $links = array(
+      'edit' => array(
+        'title' => 'edit',
+        'href' => 'admin/structure/registration/types/' . $type . '/edit',
+      ),
+      'manage fields' => array(
+        'title' => 'manage fields',
+        'href' => 'admin/structure/registration/types/' . $type . '/manage/fields',
+      ),
+      'manage display' => array(
+        'title' => 'manage display',
+        'href' => 'admin/structure/registration/types/' . $type . '/manage/display',
+      ),
+      'delete' => array(
+        'title' => 'delete',
+        'href' => 'admin/structure/registration/types/' . $type . '/delete',
+      ),
+    );
+    $rows[] = array(
+      theme('registration_types', array('type' => $info)),
+      theme('links', array('links' => $links, 'attributes' => array('class' => 'links inline operations'))),
+    );
+  }
+  
+  if (empty($rows)) {
+    $rows[] = array(
+      array(
+        'data' => t('There are no registration types yet. <a href="@link">Add a Registration Type</a>', array('@link' => url('admin/structure/registration/types/add'))),
+        'colspan' => 2,
+      ),
+    );
+  }
+  
+  return theme('table', array('header' => $header, 'rows' => $rows));
+}
+
+/**
+ * Themes a specific registration type row.
+ */
+function theme_registration_types($variables) {
+  $type = $variables['type'];
+
+  $output = check_plain($type->name);
+  $output .= ' <small> (Machine name: ' . check_plain($type->type) . ')</small>';
+  $output .= '<div class="description">' . filter_xss_admin($type->description) . '</div>';
+
+  return $output;
+}
+
+/**
+ * Registration entity edit/delete form title callback.
+ */
+function registration_admin_form_title($type, $action, $bundle = NULL) {
+  $mtype = registration_type_load($type);
+  switch ($action) {
+    case 'Status':
+      return 'Set Status for ' . $type . ':' . $bundle;
+    case 'Delete':
+      return 'Delete type ' . $mtype->name;
+    case 'Edit':
+      return 'Edit type ' . $mtype->name;
+  }
+}
+
+/**
+ * Implements hook_menu_alter().
+ *
+ * Set all manage field and display links to inline context so they don't show
+ * up on the Types page.
+ */
+function registration_menu_alter(&$items) {
+  foreach (registration_entity_types() as $type => $info) {
+    $items['admin/structure/registration/types/' . $type . '/manage/fields']['context'] = MENU_CONTEXT_INLINE;
+    $items['admin/structure/registration/types/' . $type . '/manage/display']['context'] = MENU_CONTEXT_INLINE;
+    $items['admin/structure/registration/types/' . $type . '/manage/display/full']['context'] = MENU_CONTEXT_PAGE;
+    $items['admin/structure/registration/types/' . $type . '/manage/display/teaser']['context'] = MENU_CONTEXT_PAGE;
+  }
+}
+
+/**
+ * Entity registration status form callback.
+ */
+function registration_status_form($form, $form_state, $type, $bundle) {
+  $form = array();
+
+  $form['type'] = array(
+    '#type' => 'hidden',
+    '#value' => $type . ':_' . $bundle,
+  );
+
+  $form['status'] = array(
+    '#type' => 'radios',
+    '#title' => t('Status'),
+    '#default_value' => variable_get('registration_status:' . $type . ':_' . $bundle, 0),
+    '#options' => array('Disabled', 'Enabled'),
+  );
+  
+  $form['registration_entity'] = array(
+    '#type' => 'select',
+    '#title' => t('Registration Type'),
+    '#default_value' => variable_get('registration_bundle:' . $type . ':_' . $bundle, ''),
+    '#options' => registration_bundle_options(),
+  );
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => 'Save Settings',
+  );
+
+  return $form;
+}
+
+/**
+ * Entity registration status submit handler.
+ */
+function registration_status_form_submit($form, &$form_state) {
+  $type = $form_state['values']['type'];
+  variable_set('registration_bundle:' . $type, $form_state['values']['registration_entity']);
+  variable_set('registration_status:' . $type, $form_state['values']['status']);
+  drupal_set_message(t('Registration settings updated for @type.', array('@type' => $type)));
+  drupal_goto('admin/structure/registration');
+}
+
+/**
+ * Callback to get options list of registration bundles.
+ */
+function registration_bundle_options() {
+  $options = array('' => 'Select a Bundle');
+  foreach (registration_entity_types() as $type => $info) {
+    $options[$type] = $info->name;
+  }
+  return $options;
+}
