diff --git a/includes/registration.entity.inc b/includes/registration.entity.inc
index b5cb3dd..6834e1d 100644
--- a/includes/registration.entity.inc
+++ b/includes/registration.entity.inc
@@ -257,13 +257,6 @@ class Registration extends Entity {
       '#suffix' => '</div>',
     );
 
-    $states = registration_states();
-    $build['state'] = array(
-      '#prefix' => '<div class="field registration-state"><div class="field-label">' . t('State') . '</div>',
-      '#markup' => $states[$this->state],
-      '#suffix' => '</div>',
-    );
-
     return $build;
   }
 
@@ -273,11 +266,6 @@ class Registration extends Entity {
    * @return mixed
    */
   public function save() {
-    // set a default state if not provided
-    if (!$this->state || $this->state == -1) {
-      $default_state = registration_get_default_state();
-      $this->state = $default_state->registration_state_id;
-    }
     $this->updated = REQUEST_TIME;
     if (!$this->registration_id) {
       $this->created = REQUEST_TIME;
@@ -575,8 +563,19 @@ function registration_get_types($name = NULL) {
  * @return
  *   A registration type array or FALSE if $type does not exist.
  */
-function registration_type_load($type) {
-  return registration_get_types($type);
+function registration_type_load($registration_type_id) {
+  return entity_load_single('registration_type', $registration_type_id);
+}
+
+/**
+ * Return a registration type by machine name.
+ *
+ * @param $name
+ *   If set, the type with the given name is returned.
+ */
+function registration_type_load_by_name($name) {
+  $types = entity_load_multiple_by_name('registration_type', array($name));
+  return isset($name) ? reset($types) : $types;
 }
 
 /**
@@ -605,8 +604,7 @@ function registration_type_delete(RegistrationType $type) {
  */
 class RegistrationState extends Entity {
 
-  public $name, $label, $description, $default_state,
-    $active, $show_on_form, $weight;
+  public $name, $label, $description, $active, $hidden, $weight, $registration_type;
 
   public function __construct($values = array()) {
     parent::__construct($values, 'registration_state');
@@ -618,19 +616,6 @@ class RegistrationState extends Entity {
  * The controller class used for registration state entities
  */
 class RegistrationStateController extends EntityAPIControllerExportable {
-
-  public function save($entity, DatabaseTransaction $transaction = NULL) {
-    parent::save($entity, $transaction);
-
-    if ($entity->default_state == 1) {
-      $query = db_update('registration_state')
-        ->fields(array('default_state' => 0))
-        ->condition('registration_state_id',
-        $entity->registration_state_id, '<>');
-      $query->execute();
-    }
-  }
-
 }
 
 
@@ -642,7 +627,6 @@ class RegistrationStatesUIController extends EntityDefaultUIController {
   public function overviewForm($form, &$form_state) {
     return drupal_get_form('registration_states_overview_form');
   }
-
 }
 
 /**
@@ -651,3 +635,102 @@ class RegistrationStatesUIController extends EntityDefaultUIController {
 function registration_state_access($op, $entity = NULL, $account = NULL, $entity_type = NULL) {
   return user_access('administer registration states', $account);
 }
+
+
+/**
+ * Query registration state entities.
+ *
+ * @param bool $reset
+ *   (optional) Reset internal cache.
+ *
+ * @return array
+ *   An array of registration state entities keyed by registration type name.
+ */
+function registration_states($reset = FALSE) {
+  $fast = &drupal_static(__FUNCTION__, NULL);
+
+  if ($reset || !isset($fast)) {
+    $fast = array();
+
+    $query = new EntityFieldQuery();
+    $query->entityCondition('entity_type', 'registration_state');
+
+    if ($results = $query->execute()) {
+      $entities = entity_load('registration_state', array_keys($results['registration_state']));
+      foreach ($entities as $state) {
+        $registration_types[$state->registration_type][] = $state;
+      }
+
+      foreach ($registration_types as $registration_type_id => $states) {
+        $registration_type = registration_type_load($registration_type_id);
+        foreach ($states as $state) {
+          if (!empty($registration_type->name)) {
+            $fast[$registration_type->name][$state->registration_state_id] = $state;
+          }
+        }
+      }
+    }
+  }
+
+  return $fast;
+}
+
+/**
+ * Get a list of active state entities.
+ *
+ * @param string $registration_type
+ *   Registration type to get states for.
+ *
+ * @return array
+ *   An array of active registration state entities.
+ */
+function registration_states_active($registration_type) {
+  $states = registration_states();
+  $return = array();
+
+  if (isset($states[$registration_type])) {
+    foreach ($states[$registration_type] as $id => $state) {
+      if (!$state->hidden) {
+        $return[] = $state;
+      }
+    }
+  }
+
+  return $return;
+}
+
+/**
+ * Find the unique state ID for a registration type and state combination.
+ *
+ * @param string $registration_type
+ *   A registration type.
+ * @param string $state_name
+ *   A state machine name.
+ *
+ * @return int|bool
+ *   Returns unique state identifier, or FALSE.
+ */
+function registration_get_state_id($registration_type, $state_name) {
+  $states = registration_states($registration_type);
+
+  if (isset($states[$registration_type])) {
+    foreach ($states[$registration_type] as $state) {
+      if ($state->name == $state_name) {
+        return $state->registration_state_id;
+      }
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+ * Return a state by machine name.
+ *
+ * @param $name
+ *   If set, the type with the given name is returned.
+ */
+function registration_state_load_by_name($name) {
+  $types = entity_load_multiple_by_name('registration_state', array($name));
+  return isset($name) ? reset($types) : $types;
+}
\ No newline at end of file
diff --git a/includes/registration.field.inc b/includes/registration.field.inc
index a8d95ad..9deb286 100644
--- a/includes/registration.field.inc
+++ b/includes/registration.field.inc
@@ -6,6 +6,26 @@
  */
 
 /**
+ * Registration widget.
+ */
+define('REGISTRATION_WIDGET', 'registration_select');
+
+/**
+ * Registration state widget.
+ */
+define('REGISTRATION_STATE_WIDGET', 'registration_state');
+
+/**
+ * Registration widget.
+ */
+define('REGISTRATION_FORMATTER_DEFAULT', 'registration_default');
+
+/**
+ * Registration state widget.
+ */
+define('REGISTRATION_STATE_FORMATTER_DEFAULT', 'registration_state_default');
+
+/**
  * Implements hook_field_info().
  */
 function registration_field_info() {
@@ -35,10 +55,18 @@ function registration_field_info() {
           ),
         ),
       ),
-      'default_widget' => 'registration_select',
-      'default_formatter' => 'registration_default',
+      'default_widget' => REGISTRATION_WIDGET,
+      'default_formatter' => REGISTRATION_FORMATTER_DEFAULT,
       'no_ui' => FALSE
     ),
+    'registration_state' => array(
+      'label' => t('Registration State'),
+      'description' => t('Allow registrations to have states.'),
+      'settings' => array(),
+      'default_widget' => REGISTRATION_STATE_WIDGET,
+      'default_formatter' => REGISTRATION_STATE_FORMATTER_DEFAULT,
+      'no_ui' => FALSE,
+    ),
   );
 }
 
@@ -48,41 +76,43 @@ function registration_field_info() {
  * Add default registration field instance settings.
  */
 function registration_field_instance_settings_form($field, $instance) {
-  $form = $form_state = array();
-  $default_settings = isset($instance['settings']['default_registration_settings']) ? $instance['settings']['default_registration_settings'] : array();
-
-  // flatten scheduling and reminder settings since this form is in tree mode
-  foreach ($default_settings as $key => $val) {
-    if ($key != 'settings' and is_array($val)) {
-      foreach ($val as $key1 => $val1) {
-        if (is_array($val1)) {
-          foreach ($val1 as $key2 => $val2) {
-            $default_settings[$key2] = $val2;
+  if ($field['type'] == 'registration') {
+    $form = $form_state = array();
+    $default_settings = isset($instance['settings']['default_registration_settings']) ? $instance['settings']['default_registration_settings'] : array();
+
+    // flatten scheduling and reminder settings since this form is in tree mode
+    foreach ($default_settings as $key => $val) {
+      if ($key != 'settings' and is_array($val)) {
+        foreach ($val as $key1 => $val1) {
+          if (is_array($val1)) {
+            foreach ($val1 as $key2 => $val2) {
+              $default_settings[$key2] = $val2;
+            }
+          }
+          else {
+            $default_settings[$key1] = $val1;
           }
         }
-        else {
-          $default_settings[$key1] = $val1;
-        }
+        unset($default_settings[$key]);
       }
-      unset($default_settings[$key]);
     }
-  }
 
-  $settings_form = registration_entity_settings_form($form, $form_state, $default_settings);
+    $settings_form = registration_entity_settings_form($form, $form_state, $default_settings);
 
-  $form['default_registration_settings'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Default Registration settings'),
-    '#collapsible' => TRUE,
-    '#description' => t('These settings will be applied when an entity with this field is saved and does not yet have it\'s own settings applied.')
-  );
+    $form['default_registration_settings'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Default Registration settings'),
+      '#collapsible' => TRUE,
+      '#description' => t('These settings will be applied when an entity with this field is saved and does not yet have it\'s own settings applied.')
+    );
 
-  // unset the save button just in case
-  unset($settings_form['save']);
-  $form['default_registration_settings'] += $settings_form;
+    // unset the save button just in case
+    unset($settings_form['save']);
+    $form['default_registration_settings'] += $settings_form;
 
-  // @todo: validation
-  return $form;
+    // @todo: validation
+    return $form;
+  }
 }
 
 /**
@@ -96,8 +126,15 @@ function registration_field_validate($entity_type, $entity, $field, $instance, $
  * Implements hook_field_is_empty().
  */
 function registration_field_is_empty($item, $field) {
-  if (empty($item['registration_type']) && (string) $item['registration_type'] !== '') {
-    return TRUE;
+  if ($field['type'] == 'registration') {
+    if (empty($item['registration_type'])) {
+      return TRUE;
+    }
+  }
+  elseif ($field['type'] == 'registration_state') {
+    if (empty($item['registration_state'])) {
+      return TRUE;
+    }
   }
   return FALSE;
 }
@@ -107,7 +144,7 @@ function registration_field_is_empty($item, $field) {
  */
 function registration_field_widget_info() {
   return array(
-    'registration_select' => array(
+    REGISTRATION_WIDGET => array(
       'label' => t('Registration Type'),
       'field types' => array('registration'),
       'settings' => array(),
@@ -116,29 +153,64 @@ function registration_field_widget_info() {
         'default value' => FIELD_BEHAVIOR_DEFAULT,
       ),
     ),
+    REGISTRATION_STATE_WIDGET => array(
+      'label' => t('Registration State'),
+      'field types' => array('registration_state'),
+      'settings' => array(),
+      'behaviors' => array(
+        'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+        'default value' => FIELD_BEHAVIOR_DEFAULT,
+      ),
+    ),
   );
 }
 
 /**
  * Implements hook_field_widget_form().
  */
-function registration_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
-  $options = array('' => t('-- Disable Registrations --'));
-  foreach (registration_get_types() as $type) {
-    $options[$type->name] = $type->label;
-  }
-  $element += array(
-    '#type' => 'select',
-    '#options' => $options,
-    '#default_value' => isset($items[$delta]) ? $items[$delta] : array(),
-  );
+function registration_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $base) {
+  $element = $base;
+  $registration_type = $instance['bundle'];
+
+  switch ($instance['widget']['type']) {
+    case REGISTRATION_WIDGET:
+      $options = array();
+      foreach (registration_get_types() as $type) {
+        $options[$type->name] = $type->label;
+      }
+
+      $element += array(
+        '#type' => 'select',
+        '#options' => $options,
+        '#empty_option' => t('- Disable Registrations -'),
+        '#default_value' => isset($items[$delta]) ? $items[$delta] : array(),
+        '#description' => t('Select what type of registrations should be enabled for this @type.', array('@type' => $instance['bundle'])),
+      );
+
+      return array('registration_type' => $element);
+      break;
+
+    case REGISTRATION_STATE_WIDGET:
+      $options = array();
+      $states = registration_states();
+      if (isset($states[$registration_type])) {
+        foreach ($states[$registration_type] as $state) {
+          if (!$state->hidden) {
+            $options[$state->registration_state_id] = $state->label;
+          }
+        }
+      }
+
+      $element += array(
+        '#type' => 'select',
+        '#options' => $options,
+        '#default_value' => isset($items[$delta]['registration_state']) ? $items[$delta]['registration_state'] : array(),
+      );
 
-  // force some help text into the field, appending anything the user addded.
-  $element['#description'] .= ' ' . t('Select what type of registrations should be
-    enabled for this @type. Depending on the display settings, it will appear
-    as either string, registration link, or form.', array('@type' => $instance['bundle']));
+      return array('registration_state' => $element);
+      break;
 
-  return array('registration_type' => $element);
+  }
 }
 
 /**
@@ -146,7 +218,7 @@ function registration_field_widget_form(&$form, &$form_state, $field, $instance,
  */
 function registration_field_formatter_info() {
   return array(
-    'registration_default' => array(
+    REGISTRATION_FORMATTER_DEFAULT => array(
       'label' => t('Default'),
       'field types' => array('registration'),
     ),
@@ -158,6 +230,10 @@ function registration_field_formatter_info() {
       'label' => t('Registration Form'),
       'field types' => array('registration'),
     ),
+    REGISTRATION_STATE_FORMATTER_DEFAULT => array(
+      'label' => t('Default'),
+      'field types' => array('registration_state'),
+    ),
   );
 }
 
@@ -166,41 +242,56 @@ function registration_field_formatter_info() {
  */
 function registration_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
   $element = array();
-
-  // we know we should only have a single item
-  if (isset($items[0]['registration_type']) && !empty($items[0]['registration_type'])) {
-    $reg_type = registration_type_load($items[0]['registration_type']);
-    switch ($display['type']) {
-      case 'registration_default':
-        $element[0] = array('#markup' => $reg_type->label);
-        break;
-      case 'registration_link':
-        // enable registration link if accessible
-        if (registration_register_page_access($entity_type, $entity)) {
-          $uri = entity_uri($entity_type, $entity);
-          $element[0] = array(
-            '#markup' => theme('registration_link',
-              array(
-                'label' => $reg_type->label,
-                'path' => $uri['path'] . '/register'
-              )
-            )
+  list($entity_id) = entity_extract_ids($entity_type, $entity);
+
+  switch ($display['type']) {
+    // Registration fields
+    case REGISTRATION_FORMATTER_DEFAULT:
+      foreach ($items as $delta => $item) {
+        $registration_type = registration_type_load_by_name($item['registration_type']);
+        $element[$delta] = array('#markup' => $registration_type->label);
+      }
+      break;
+
+    case 'registration_link':
+      if (registration_register_page_access($entity_type, $entity)) {
+        $uri = entity_uri($entity_type, $entity);
+        foreach ($items as $delta => $item) {
+          $registration_type = registration_type_load_by_name($item['registration_type']);
+          $element[$delta] = array(
+            '#markup' => theme('registration_link', array(
+              'label' => $registration_type->label,
+              'path' => $uri['path'] . '/register'
+            ))
           );
         }
-        break;
-      case 'registration_form':
-        // enable registration link if accessible
-        list($entity_id) = entity_extract_ids($entity_type, $entity);
-        if (registration_register_page_access($entity_type, $entity) && registration_status($entity_type, $entity_id)) {
+      }
+      break;
+
+    case 'registration_form':
+      if (registration_register_page_access($entity_type, $entity) && registration_status($entity_type, $entity_id)) {
+        foreach ($items as $delta => $item) {
+          $registration_type = registration_type_load_by_name($item['registration_type']);
           $registration = entity_get_controller('registration')->create(array(
             'entity_type' => $entity_type,
             'entity_id' => $entity_id,
-            'type' => $reg_type->name,
+            'type' => $registration_type->name,
           ));
-          $element[0] = drupal_get_form('registration_form', $registration);
+          $element[$delta] = drupal_get_form('registration_form', $registration);
         }
-        break;
-    }
+      }
+      break;
+
+    // Registration state fields
+    case REGISTRATION_STATE_FORMATTER_DEFAULT:
+      foreach ($items as $delta => $item) {
+        $state = entity_load_single('registration_state', $item['registration_state']);
+        if ($state) {
+          $element[$delta]['#markup'] = $state->label;
+        }
+      }
+      break;
+
   }
 
   return $element;
@@ -336,3 +427,27 @@ function _registration_menu_rebuild($instance) {
     menu_rebuild();
   }
 }
+
+/**
+ * Get name of registration_state field attached to a registration bundle.
+ *
+ * Technically more than one registration_state field type can be attached per
+ * bundle. This will return the first instance found.
+ *
+ * @param string $registration_type
+ *   The registration bundle.
+ *
+ * @return string
+ *   Name of a registration_state field.
+ */
+function registration_get_state_field_name($registration_type) {
+  $entity_type = 'registration';
+
+  $instances = field_info_instances($entity_type, $registration_type);
+  foreach (array_keys($instances) as $field_name) {
+    $field = field_info_field($field_name);
+    if ($field['type'] == 'registration_state') {
+      return $field_name;
+    }
+  }
+}
diff --git a/includes/registration.forms.inc b/includes/registration.forms.inc
index 30a43b4..baf1035 100644
--- a/includes/registration.forms.inc
+++ b/includes/registration.forms.inc
@@ -74,24 +74,6 @@ function registration_form($form, &$form_state, Registration $registration) {
     '#element_validate' => array('element_validate_integer_positive')
   );
 
-  $options = array();
-  $default_state = -1;
-  $states = registration_states(array('show_on_form' => TRUE));
-  foreach ($states as $state) {
-    $options[$state->registration_state_id] = t('@state', array('@state' => $state->label));
-    if ($state->default_state) {
-      $default_state = $state->registration_state_id;
-    }
-  }
-  $form['state'] = array(
-    '#type' => 'select',
-    '#title' => t('State'),
-    '#description' => t('State of this registration'),
-    '#default_value' => isset($registration->state) ? $registration->state : $default_state,
-    '#options' => $options,
-    '#access' => !empty($states)
-  );
-
   field_attach_form('registration', $registration, $form, $form_state);
 
   $form['actions'] = array('#type' => 'actions');
@@ -186,8 +168,6 @@ function registration_form_submit($form, &$form_state) {
   }
 
   $registration->count = $form_state['values']['count'];
-  $registration->state = (!empty($form_state['values']['state']))
-    ? $form_state['values']['state'] : NULL;
 
   switch ($form_state['values']['who_is_registering']) {
     case REGISTRATION_REGISTRANT_TYPE_ANON:
@@ -331,7 +311,7 @@ function registration_registrations_broadcast_form_submit($form, &$form_state) {
  *
  * @return array $form
  *
- * @see hook_registration_entity_settings().
+ * @see hook_registration_entity_settings()
  */
 function registration_entity_settings_form($form, &$form_state, $settings, $entity_type = NULL, $entity_id = NULL) {
   if ($entity_id) {
@@ -589,7 +569,6 @@ function registration_convert_form_settings($values) {
  * Generates the Registration state editing form.
  */
 function registration_state_form($form, &$form_state, $registration_state, $op = 'edit') {
-
   $form['label'] = array(
     '#title' => t('Label'),
     '#type' => 'textfield',
@@ -605,28 +584,27 @@ function registration_state_form($form, &$form_state, $registration_state, $op =
     '#maxlength' => 32,
     //'#disabled' => $registration_state->locked && $op != 'clone',
     '#machine_name' => array(
-      'exists' => 'registration_get_states',
+      'exists' => 'registration_state_load_by_name',
       'source' => array('label'),
     ),
     '#description' => t('A unique machine-readable name for
     this registration state. It must only contain lowercase letters,
      numbers, and underscores.'),
   );
-  $form['default_state'] = array(
-    '#title' => t('Default'),
-    '#type' => 'checkbox',
-    '#default_value' => isset($registration_state->default_state) ?
-      $registration_state->default_state : 0,
-    '#attributes' => array('class' => array('reg-default')),
-  );
-  $form['weight'] = array(
-    '#title' => t('Weight'),
-    '#type' => 'weight',
-    '#default_value' => isset($registration_state->weight) ?
-      $registration_state->weight : 0,
-    '#delta' => 15,
-    '#attributes' => array('class' => array('registration-state-weight')),
+
+  $options = array();
+  foreach (registration_get_types() as $type) {
+    $options[$type->id] = $type->label;
+  }
+
+  $form['registration_type'] = array(
+    '#type' => 'select',
+    '#options' => $options,
+    '#required' => TRUE,
+    '#default_value' => isset($registration_state->registration_type) ? $registration_state->registration_type : 0,
+    '#description' => t('Select what type of registration should be associated with this state.'),
   );
+
   $form['description'] = array(
     '#title' => t('Description'),
     '#type' => 'textfield',
@@ -672,7 +650,12 @@ function registration_state_form_submit(&$form, &$form_state) {
  * Registration states setting form
  */
 function registration_state_overview_form($form, &$form_state) {
-  $registration_states = registration_states();
+  $query = new EntityFieldQuery();
+  $results = $query
+    ->entityCondition('entity_type', 'registration_state')
+    ->propertyOrderBy('weight', 'ASC')
+    ->execute();
+  $registration_states = entity_load('registration_state', array_keys($results['registration_state']));
 
   $form['#attached']['js'] = array(
     drupal_get_path('module', 'registration') . '/registration.js',
@@ -683,6 +666,8 @@ function registration_state_overview_form($form, &$form_state) {
   if (!empty($registration_states)) {
 
     foreach ($registration_states as $sid => $state) {
+      $registration_type = registration_type_load($state->registration_type);
+
       $form['state'][$sid]['sid'] = array(
         '#type' => 'hidden',
         '#default_value' => $sid,
@@ -695,12 +680,6 @@ function registration_state_overview_form($form, &$form_state) {
         '#size' => 20,
         '#required' => TRUE,
       );
-      $form['state'][$sid]['default_state'] = array(
-        '#title' => t('Default'),
-        '#type' => 'checkbox',
-        '#default_value' => $state->default_state,
-        '#attributes' => array('class' => array('reg-default')),
-      );
       $form['state'][$sid]['weight'] = array(
         '#title' => t('Weight'),
         '#type' => 'weight',
@@ -715,31 +694,38 @@ function registration_state_overview_form($form, &$form_state) {
         '#maxlength' => 128,
         '#size' => 50,
       );
+      $form['state'][$sid]['registration_type'] = array(
+        '#type' => 'item',
+        '#markup' => !empty($registration_type->label) ? $registration_type->label : '',
+      );
       $form['state'][$sid]['active'] = array(
         '#title' => t('Active'),
         '#type' => 'checkbox',
         '#default_value' => $state->active,
       );
-      $form['state'][$sid]['show_on_form'] = array(
-        '#title' => t('Show on form'),
+      $form['state'][$sid]['hidden'] = array(
+        '#title' => t('Hide on form'),
         '#type' => 'checkbox',
-        '#default_value' => $state->show_on_form,
+        '#default_value' => $state->hidden,
+      );
+      $form['state'][$sid]['edit'] = array(
+        '#type' => 'item',
+        '#markup' => l(t('edit'), 'admin/structure/registration/registration_states/manage/' . $state->registration_state_id . '/edit', array('query' => drupal_get_destination())),
       );
       $form['state'][$sid]['delete'] = array(
         '#type' => 'item',
-        '#markup' => l(t('delete'), 'admin/structure/registration/registration_states/manage/' . $state->name . '/delete', array('query' => drupal_get_destination())),
+        '#markup' => l(t('delete'), 'admin/structure/registration/registration_states/manage/' . $state->registration_state_id . '/delete', array('query' => drupal_get_destination())),
       );
       $form['state'][$sid]['export'] = array(
         '#type' => 'item',
-        '#markup' => l(t('export'), 'admin/structure/registration/registration_states/manage/' . $state->name . '/export'),
+        '#markup' => l(t('export'), 'admin/structure/registration/registration_states/manage/' . $state->registration_state_id . '/export'),
       );
     }
   }
 
   $form['help'] = array(
     '#type' => 'item',
-    '#description' => t("This table defines the registration states available on this site.
-    The Default will be used if no states are marked as Show on Form. "),
+    '#description' => t("This table defines the registration states available on this site. The Default will be used if no states are marked as Show on Form."),
   );
 
 
@@ -760,9 +746,8 @@ function registration_state_overview_form_submit($form, &$form_state) {
 
     $registration_state = entity_load_single('registration_state', $state['sid']);
     $registration_state->label = $state['label'];
-    $registration_state->default_state = isset($state['default_state']) ? $state['default_state'] : 0;
     $registration_state->active = isset($state['active']) ? $state['active'] : 0;
-    $registration_state->show_on_form = isset($state['show_on_form']) ? $state['show_on_form'] : 0;
+    $registration_state->hidden = isset($state['hidden']) ? $state['hidden'] : 0;
     $registration_state->weight = $state['weight'];
     $registration_state->description = $state['description'];
 
@@ -784,25 +769,28 @@ function theme_registration_state_overview_form($variables) {
   $header = array(
     array('data' => t('Label !required', array('!required' => '<span class="form-required" title="' . t('This field is required.') . '">*</span>'))),
     array('data' => t('Description')),
-    array('data' => t('Default')),
+    array('data' => t('Registration Type')),
     array('data' => t('Active')),
-    array('data' => t('Show on form')),
+    array('data' => t('Hide on form')),
     array('data' => t('Weight')),
-    array('data' => t('Operations'), 'colspan' => 2)
+    array('data' => t('Operations'), 'colspan' => 3)
+  );
+
+  $elements = array(
+    'label',
+    'description',
+    'registration_type',
+    'active',
+    'hidden',
+    'weight',
+    'edit',
+    'delete',
+    'export'
   );
 
   foreach (element_children($form['state']) as $key) {
     $row = array();
-    foreach (array(
-               'label',
-               'description',
-               'default_state',
-               'active',
-               'show_on_form',
-               'weight',
-               'delete',
-               'export'
-             ) as $element) {
+    foreach ($elements as $element) {
       // Since we're rendering these in a table, remove any #title attributes.
       if (!empty($form['state'][$key][$element]['#title'])) {
         unset($form['state'][$key][$element]['#title']);
@@ -816,7 +804,10 @@ function theme_registration_state_overview_form($variables) {
     );
   }
 
+  hide($form['help']);
+
   $output = theme('table', array(
+    'caption' => $form['help']['#description'],
     'header' => $header,
     'rows' => $rows,
     'attributes' => array('id' => 'registration-state-admin-settings-table')
diff --git a/registration.install b/registration.install
index 7caec51..ed4b115 100644
--- a/registration.install
+++ b/registration.install
@@ -62,11 +62,6 @@ function registration_schema() {
         'not null' => TRUE,
         'default' => 0,
       ),
-      'state' => array(
-        'description' => 'State of this registration.',
-        'type' => 'int',
-        'not null' => TRUE,
-      ),
       'created' => array(
         'description' => 'The Unix timestamp when the registration was created.',
         'type' => 'int',
@@ -84,7 +79,6 @@ function registration_schema() {
       'registration_updated' => array('updated'),
       'registration_created' => array('created'),
       'registration_type' => array(array('type', 4)),
-      'registration_state' => array('state'),
     ),
     'foreign keys' => array(
       'registration_author' => array(
@@ -95,10 +89,6 @@ function registration_schema() {
         'table' => 'users',
         'columns' => array('user_uid' => 'uid'),
       ),
-      'registration_state' => array(
-        'table' => 'registration_state',
-        'columns' => array('state' => 'registration_state_id'),
-      ),
     ),
     'unique keys' => array(
       'entity_id_entity_type_user' => array(
@@ -254,6 +244,11 @@ function registration_schema() {
         'not null' => TRUE,
         'description' => t('The registration state ID.'),
       ),
+      'registration_type' => array(
+        'description' => 'The registration type for this state.',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
       'name' => array(
         'type' => 'varchar',
         'length' => 128,
@@ -272,13 +267,6 @@ function registration_schema() {
         'not null' => FALSE,
         'description' => t('The description of the registration state.'),
       ),
-      'default_state' => array(
-        'description' => 'A boolean indicating default registration state.',
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'size' => 'tiny',
-      ),
       'active' => array(
         'type' => 'int',
         'not null' => TRUE,
@@ -286,7 +274,7 @@ function registration_schema() {
         'size' => 'tiny',
         'description' => t('A flag showing active registration states.'),
       ),
-      'show_on_form' => array(
+      'hidden' => array(
         'type' => 'int',
         'not null' => TRUE,
         'default' => 0,
@@ -315,14 +303,16 @@ function registration_schema() {
         'not null' => FALSE,
       ),
     ),
+    'foreign keys' => array(
+      'registration_type' => array(
+        'table' => 'registration_type',
+        'columns' => array('registration_type' => 'id'),
+      ),
+    ),
     'indexes' => array(
       'registration_state_name' => array('name'),
-      'registration_state_default_state' => array('default_state'),
     ),
     'primary key' => array('registration_state_id'),
-    'unique keys' => array(
-      'name' => array('name'),
-    ),
   );
 
   return $schema;
@@ -332,86 +322,52 @@ function registration_schema() {
  * Implements hook_field_schema().
  */
 function registration_field_schema($field) {
-  $columns = array(
-    'registration_type' => array(
-      'type' => 'varchar',
-      'length' => 32,
-      'not null' => FALSE
-    ),
-  );
-  $indexes = array(
-    'registration_type' => array('registration_type'),
-  );
-  $foreign_keys = array(
-    'registration_type' => array(
-      'table' => 'registration_type',
-      'columns' => array('registration_type' => 'name'),
-    ),
-  );
-  return array(
-    'columns' => $columns,
-    'indexes' => $indexes,
-    'foreign keys' => $foreign_keys,
-  );
-}
-
-/**
- * Implements hook_install
- */
-function registration_install() {
-  // Create default states
-  $states = array(
-    'complete' => array(
-      'label' => st('Complete'),
-      'description' => st('Registration has been completed.'),
-      'default_state' => 1,
-      'active' => 1,
-      'show_on_form' => 0,
-      'weight' => 1,
-    ),
-    'pending' => array(
-      'label' => st('Pending'),
-      'description' => st('Registration is pending.'),
-      'default_state' => 0,
-      'active' => 0,
-      'show_on_form' => 0,
-      'weight' => 1,
-    ),
-    'canceled' => array(
-      'label' => st('Canceled'),
-      'description' => st('Registration was cancelled'),
-      'default_state' => 0,
-      'active' => 0,
-      'show_on_form' => 0,
-      'weight' => 1,
-    ),
-  );
-
-  foreach ($states as $state_name => $state_label) {
-    $registration_state = entity_create('registration_state',
-      array(
-        'name' => $state_name,
-        'label' => $state_label['label'],
-        'description' => $state_label['description'],
-        'default_state' => $state_label['default_state'],
-        'active' => $state_label['active'],
-        'show_on_form' => $state_label['show_on_form'],
-        'weight' => $state_label['weight'],
-      )
-    );
-    $registration_state->save();
+  if (isset($field['type'])) {
+    if ($field['type'] == 'registration') {
+      $columns = array(
+        'registration_type' => array(
+          'type' => 'varchar',
+          'length' => 32,
+          'not null' => FALSE
+        ),
+      );
+      $indexes = array(
+        'registration_type' => array('registration_type'),
+      );
+      $foreign_keys = array(
+        'registration_type' => array(
+          'table' => 'registration_type',
+          'columns' => array('registration_type' => 'name'),
+        ),
+      );
+      return array(
+        'columns' => $columns,
+        'indexes' => $indexes,
+        'foreign keys' => $foreign_keys,
+      );
+    }
+    elseif ($field['type'] == 'registration_state') {
+      $columns = array(
+        'registration_state' => array(
+          'description' => 'State of this registration.',
+          'type' => 'int',
+          'not null' => TRUE,
+        ),
+      );
+      $indexes = array(
+        'registration_state' => array('registration_state'),
+      );
+      $foreign_keys = array(
+        'registration_state' => array(
+          'table' => 'registration_state',
+          'columns' => array('registration_state' => 'registration_state_id'),
+        ),
+      );
+      return array(
+        'columns' => $columns,
+        'indexes' => $indexes,
+        'foreign keys' => $foreign_keys,
+      );
+    }
   }
-}
-
-/**
- * Implements hook_uninstall().
- */
-function hook_uninstall() {
-  // Remove default states
-  $default_states = array(
-    'complete', 'complete', 'canceled'
-  );
-  db_delete('registration_state')
-    ->condition('name', $default_states, 'IN')
-    ->execute();
-}
+}
\ No newline at end of file
diff --git a/registration.module b/registration.module
index 6d59288..a075ce3 100644
--- a/registration.module
+++ b/registration.module
@@ -33,6 +33,21 @@ define('REGISTRATION_REGISTRANT_TYPE_USER', 'registration_registrant_type_user')
 define('REGISTRATION_REGISTRANT_TYPE_ANON', 'registration_registrant_type_anon');
 
 /**
+ * Machine name for builtin pending state.
+ */
+define('REGISTRATION_STATE_PENDING', 'pending');
+
+/**
+ * Machine name for builtin complete state.
+ */
+define('REGISTRATION_STATE_COMPLETE', 'complete');
+
+/**
+ * Machine name for builtin canceled state.
+ */
+define('REGISTRATION_STATE_CANCELED', 'canceled');
+
+/**
  * Implements hook_menu().
  */
 function registration_menu() {
@@ -408,6 +423,9 @@ function registration_register_page($entity_type, $entity) {
  * @see registration_menu()
  */
 function registration_registrations_page($entity_type, $entity) {
+  $registration_type = registration_get_entity_registration_type($entity_type, $entity);
+  $state_field_name = registration_get_state_field_name($registration_type);
+
   $header = array(
     array(
       'data' => t('id'),
@@ -448,9 +466,11 @@ function registration_registrations_page($entity_type, $entity) {
     ),
     array(
       'data' => t('State'),
-      'field' => 'state',
-      'type' => 'property',
-      'specifier' => 'state'
+      'type' => 'field',
+      'specifier' => array(
+        'field' => $state_field_name,
+        'column' => 'registration_state'
+      ),
     ),
     array('data' => t('Actions')),
   );
@@ -469,7 +489,6 @@ function registration_registrations_page($entity_type, $entity) {
 
   if (!empty($result['registration'])) {
     $registrations = registration_load_multiple(array_keys($result['registration']));
-    $states = registration_states();
     $rows = array();
 
     foreach ($registrations as $registration) {
@@ -493,6 +512,8 @@ function registration_registrations_page($entity_type, $entity) {
         l('Delete', 'registration/' . $registration->registration_id . '/delete'),
       );
 
+      $states = field_view_field('registration', $registration, $state_field_name, array('label' => 'hidden'));
+
       $rows[] = array(
         l($registration->registration_id, 'registration/' . $registration->registration_id),
         l($registration->mail, 'mailto:' . $registration->mail),
@@ -500,7 +521,7 @@ function registration_registrations_page($entity_type, $entity) {
         $author_col,
         $registration->count,
         format_date($registration->created),
-        $states[$registration->state]->label,
+        render($states),
         implode(' | ', $actions)
       );
     }
@@ -585,26 +606,40 @@ function registration_has_room($entity_type, $entity_id, $slots = 0) {
  *   The host entity type.
  * @param int $entity_id
  *   The host entity ID.
+ * @param bool $reset
+ *   Reset session cache.
  *
  * @return int
  *   The number of slots remaining for a host entity.
  *
  * @see registration_has_room()
  */
-function registration_event_count($entity_type, $entity_id) {
-  $count = &drupal_static(__FUNCTION__ . '_' . $entity_type . '_' . $entity_id, FALSE);
-  if (!$count) {
-    $query = db_select('registration', 'r');
-    $query->addExpression('sum(count)', 'count');
-    $query->condition('entity_id', $entity_id);
-    $query->condition('entity_type', $entity_type);
-    $query->condition('state', registration_get_active_states(), 'IN');
-    $result = $query->execute();
-    $count = $result->fetchField();
-    $count = ($count == '') ? 0 : $count;
+function registration_event_count($entity_type, $entity_id, $reset = FALSE) {
+  $fast = &drupal_static(__FUNCTION__, array());
+
+  if ($reset || !isset($fast[$entity_type][$entity_id])) {
+    $entity = entity_load_single($entity_type, $entity_id);
+    $registration_type = registration_get_entity_registration_type($entity_type, $entity);
+    $state_field_name = registration_get_state_field_name($registration_type);
+
+    $query = new EntityFieldQuery;
+    $query
+      ->entityCondition('entity_type', 'registration')
+      ->propertyCondition('entity_type', $entity_type)
+      ->propertyCondition('entity_id', $entity_id)
+      ->count();
+
+    if ($state_field_name) {
+      $states = registration_states_active($registration_type);
+      if (!empty($states)) {
+        $query->fieldCondition($state_field_name, 'registration_state', array_keys($states), 'IN');
+      }
+    }
+
+    $fast[$entity_type][$entity_id] = (int)$query->execute();
   }
 
-  return $count;
+  return $fast[$entity_type][$entity_id];
 }
 
 /**
@@ -615,6 +650,39 @@ function registration_entity_insert($entity, $entity_type) {
   if ($registration_type !== FALSE) {
     registration_entity_set_default_settings($entity_type, $entity);
   }
+
+  if ($entity_type == 'registration_type') {
+    // Create builtin states
+    $states = array(
+      'pending' => array(
+        'label' => t('Pending'),
+        'description' => t('Registration is pending.'),
+      ),
+      'complete' => array(
+        'label' => t('Complete'),
+        'description' => t('Registration has been completed.'),
+      ),
+      'canceled' => array(
+        'label' => t('Canceled'),
+        'description' => t('Registration was cancelled'),
+      ),
+    );
+
+    $i = 0;
+    foreach ($states as $name => $state) {
+      $registration_state = entity_create('registration_state', $state + array(
+        'name' => $name,
+        'registration_type' => $entity->id,
+        'status' => 1,
+        'active' => 1,
+        'hidden' => 0,
+        'weight' => $i,
+      ));
+      entity_save('registration_state', $registration_state);
+
+      $i += 1;
+    }
+  }
 }
 
 /**
@@ -667,8 +735,8 @@ function registration_entity_delete($entity, $entity_type) {
     ->condition('entity_type', $entity_type)
     ->execute();
 
-  // Remove references to a registration_type on host entities
   if ($entity_type == 'registration_type') {
+    // Remove references to a registration_type on host entities
     $registration_fields = field_read_fields(array('type' => 'registration'));
     if (!empty($registration_fields)) {
       foreach (array_keys($registration_fields) as $field_name) {
@@ -685,6 +753,16 @@ function registration_entity_delete($entity, $entity_type) {
         }
       }
     }
+
+    // Remove states for this registration_type
+    $query = new EntityFieldQuery;
+    $result = $query
+      ->entityCondition('entity_type', 'registration_state')
+      ->propertyCondition('registration_type', $entity_id)
+      ->execute();
+    if (!empty($result['registration_state'])) {
+      entity_delete_multiple('registration_state', array_keys($result['registration_state']));
+    }
   }
 }
 
@@ -784,7 +862,6 @@ function registration_send_broadcast($entity_type, $entity_id, $subject, $messag
     ->entityCondition('entity_type', 'registration')
     ->propertyCondition('entity_id', $entity_id)
     ->propertyCondition('entity_type', $entity_type)
-    ->propertyCondition('state', registration_get_active_states(), 'IN')
     ->execute();
 
   if (!empty($entities)) {
@@ -1179,77 +1256,4 @@ function registration_field_extra_fields() {
   }
 
   return $extra;
-}
-
-/**
- * Return all registration state entities.
- *
- * @param bool $active
- * @param bool $show_on_form
- *
- * @return array
- *   An array of registration state entities.
- */
-function registration_states($conditions = array()) {
-  $states = &drupal_static(__FUNCTION__ . serialize($conditions), array());
-  if (!empty($states)) {
-    return $states;
-  }
-
-  $entity_type = 'registration_state';
-  $query = new EntityFieldQuery();
-  $query
-    ->entityCondition('entity_type', $entity_type)
-    ->propertyOrderBy('weight', 'ASC');
-
-  foreach ($conditions as $col => $val) {
-    $query->propertyCondition($col, $val);
-  }
-
-  if ($results = $query->execute()) {
-    $states = entity_load($entity_type, array_keys($results[$entity_type]));
-  }
-
-  return $states;
-}
-
-/**
- * Return an array of all active state IDs.
- *
- * @return array
- */
-function registration_get_active_states() {
-  $active = array();
-  $states = registration_states(array('active' => TRUE));
-  foreach ($states as $state) {
-    $active[] = $state->internalIdentifier();
-  }
-  return $active;
-}
-
-/**
- * Return default state
- *
- * @return array
- */
-function registration_get_default_state() {
-  $default = '';
-  $states = registration_states();
-  foreach ($states as $state) {
-    if ($state->default_state) {
-      $default = $state;
-    }
-  }
-  return $default;
-}
-
-/**
- * Gets an array of all registration states, keyed by the name.
- *
- * @param $name
- *   If set, the type with the given name is returned.
- */
-function registration_get_states($name = NULL) {
-  $types = entity_load_multiple_by_name('registration_state', isset($name) ? array($name) : FALSE);
-  return isset($name) ? reset($types) : $types;
-}
+}
\ No newline at end of file
diff --git a/registration.test b/registration.test
index e6f03b0..8c219c3 100644
--- a/registration.test
+++ b/registration.test
@@ -431,7 +431,7 @@ class RegistrationStandardTestCase extends RegistrationTestCase {
     $this->drupalGet('registration/' . $registration_b->registration_id);
     $this->assertResponse(200, t('User with permission can view registration'), 'Registration');
 
-    $this->assertTrue(registration_event_count($this->host_entity_type, $this->host_entity_id) == 2, t('Get slots filled for a host entity.'), 'Registration');
+    $this->assertTrue(registration_event_count($this->host_entity_type, $this->host_entity_id, TRUE) == 2, t('Get slots filled for a host entity.'), 'Registration');
     $this->assertFalse(registration_has_room($this->host_entity_type, $this->host_entity_id), t('No slots available'), 'Registration');
 
     // Test registered users
