diff --git a/multistep.admin.inc b/multistep.admin.inc
index ea310b4..24e607c 100644
--- a/multistep.admin.inc
+++ b/multistep.admin.inc
@@ -67,8 +67,8 @@ function multistep_admin_settings_workflow_form($form, &$form_state) {
     '#weight' => -6,
   );
   return system_settings_form($form);
-}  
-  
+}
+
 /**
  * Form used for changing multistep form labels.
  */
@@ -114,19 +114,22 @@ function multistep_admin_settings_design_form($form, &$form_state) {
 function multistep_admin_settings_reset_form($form, &$form_state) {
   $form = array();
   $form['#description'] = t('This form will reset all the step data for the selected content type. Use this if you just enabled multistep for a content type that already contained nodes.') . '<br /><strong>' . t('Warning! Resetting the tables for a content type that already had multistep enabled could result in the loss of the step data!') . '</strong>';
-  $options = array('' => '- Select -');
-  foreach (node_type_get_types() as $type) {
-    if (is_multistep($type)) {
-      $options[$type->type] = $type->name;
-    }
-  }
-  $form['multistep_type'] = array(
+
+  $entity_info = entity_get_info();
+  $form['multistep_entity_type'] = array(
     '#type' => 'select',
-    '#title' => t('Content type'),
-    '#options' => $options,
+    '#title' => t('Entity type'),
+    '#options' => array_combine(array_keys($entity_info), array_keys($entity_info)),
+    '#default_value' => 'node',
     '#required' => TRUE,
-    '#weight' => -1,
+    '#weight' => -2,
+    '#ajax' => array(
+      'wrapper' => 'multistep_bundles',
+      'callback' => 'multistep_admin_settings_reset_form_ajax',
+    ),
   );
+  // Apply AJAX callback on initial load
+  $form['multistep_type'] = multistep_admin_settings_reset_form_ajax($form, $form_state);
   // Show reset button if multistep is enabled for this content type.
   $form['multistep_reset'] = array(
     '#type' => 'submit',
@@ -137,10 +140,31 @@ function multistep_admin_settings_reset_form($form, &$form_state) {
   return $form;
 }
 
+function multistep_admin_settings_reset_form_ajax($form, &$form_state) {
+  $entity_type = isset($form_state['values']['multistep_entity_type']) ? $form_state['values']['multistep_entity_type'] : 'node';
+  $options = array('' => '- Select -');
+  $info = entity_get_info($entity_type);
+  foreach ($info['bundles'] as $type => $bundle_info) {
+    if (is_multistep($type, $entity_type)) {
+      $options[$type] = $bundle_info['label'];
+    }
+  }
+  $form['multistep_type'] = array(
+    '#type' => 'select',
+    '#title' => t('Content type'),
+    '#options' => $options,
+    '#required' => TRUE,
+    '#weight' => -1,
+    '#prefix' => '<div id="multistep_bundles">',
+    '#suffix' => '</div>',
+  );
+  return $form['multistep_type'];
+}
+
 /**
  * Resets the multistep table data for the selected content type.
  */
 function multistep_admin_settings_reset_form_submit($form, &$form_state) {
-  _multistep_reset_data($form_state['values']['multistep_type']);
+  _multistep_reset_data($form_state['values']['multistep_type'], $form_state['values']['multistep_entity_type']);
   drupal_set_message(t('Data was reset successfully.'));
 }
diff --git a/multistep.install b/multistep.install
index f826596..ae18a04 100644
--- a/multistep.install
+++ b/multistep.install
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * 
+ *
  */
 
 /**
@@ -27,12 +27,19 @@ function multistep_schema() {
   $schema['multistep'] = array(
     'description' => 'Keeps track of submitted steps in multistep forms.',
     'fields' => array(
-      'nid' => array(
+      'id' => array(
         'type' => 'int',
         'unsigned' => TRUE,
         'not null' => TRUE,
         'default' => 0,
-        'description' => 'The primary identifier for a node.'
+        'description' => 'The primary identifier for an entity.'
+      ),
+      'entity_type' => array(
+        'type' => 'varchar',
+        'length' => 64,
+        'not null' => TRUE,
+        'default' => '',
+        'description' => 'The entity type.'
       ),
       'step' => array(
         'type' => 'varchar',
@@ -49,9 +56,9 @@ function multistep_schema() {
         'description' => 'The status of the step.'
       ),
     ),
-    'primary key' => array('nid', 'step'),
+    'primary key' => array('id', 'entity_type', 'step'),
     'indexes' => array(
-      'multistep_nid_step' => array('nid', 'step'),
+      'multistep_id_type_step' => array('id', 'entity_type', 'step'),
       'multistep_status' => array(array('status', 1)),
     ),
   );
@@ -79,19 +86,21 @@ function multistep_disable() {
  */
 function multistep_uninstall() {
   // Remove variables created by the module.
-  $node_types = node_type_get_types();
-  foreach ($node_types as $node_type) {
-    variable_del('multistep_expose_' . $node_type->type);
-    variable_del('multistep_menu_' . $node_type->type);
-    variable_del('multistep_progress_' . $node_type->type);
-    variable_del('multistep_steps_' . $node_type->type);
-    variable_del('multistep_buttons_' . $node_type->type);
-    variable_del('multistep_default_' . $node_type->type);
-    /*
-    * @todo Verify how Field API handles extra fields
-    foreach ($node_type['extra'] as $extra_field) {
-      variable_del('multistep_extra_' . $extra_field . '_' . $content_type['type']);
-    }*/
+  $info = entity_get_info();
+  foreach ($info as $entity_type => $info) {
+    foreach ($info['bundles'] as $type => $bundle_info) {
+      variable_del('multistep_expose_' . $entity_type . '_' . $type);
+      variable_del('multistep_menu_' . $entity_type . '_' . $type);
+      variable_del('multistep_progress_' . $entity_type . '_' . $type);
+      variable_del('multistep_steps_' . $entity_type . '_' . $type);
+      variable_del('multistep_buttons_' . $entity_type . '_' . $type);
+      variable_del('multistep_default_' . $entity_type . '_' . $type);
+      /*
+      * @todo Verify how Field API handles extra fields
+      foreach ($node_type['extra'] as $extra_field) {
+        variable_del('multistep_extra_' . $extra_field . '_' . $content_type['type']);
+      }*/
+    }
   }
   variable_del('multistep_status_revisions');
   variable_del('multistep_status_publishing');
@@ -110,7 +119,7 @@ function multistep_uninstall() {
 function multistep_update_6100(&$sandbox) {
   $schema['multistep'] = array(
     'fields' => array(
-      'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'description' => 'The primary identifier for a node.'),
+      'id' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'description' => 'The primary identifier for an entity.'),
       'step' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'description' => 'A particular step of the nid.'),
       'status' => array('type' => 'varchar', 'length' => 12, 'not null' => TRUE, 'default' => '', 'description' => 'The status of the step.'),
     ),
diff --git a/multistep.module b/multistep.module
index cdd72f2..70bdcb5 100644
--- a/multistep.module
+++ b/multistep.module
@@ -3,7 +3,7 @@
 /**
  * @file
  * The Multistep module adds multiple-step functionality to content types.
- * 
+ *
  * @todo Change the step argument so that it's passed in a different REQUEST variable.
  * @todo Calculate (and store) the number of Form steps per form.
  */
@@ -155,21 +155,26 @@ function multistep_block_save($delta = '', $edit = array()) {
 /**
  * Implements hook_block_view().
  */
-function multistep_block_view($type = '') {
-  if (!is_multistep($type)) return;
+function multistep_block_view($type = '', $entity_type = 'node') {
+  if (!is_multistep($type, $entity_type)) return;
 
   $router_item = menu_get_item();
-  $page_callback = $router_item['page_callback']; 
-  
+  $page_callback = $router_item['page_callback'];
+
   if ($page_callback == 'node_page_edit') {
-    $node = menu_get_object();
-    if ($node->type != $type) return;
-    $nid = $node->nid;
+    $entity = menu_get_object();
+    if ($entity->type != $type) return;
+    $id = $entity->nid;
   } elseif($page_callback == 'node_add') {
     if ($router_item['page_arguments'][0] != $type) return;
-    $nid = 0;
+    $id = 0;
+  } elseif ($page_callback == 'entity_ui_get_form') {
+    // TODO set $id etc
+    $entity = menu_get_object();
+    $wrapper = entity_metadata_wrapper($entity_type, $entity);
+    $id = $wrapper->getIdentifier();
   } else return;
-  
+
   $content = array();
   // Display block body.
   if (variable_get('multistep_body_' . $type, '') != '') {
@@ -178,12 +183,12 @@ function multistep_block_view($type = '') {
     );
   }
   // Get step information
-  $current_step = multistep_get_step($type);
-  $groups = multistep_get_steps($type);
+  $current_step = multistep_get_step($type, $entity_type);
+  $groups = multistep_get_steps($type, $entity_type);
   // Get design variables
   $workflow_mode = variable_get('multistep_workflow_mode', 'free');
   // Generate the menu items.
-  if (variable_get('multistep_menu_' . $type, 1)) {
+  if (variable_get('multistep_menu_' . $entity_type . '_' . $type, 1)) {
     $data = array();
     $content['multistep_block_navigation'] = array(
       '#theme' => 'multistep_navigation',
@@ -191,14 +196,14 @@ function multistep_block_view($type = '') {
     );
     foreach ($groups as $group) {
       // Highlight unsubmitted steps.
-      $status = _multistep_get_status($nid, $group->group_name);
+      $status = _multistep_get_status($id, $group->group_name, $entity_type);
       $content['multistep_block_navigation']['#children'][$group->weight . $group->group_name] = array(
-        'id' => 'multistep-' . $type . '-' . $group->group_name,
+        'id' => 'multistep-' . $entity_type . '-' . $type . '-' . $group->group_name,
         'class' => array(
           is_null($status) || $status == '' ? '' : 'multistep-' . $status,
           $current_step == $group->group_name ? 'active': '',
         ),
-        'url' => $nid && ($workflow_mode == 'free' || ($workflow_mode == 'direct' && ($status == 'submitted' || multistep_get_next($type, $last_submitted_step) == $group->group_name))) ? $_GET['q'] : NULL,
+        'url' => $id && ($workflow_mode == 'free' || ($workflow_mode == 'direct' && ($status == 'submitted' || multistep_get_next($type, $last_submitted_step) == $group->group_name))) ? $_GET['q'] : NULL,
         'step' => $group->group_name,
         'label' => $group->label,
         'next_unsubmitted_step' => FALSE,
@@ -214,11 +219,11 @@ function multistep_block_view($type = '') {
     }
   }
   // Generate the progress bar.
-  if (variable_get('multistep_progress_' . $type, 1)) {
+  if (variable_get('multistep_progress_' . $entity_type . '_' . $type, 1)) {
     if ($steps = count($groups)) {
       $submitted = 0;
       foreach ($groups as $group) {
-        $status = _multistep_get_status($nid, $group->group_name);
+        $status = _multistep_get_status($id, $group->group_name, $entity_type);
         // Count how many steps have been submitted.
         if ($status == 'submitted') {
           $submitted++;
@@ -230,10 +235,10 @@ function multistep_block_view($type = '') {
       );
     }
   }
-  $node_type = node_type_load($type);
+  // TODO: get pretty name for entity bundle
   drupal_add_css(drupal_get_path('module', 'multistep') . '/multistep.css');
   return array(
-    'subject' => $node_type->name . ' menu',
+    'subject' => $type . ' menu',
     'content' => $content,
   );
 }
@@ -292,32 +297,52 @@ function multistep_field_group_pre_render(&$element, $group, &$form) {
 }
 
 /**
- * Implements hook_node_insert().
- * Generate the step list for this node in the database.
+ * Implements hook_entity_insert().
+ * Generate the step list for this entity in the database.
  */
-function multistep_node_insert($node) {
-  if (is_multistep($node)) {
-    _multistep_update_status($node->nid, 'unsubmitted');
+function multistep_entity_insert($entity, $entity_type = 'node') {
+  if (is_multistep($entity, $entity_type)) {
+    $wrapper = entity_metadata_wrapper($entity_type, $entity);
+    _multistep_update_status($wrapper->getIdentifier(), 'unsubmitted', $entity_type);
   }
 }
 
 /**
- * Implements hook_node_delete().
- * Remove the step list for this node in the database.
+ * Implements hook_entity_delete().
+ * Remove the step list for this entity in the database.
  */
-function multistep_node_delete($node) {
-  if (is_multistep($node)) {
+function multistep_entity_delete($entity, $entity_type = 'node') {
+  if (is_multistep($entity, $entity_type)) {
+    $wrapper = entity_metadata_wrapper($entity_type, $entity);
     db_delete('multistep')
-      ->condition('nid', $node->nid)
+      ->condition('id', $wrapper->getIdentifier())
+      ->condition('entity_type', $entity_type)
       ->execute();
   }
 }
 
 /**
- * Implements hook_field_attach_form().
+ * Implements hook_form_alter().
  */
-function multistep_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode = NULL) {
-  if (!($entity_type == 'node') || !is_multistep($entity)) {
+function multistep_form_alter(&$form, &$form_state, $form_id) {
+  // Is this an entity add/edit form?
+  if (isset($form['#entity_type']) && isset($form['#bundle']) && isset($form['#entity'])) {
+    $entity_type = $form['#entity_type'];
+    $entity = $form['#entity'];
+    // Is it enough to assume that this is the add/edit form for
+    // this entity type if those keys are set?
+
+    // Carry out what used to be multistep_field_attach_form
+    multistep_field_attach_form_callback($entity_type, $entity, $form, $form_state);
+  }
+}
+
+/**
+ * Helper to attach multistep form actions etc.
+ * Used to implement hook_field_attach_form, now done on hook_form_alter instead
+ */
+function multistep_field_attach_form_callback($entity_type, $entity, &$form, &$form_state, $langcode = NULL) {
+  if (!is_multistep($entity, $entity_type)) {
     return;
   }
   /* Disable immediate redirection through "destination" parameter, but preserve the destination value.
@@ -338,18 +363,21 @@ function multistep_field_attach_form($entity_type, $entity, &$form, &$form_state
   if (module_exists('content_profile') && is_content_profile($type)) {
     unset($form['#redirect']);
   }*/
-  $step = multistep_get_step($entity);
+  $step = multistep_get_step($entity, $entity_type);
   $form['#multistep'] = array(
-    'previous' => multistep_get_previous($entity, $step),
+    'previous' => multistep_get_previous($entity, $step, $entity_type),
     'current' => $step,
-    'next' => multistep_get_next($entity, $step),
+    'next' => multistep_get_next($entity, $step, $entity_type),
   );
+
   // This adds different submitting buttons (Previous, Save, Next, Done).
-  if ($step != multistep_get_first($entity)) {
+  // TODO is this submit fn OK?
+  $submit_fn = isset($form['#submit']) ? $form['#submit'][0] : $form['#form_id'] . '_submit';
+  if ($step != multistep_get_first($entity, $entity_type)) {
     $form['actions']['previous'] = array(
       '#type' => 'submit',
       '#value' => variable_get('multistep_button_prev', t('< Previous')),
-      '#submit' => array('node_form_submit', 'multistep_submit'),
+      '#submit' => array($submit_fn, 'multistep_submit'),
       '#weight' => -999,
       '#access' => variable_get('multistep_button_prev', TRUE),
     );
@@ -357,15 +385,15 @@ function multistep_field_attach_form($entity_type, $entity, &$form, &$form_state
   $form['actions']['save'] = array(
     '#type' => 'submit',
     '#value' => variable_get('multistep_button_save', t('Save')),
-    '#submit' => array('node_form_submit', 'multistep_submit'),
+    '#submit' => array($submit_fn, 'multistep_submit'),
     '#weight' => 0,
     '#access' => variable_get('multistep_button_save', TRUE),
   );
-  if ($step != multistep_get_last($entity)) {
+  if ($step != multistep_get_last($entity, $entity_type)) {
     $form['actions']['next'] = array(
       '#type' => 'submit',
       '#value' => variable_get('multistep_button_next', t('Next >')),
-      '#submit' => array('node_form_submit', 'multistep_submit'),
+      '#submit' => array($submit_fn, 'multistep_submit'),
       '#weight' => 999,
     );
   }
@@ -373,7 +401,7 @@ function multistep_field_attach_form($entity_type, $entity, &$form, &$form_state
     $form['actions']['done'] = array(
       '#type' => 'submit',
       '#value' => variable_get('multistep_button_done', t('Done')),
-      '#submit' => array('node_form_submit', 'multistep_submit'),
+      '#submit' => array($submit_fn, 'multistep_submit'),
       '#weight' => 999,
     );
   }
@@ -389,8 +417,9 @@ function multistep_field_attach_form($entity_type, $entity, &$form, &$form_state
  * Implements hook_node_validate().
  * Set proper revisioning and publishing.
  */
+ // TODO: support all entity types
 function multistep_node_validate($node, $form, &$form_state) {
-  if (!is_multistep($node)) {
+  if (!is_multistep($node, 'node')) {
     return;
   }
   /*if ($form['revision_information']['revision']['#value']) {
@@ -409,11 +438,14 @@ function multistep_node_validate($node, $form, &$form_state) {
  * Submit the form and redirect to the next appropriate step.
  */
 function multistep_submit($form, &$form_state) {
-  $nid = $form_state['nid'];
+  $entity = $form_state['build_info']['args'][0];
+  $entity_type = $form_state['complete form']['#entity_type'];
+  $wrapper = entity_metadata_wrapper($entity_type, $entity);
+  $id = $wrapper->getIdentifier();
   // Update the step list for this node in the database
   $current_step = $form['#multistep']['current'];
   $status = module_invoke_all('multistep_update_status', $form_state, 'submitted', $current_step);
-  _multistep_update_status($nid, $status, $current_step);
+  _multistep_update_status($id, $status, $current_step, $entity_type);
   $step = FALSE;
   switch ($form_state['triggering_element']['#parents'][0]) {
     case 'previous':
@@ -424,14 +456,15 @@ function multistep_submit($form, &$form_state) {
       $step = $form['#multistep']['current'];
       break;
   }
+  $uri = entity_uri($entity_type, $entity);
   if ($step) {
     $query = array(
       'query' => array('step' => $step),
     );
-    $form_state['redirect'] = array('node/' . $nid . '/edit', $query);
+    $form_state['redirect'] = array($uri['path'] . '/edit', $query);
   }
   else {
-    $form_state['redirect'] = array('node/' . $nid);
+    $form_state['redirect'] = array($uri['path']);
   }
 }
 
@@ -482,13 +515,14 @@ function _multistep_publishing($complete) {
 /**
  * Get all steps as an array.
  */
-function multistep_get_steps($type) {
+function multistep_get_steps($type, $entity_type = 'node') {
   $multistep = &drupal_static(__FUNCTION__);
   if (is_object($type)) {
-    $type = $type->type;
+    $wrapper = entity_metadata_wrapper($entity_type, $type);
+    $type = $wrapper->getBundle();
   }
-  if (!isset($multistep[$type])) {
-    $groups = field_group_info_groups('node', $type, 'form');
+  if (!isset($multistep[$entity_type]) || !isset($multistep[$entity_type][$type])) {
+    $groups = field_group_info_groups($entity_type, $type, 'form');
     $steps = array();
     foreach ($groups as $group) {
       if ($group->format_type == 'multistep') {
@@ -496,14 +530,14 @@ function multistep_get_steps($type) {
       }
     }
     uasort($steps, '_multistep_cmp_group_weight');
-    $multistep[$type] = $steps;
+    $multistep[$entity_type][$type] = $steps;
   }
-  return $multistep[$type];
+  return $multistep[$entity_type][$type];
 }
 
 /**
  * group weight compare herper function
- * 
+ *
  * @param $a
  * @param $b
  * @return int weight difference
@@ -514,8 +548,8 @@ function _multistep_cmp_group_weight($a, $b) {
 /**
  * Determine if a given node is a multistep form.
  */
-function is_multistep($type) {
-  $steps = multistep_get_steps($type);
+function is_multistep($type, $entity_type = 'node') {
+  $steps = multistep_get_steps($type, $entity_type);
   return !empty($steps);
 }
 
@@ -528,20 +562,21 @@ function is_multistep($type) {
  * @todo Add support for toggling the multistep/one-page form.
  * @todo If no step is specified, return the next unsubmitted step (if that option is enabled).
  */
-function multistep_get_step($type) {
+function multistep_get_step($type, $entity_type = 'node') {
   // If the step is passed through the request, return that one
   if (isset($_REQUEST['step'])) {
     return $_REQUEST['step'];
   }
   if (is_object($type)) {
-    $type = $type->type;
+    $wrapper = entity_metadata_wrapper($entity_type, $type);
+    $type = $wrapper->getBundle();
   }
   // @see http://drupal.org/node/566682 - Added support for hierarchical_select
   if (arg(0) == 'hierarchical_select_json') {
     $hsid = $_POST['hsid'];
     foreach ($_POST['taxonomy'] as $vid => $config) {
       if ($config['hsid'] == $hsid) {
-        return variable_get('multistep_extra_taxonomy_' . $vid . '_' . $type, $step);
+        return variable_get('multistep_extra_taxonomy_' . $vid . '_' . $entity_type . '_' . $type, $step);
       }
     }
   }
@@ -551,7 +586,7 @@ function multistep_get_step($type) {
   || arg(0) == 'autocomplete_widgets') { // Autocomplete Widgets does this
     $field = arg(2);
     // Decide step based on type/field combination
-    return multistep_get_field_step($field, $type);
+    return multistep_get_field_step($field, $type, $entity_type);
   }
   // This condition occurs if using AJAX to add another value for a multi-value field
   if (arg(1) == 'js_add_more' // Add more button
@@ -569,17 +604,17 @@ function multistep_get_step($type) {
       }
     }
     // Decide step based on type/field combination
-    return multistep_get_field_step($field, $type);
+    return multistep_get_field_step($field, $type, $entity_type);
   }
   // If no step is specified, return the first one
-  return multistep_get_first($type);
+  return multistep_get_first($type, $entity_type);
 }
 
 /**
  * Gets the first step.
  */
-function multistep_get_first($type) {
-  $steps = multistep_get_steps($type);
+function multistep_get_first($type, $entity_type = 'node') {
+  $steps = multistep_get_steps($type, $entity_type);
   reset($steps);
   return key($steps);
 }
@@ -587,8 +622,8 @@ function multistep_get_first($type) {
 /**
  * Gets the step prior to the specified step.
  */
-function multistep_get_previous($type, $step) {
-  $steps = multistep_get_steps($type);
+function multistep_get_previous($type, $step, $entity_type = 'node') {
+  $steps = multistep_get_steps($type, $entity_type);
   $step_names = array_keys($steps);
   $step_index = array_search($step, $step_names);
   if($step_index === FALSE) return FALSE;
@@ -602,8 +637,8 @@ function multistep_get_previous($type, $step) {
 /**
  * Gets the step after the specified step.
  */
-function multistep_get_next($type, $step) {
-  $steps = multistep_get_steps($type);
+function multistep_get_next($type, $step, $entity_type = 'node') {
+  $steps = multistep_get_steps($type, $entity_type);
   $step_names = array_keys($steps);
   $step_index = array_search($step, $step_names);
   if($step_index === FALSE) return FALSE;
@@ -617,8 +652,8 @@ function multistep_get_next($type, $step) {
 /**
  * Gets the last step.
  */
-function multistep_get_last($type) {
-  $steps = multistep_get_steps($type);
+function multistep_get_last($type, $entity_type = 'node') {
+  $steps = multistep_get_steps($type, $entity_type);
   end($steps);
   return key($steps);
 }
@@ -628,10 +663,10 @@ function multistep_get_last($type) {
  * Determine the current step that the field should be part of in the current
  * node type.
  */
-function multistep_get_field_step($field_name, $type) {
-  $groups = multistep_get_steps($type);
+function multistep_get_field_step($field_name, $type, $entity_type = 'node') {
+  $groups = multistep_get_steps($type, $entity_type);
   // Recursively find field step
-  $groupinfo = field_group_info_groups('node', $type, 'form');
+  $groupinfo = field_group_info_groups($entity_type, $type, 'form');
   foreach ($groups as $group) {
     if ($step = multistep_get_field_step_recursive($field_name, $group->group_name, $groupinfo)) {
       return $step;
@@ -639,7 +674,7 @@ function multistep_get_field_step($field_name, $type) {
   }
   // Field does not belong to any step
   // FIXME: we should in fact throw an error or so
-  return multistep_get_first($type);
+  return multistep_get_first($type, $entity_type);
 }
 
 /**
@@ -667,44 +702,49 @@ function multistep_get_field_step_recursive($field, $group_name, $groupinfo) {
 /**
  * Implements of hook_multistep_update_status().
  */
-function multistep_multistep_update_status($form_state, $status, $step) {
+function multistep_multistep_update_status($form_state, $status, $step, $entity_type = 'node') {
   return 'submitted';
 }
 
 /**
  * Updates the multistep table with the current status of each step.
  */
-function _multistep_update_status($nid, $status, $step = 'all') {
-  if (is_object($nid)) {
-    $nid = $nid->nid;
+function _multistep_update_status($id, $status, $step = 'all', $entity_type = 'node') {
+  if (is_object($id)) {
+    $wrapper = entity_metadata_wrapper($entity_type, $id);
+    $id = $id->getIdentifier();
   }
-  elseif (empty($nid)) {
+  elseif (empty($id)) {
     return;
   }
   // When all steps are passed (or no step specified), initialize
   if ($step == 'all') {
-    $node = node_load($nid);
-    $groups = multistep_get_steps($node->type);
+    $entities = entity_load($entity_type, array($id));
+    $entity = reset($entities);
+    $wrapper = entity_metadata_wrapper($entity_type, $entity);
+    $groups = multistep_get_steps($wrapper->getBundle());
     foreach ($groups as $group) {
-      _multistep_update_status($node, $status, $group->group_name);
+      _multistep_update_status($entity, $status, $group->group_name, $entity_type);
     }
     return;
   }
   // Generate the step list for this node in the database, or set the current step.
-  if (_multistep_get_status($nid, $step)) {
+  if (_multistep_get_status($id, $step, $entity_type)) {
     db_update('multistep')
       ->fields(array(
         'status' => $status,
       ))
-      ->condition('nid', $nid)
+      ->condition('id', $id)
       ->condition('step', $step)
+      ->condition('entity_type', $entity_type)
       ->execute();
   }
   else {
     db_insert('multistep')
       ->fields(array(
-        'nid' => $nid,
+        'id' => $id,
         'step' => $step,
+        'entity_type' => $entity_type,
         'status' => $status,
       ))
       ->execute();
@@ -714,19 +754,18 @@ function _multistep_update_status($nid, $status, $step = 'all') {
 /**
  * Generate multistep data for all nodes of a given content type.
  */
-function _multistep_reset_data($type) {
+function _multistep_reset_data($type, $entity_type = 'node') {
   // Do nothing if multistep is not enabled for this node type.
-  if (!variable_get('multistep_enabled_' . $type, 0)) {
+  if (!variable_get('multistep_enabled_' . $entity_type . '_' . $type, 0)) {
     return;
   }
-  // Get all the nodes for this content type.
-  // @todo Use node_load_multiple().
-  $result = db_query('SELECT nid, status FROM {node} WHERE type = :type', array(':type' => $type));
-  foreach ($result as $node) {
-    if ($node->status == 1) {
+  // Get all the entities for this type/bundle.
+  $entities = entity_load($entity_type, array('type' => $type));
+  foreach ($entities as $id => $entity) {
+    if ($entity->status == 1) {
       $status = 'submitted';
     }
-    _multistep_update_status($node->nid, $status);
+    _multistep_update_status($id, $status, $entity_type);
   }
 }
 
@@ -734,11 +773,12 @@ function _multistep_reset_data($type) {
  * Get status of a step in a specific node.
  * if we're on node creation form and $nid == 0 return false
  */
-function _multistep_get_status($nid, $step = 'all') {
-  if(!$nid) return FALSE;
+function _multistep_get_status($id, $step = 'all', $entity_type = 'node') {
+  if(!$id) return FALSE;
   if ($step == 'all') {
-    $result = db_query('SELECT step, status FROM {multistep} WHERE nid = :nid', array(
-      ':nid' => $nid,
+    $result = db_query('SELECT step, status FROM {multistep} WHERE id = :id AND entity_type = :entity_type', array(
+      ':id' => $id,
+      ':entity_type' => $entity_type,
     ))->fetchAll();
     $status = array();
     foreach ($result as $row) {
@@ -746,8 +786,9 @@ function _multistep_get_status($nid, $step = 'all') {
     }
     return $status;
   }
-  return db_query('SELECT status FROM {multistep} WHERE nid = :nid AND step = :step', array(
-    ':nid' => $nid,
+  return db_query('SELECT status FROM {multistep} WHERE id = :id AND entity_type = :entity_type AND step = :step', array(
+    ':id' => $id,
+    ':entity_type' => $entity_type,
     ':step' => $step,
   ))->fetchField();
 }
@@ -755,9 +796,10 @@ function _multistep_get_status($nid, $step = 'all') {
 /**
  * Check to see if the node is complete.
  */
-function multistep_is_complete($node) {
+function multistep_is_complete($entity, $entity_type = 'node') {
   // Get the status of all the steps in the node
-  $status = _multistep_get_status($node->nid);
+  $wrapper = entity_metadata_wrapper($entity_type, $entity);
+  $status = _multistep_get_status($wrapper->getIdentifier(), $entity_type);
   // Look for a step that is not yet submitted
   return !in_array('unsubmitted', $status);
 }
@@ -766,14 +808,15 @@ function multistep_is_complete($node) {
  * Decide whether the current submission process will bring the form to
  * completion status, or if it's already complete.
  */
-function multistep_will_complete($node) {
-  if (multistep_is_complete($node)) {
+function multistep_will_complete($entity, $entity_type = 'node') {
+  if (multistep_is_complete($entity, $entity_type)) {
     return TRUE;
   }
   // Get the current step
-  $step = multistep_get_step($node->type);
+  $wrapper = entity_metadata_wrapper($entity_type, $entity);
+  $step = multistep_get_step($wrapper->getBundle(), $entity_type);
   // Get the status of all the steps in the node
-  $status = _multistep_get_status($node->nid);
+  $status = _multistep_get_status($wrapper->getIdentifier(), $entity_type);
   // Remove non-unsubmitted steps from the array
   foreach ($status as $key => $unsubmitted) {
     if ($unsubmitted != 'unsubmitted') {
