diff --git a/file_entity.admin.inc b/file_entity.admin.inc
index 2409e20..0789c25 100644
--- a/file_entity.admin.inc
+++ b/file_entity.admin.inc
@@ -523,14 +523,17 @@ function file_entity_multiple_delete_confirm_submit($form, &$form_state) {
  * Displays the file type admin overview page.
  */
 function file_entity_list_types_page() {
+  // Allow for ctools formatting.
+  drupal_add_css(drupal_get_path('module', 'ctools') . '/css/export-ui-list.css');
+
   $file_entity_info = entity_get_info('file');
   $field_ui = module_exists('field_ui');
   $header = array(
     array('data' => t('Name')),
-    array('data' => t('Operations'), 'colspan' => $field_ui ? '4' : '2'),
+    array('data' => t('Operations'), 'colspan' => $field_ui ? '5' : '3'),
+    array('data' => t('Status')),
   );
   $rows = array();
-
   foreach (file_type_get_all_types(TRUE) as $type) {
     $row = array(array('data' => theme('file_entity_file_type_overview', array('label' => $type->label, 'description' => $type->description))));
     $path = isset($file_entity_info['bundles'][$type->type]['admin']['real path']) ? $file_entity_info['bundles'][$type->type]['admin']['real path'] : NULL;
@@ -542,9 +545,54 @@ function file_entity_list_types_page() {
     }
     $row[] = array('data' => isset($path) ? l(t('manage file display'), $path . '/file-display') : '');
 
-    $rows[] = $row;
+    // @TODO when the type is disabled there is no usable path. Not sure
+    // what is the correct approach here.
+    $admin_path = 'admin/structure/file-types/manage/' . $type->type;
+    switch ($type->ctools_type) {
+      // Configuration is in code.
+      case 'Default':
+        if (!empty($type->disabled)) {
+          $row[] = l(t('enable'), $admin_path . '/enable');
+        }
+        else {
+          $row[] = l(t('disable'), $admin_path . '/disable');
+        }
+      break;
+
+      // Configuration is in DB.
+      case 'Normal':
+        if (!empty($type->disabled)) {
+          $status = l(t('enable'), $admin_path . '/enable');
+        }
+        else {
+          $status = l(t('disable'), $admin_path . '/disable');
+        }
+        $row[] = $status . ' | ' . l(t('delete'), $admin_path . '/delete');
+      break;
+
+      // Configuration is in code, but overridden in DB.
+      case 'Overridden':
+        if (!empty($type->disabled)) {
+          $row[] = l(t('enable'), $admin_path . '/enable');
+        }
+        else {
+          $row[] = l(t('disable'), $admin_path . '/disable') . ' | ' . l(t('revert'), $admin_path . '/revert');
+        }
+      break;
+    }
+
+    // Show the type status.
+    $row[] = !empty($type->disabled) ? t('Disabled') : $type->ctools_type;
+    // Format the row with the status.
+    $rows[] = array('data' => $row, 'class' => array((!empty($type->disabled) ? 'ctools-export-ui-disabled' : '')));
   }
 
+  // Move disabled items to the bottom.
+  $disabled = array_filter($rows, function($row) {return in_array('ctools-export-ui-disabled', $row['class']);});
+  $rows = array_diff_key($rows, $disabled);
+  $rows += $disabled;
+  $rows = array_values($rows);
+
   $build['file_type_table'] = array(
     '#theme' => 'table',
     '#header' => $header,
@@ -710,8 +758,18 @@ function theme_file_entity_file_display_order($variables) {
  * @see file_entity_file_type_form_validate()
  * @see file_entity_file_type_form_submit()
  */
-function file_entity_file_type_form($form, &$form_state, $type) {
-  $form['#file_type'] = $type->type;
+function file_entity_file_type_form($form, &$form_state, $type = NULL) {
+  if (!isset($type->type)) {
+    // This is a new type.
+    $type = (object) array(
+      'type' => '',
+      'label' => '',
+      'description' => '',
+      'streams' => array(),
+      'mimetypes' => array(),
+    );
+  }
+  $form['#file_type'] = $type;
 
   $form['label'] = array(
     '#type' => 'textfield',
@@ -720,6 +778,19 @@ function file_entity_file_type_form($form, &$form_state, $type) {
     '#required' => TRUE,
     '#default_value' => $type->label,
   );
+
+  $form['type'] = array(
+    '#type' => 'machine_name',
+    '#default_value' => $type->type,
+    '#maxlength' => 255,
+    '#disabled' => (bool) $type->type,
+    '#machine_name' => array(
+      'exists' => 'file_type_load',
+      'source' => array('label'),
+    ),
+    '#description' => t('A unique machine-readable name for this file type. It must only contain lowercase letters, numbers, and underscores.'),
+  );
+
   $form['description'] = array(
     '#type' => 'textarea',
     '#title' => t('Description'),
@@ -767,10 +838,18 @@ function file_entity_file_type_form($form, &$form_state, $type) {
     '#default_value' => $default_value,
   );
 
-  $form['submit'] = array(
+  $form['actions'] = array('#type' => 'actions');
+
+  $form['actions']['submit'] = array(
     '#type' => 'submit',
     '#value' => t('Save'),
   );
+  if (!empty($type->type)) {
+    $form['actions']['delete'] = array(
+      '#type' => 'submit',
+      '#value' => t('Delete'),
+    );
+  }
 
   return $form;
 }
@@ -799,8 +878,18 @@ function file_entity_file_type_form_validate($form, &$form_state) {
  * @see file_entity_file_type_form_validate()
  */
 function file_entity_file_type_form_submit($form, &$form_state) {
-  $type = file_type_load($form['#file_type']);
-
+  if (!empty($form['#file_type']->type)) {
+    $type = file_type_load($form['#file_type']->type);
+  }
+  else {
+    $type = (object) array(
+      'type' => $form_state['values']['type'],
+    );
+  }
+  if ($form_state['values']['op'] == t('Delete')) {
+    $form_state['redirect'] = 'admin/structure/file-types/manage/' . $type->type . '/delete';
+    return;
+  }
   $type->label = $form_state['values']['label'];
   $type->description = $form_state['values']['description'];
   $type->mimetypes = array_filter(array_map('trim', explode("\n", $form_state['values']['mimetypes'])));
@@ -816,3 +905,124 @@ function file_entity_file_type_form_submit($form, &$form_state) {
   drupal_set_message(t('The file type %type has been updated.', array('%type' => $type->label)));
   $form_state['redirect'] = 'admin/structure/file-types';
 }
+
+
+/**
+ * Menu callback; disable a single file type.
+ */
+function file_entity_type_enable_confirm($form, &$form_state, $type) {
+  $form['type'] = array('#type' => 'value', '#value' => $type->type);
+  $form['label'] = array('#type' => 'value', '#value' => $type->label);
+  $message = t('Are you sure you want to enable the file type %type?', array('%type' => $type->label));
+  return confirm_form($form, $message, 'admin/structure/file-types', '', t('Enable'));
+}
+
+
+/**
+ * Process file type disable confirm submissions.
+ */
+function file_entity_type_enable_confirm_submit($form, &$form_state) {
+  file_type_enable($form_state['values']['type']);
+  $t_args = array('%label' => $form_state['values']['label']);
+  drupal_set_message(t('The file type %label has been enabled.', $t_args));
+  watchdog('file_entity', 'Enabled file type %label.', $t_args, WATCHDOG_NOTICE);
+  $form_state['redirect'] = 'admin/structure/file-types';
+  return;
+}
+
+
+/**
+ * Menu callback; disable a single file type.
+ */
+function file_entity_type_disable_confirm($form, &$form_state, $type) {
+  $form['type'] = array('#type' => 'value', '#value' => $type->type);
+  $form['label'] = array('#type' => 'value', '#value' => $type->label);
+
+  $message = t('Are you sure you want to disable the file type %type?', array('%type' => $type->label));
+  $caption = '';
+
+  $num_files = db_query("SELECT COUNT(*) FROM {file_managed} WHERE type = :type", array(':type' => $type->type))->fetchField();
+  if ($num_files) {
+    $caption .= '<p>' . format_plural($num_files, '%type is used by 1 file on
+      your site. If you disable this file type, you will not be able to edit
+      the %type file and it may not display correctly.', '%type is used by
+      @count files on your site. If you remove %type, you will not be able to
+      edit the %type file and it may not display correctly.',
+    array('%type' => $type->label)) . '</p>';
+  }
+
+  return confirm_form($form, $message, 'admin/structure/file-types', $caption, t('Disable'));
+}
+
+
+/**
+ * Process file type disable confirm submissions.
+ */
+function file_entity_type_disable_confirm_submit($form, &$form_state) {
+  file_type_disable($form_state['values']['type']);
+  $t_args = array('%label' => $form_state['values']['label']);
+  drupal_set_message(t('The file type %label has been disabled.', $t_args));
+  watchdog('file_entity', 'Disabled file type %label.', $t_args, WATCHDOG_NOTICE);
+  $form_state['redirect'] = 'admin/structure/file-types';
+  return;
+}
+
+
+/**
+ * Menu callback; revert a single file type.
+ */
+function file_entity_type_revert_confirm($form, &$form_state, $type) {
+  $form['type'] = array('#type' => 'value', '#value' => $type->type);
+  $form['label'] = array('#type' => 'value', '#value' => $type->label);
+  $message = t('Are you sure you want to revert the file type %type?', array('%type' => $type->label));
+  return confirm_form($form, $message, 'admin/structure/file-types', '', t('Revert'));
+}
+
+
+/**
+ * Process file type delete confirm submissions.
+ */
+function file_entity_type_revert_confirm_submit($form, &$form_state) {
+  // @NOTE deleting the file_type from the DB actually reverts it to code.
+  file_type_delete($form_state['values']['type']);
+  $t_args = array('%label' => $form_state['values']['label']);
+  drupal_set_message(t('The file type %label has been reverted.', $t_args));
+  watchdog('file_entity', 'Reverted file type %label.', $t_args, WATCHDOG_NOTICE);
+  $form_state['redirect'] = 'admin/structure/file-types';
+  return;
+}
+
+
+/**
+ * Menu callback; delete a single file type.
+ */
+function file_entity_type_delete_confirm($form, &$form_state, $type) {
+  $form['type'] = array('#type' => 'value', '#value' => $type->type);
+  $form['label'] = array('#type' => 'value', '#value' => $type->label);
+
+  $message = t('Are you sure you want to delete the file type %type?', array('%type' => $type->label));
+  $caption = '';
+
+  $num_files = db_query("SELECT COUNT(*) FROM {file_managed} WHERE type = :type", array(':type' => $type->type))->fetchField();
+  if ($num_files) {
+    $caption .= '<p>' . format_plural($num_files, '%type is used by 1 file on your site. If you remove this file type, you will not be able to edit the %type file and it may not display correctly.', '%type is used by @count pieces of file on your site. If you remove %type, you will not be able to edit the %type file and it may not display correctly.', array('%type' => $type->label)) . '</p>';
+  }
+
+  $caption .= '<p>' . t('This action cannot be undone.') . '</p>';
+
+  return confirm_form($form, $message, 'admin/structure/file-types', $caption, t('Delete'));
+}
+
+/**
+ * Process file type delete confirm submissions.
+ */
+function file_entity_type_delete_confirm_submit($form, &$form_state) {
+  file_type_delete($form_state['values']['type']);
+
+  $t_args = array('%label' => $form_state['values']['label']);
+  drupal_set_message(t('The file type %label has been deleted.', $t_args));
+  watchdog('file_entity', 'Deleted file type %label.', $t_args, WATCHDOG_NOTICE);
+
+  $form_state['redirect'] = 'admin/structure/file-types';
+  return;
+}
diff --git a/file_entity.file_api.inc b/file_entity.file_api.inc
index cfe3454..1f089a9 100644
--- a/file_entity.file_api.inc
+++ b/file_entity.file_api.inc
@@ -585,6 +585,11 @@ function file_type_delete($type) {
     ->condition('type', $type->type)
     ->execute();
 
+  // Remove this type from CToolS status variable.
+  $status = variable_get('default_file_type', array());
+  unset($status[$type->type]);
+  variable_set('default_file_type', $status);
+
   file_info_cache_clear();
 
   // After deleting from the database, check if the type still exists as a
@@ -596,6 +601,29 @@ function file_type_delete($type) {
   }
 }
 
+
+/**
+ * Enable a file type.
+ *
+ * @param string $type
+ *   Type of the file_type to disable
+ */
+function file_type_enable($type) {
+  ctools_export_crud_enable('file_type', $type);
+}
+
+
+/**
+ * Disable a file type.
+ *
+ * @param string $type
+ *   Type of the file_type to disable
+ */
+function file_type_disable($type) {
+  ctools_export_crud_disable('file_type', $type);
+}
+
+
 /**
  * Determines file type for a given file.
  *
diff --git a/file_entity.module b/file_entity.module
index 62cfb0d..28d4fab 100644
--- a/file_entity.module
+++ b/file_entity.module
@@ -111,10 +111,46 @@ function file_entity_menu() {
     'access arguments' => array('administer file types'),
     'file' => 'file_entity.admin.inc',
   );
+  $items['admin/structure/file-types/add'] = array(
+    'title' => 'Add file type',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('file_entity_file_type_form'),
+    'access arguments' => array('administer file types'),
+    'type' => MENU_LOCAL_ACTION,
+    'file' => 'file_entity.admin.inc',
+  );
   $items['admin/structure/file-types/manage/%file_type'] = array(
     'title' => 'Manage file types',
     'description' => 'Manage settings for the type of files used on your site.',
   );
+  $items['admin/structure/file-types/manage/%file_type/enable'] = array(
+    'title' => 'Enable file type',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('file_entity_type_enable_confirm', 4),
+    'access arguments' => array('administer file types'),
+    'file' => 'file_entity.admin.inc',
+  );
+  $items['admin/structure/file-types/manage/%file_type/disable'] = array(
+    'title' => 'Disable file type',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('file_entity_type_disable_confirm', 4),
+    'access arguments' => array('administer file types'),
+    'file' => 'file_entity.admin.inc',
+  );
+  $items['admin/structure/file-types/manage/%file_type/revert'] = array(
+    'title' => 'Revert a file type',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('file_entity_type_revert_confirm', 4),
+    'access arguments' => array('administer file types'),
+    'file' => 'file_entity.admin.inc',
+  );
+  $items['admin/structure/file-types/manage/%file_type/delete'] = array(
+    'title' => 'Delete file type',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('file_entity_type_delete_confirm', 4),
+    'access arguments' => array('administer file types'),
+    'file' => 'file_entity.admin.inc',
+  );
   $items['admin/content/file'] = array(
     'title' => 'Files',
     'description' => 'Manage files used on your site.',
diff --git a/tests/file_entity.test b/tests/file_entity.test
index 7b1f8df..5592409 100644
--- a/tests/file_entity.test
+++ b/tests/file_entity.test
@@ -812,6 +812,99 @@ class FileEntityTypeTestCase extends FileEntityTestHelper {
     $this->assertRaw(t('!type %name was uploaded.', array('!type' => 'Image', '%name' => $file->filename)), t('Image file uploaded.'));
     $this->assertText($field['field_name'], 'File text field was found.');
   }
+
+  /**
+   * Test file types CRUD UI.
+   */
+  function testTypesCrudUi() {
+    $this->drupalGet('admin/structure/file-types');
+    $this->assertResponse(403, 'File types UI page is not accessible to unauthorized users.');
+
+    $user = $this->drupalCreateUser(array('administer file types'));
+    $this->drupalLogin($user);
+
+    $this->drupalGet('admin/structure/file-types');
+    $this->assertResponse(200, 'File types UI page is accessible to users with adequate permission.');
+
+    // Create new file type.
+    $edit = array(
+      'label' => t('Test type'),
+      'type' => 'test_type',
+      'description' => t('This is dummy file type used just for testing.'),
+      'mimetypes' => 'image/png',
+      'streams[public]' => TRUE,
+    );
+    $this->drupalGet('admin/structure/file-types/add');
+    $this->drupalPost(NULL, $edit, t('Save'));
+    $this->assertText(t('The file type @type has been updated.', array('@type' => $edit['label'])), 'New file type successfully created.');
+    $this->assertText($edit['label'], 'New file type created: label found.');
+    $this->assertText($edit['description'], 'New file type created: description found.');
+    $this->assertFieldByXPath("//table//tr[1]//td[7]", t('Normal'), 'Newly created file type is stored in DB.');
+    $this->assertLink(t('disable'), 0, 'Able to disable newly created file type.');
+    $this->assertLink(t('delete'), 0, 'Able to delete newly created file type.');
+    $this->assertLinkByHref('admin/structure/file-types/manage/' . $edit['type'] . '/disable', 0, 'Disable link points to disable confirmation page.');
+    $this->assertLinkByHref('admin/structure/file-types/manage/' . $edit['type'] . '/delete', 0, 'Delete link points to delete confirmation page.');
+
+    // Edit file type.
+    $this->drupalGet('admin/structure/file-types/manage/' . $edit['type'] . '/edit');
+    $this->assertRaw(t('Save'), 'Save button found on edit page.');
+    $this->assertRaw(t('Delete'), 'Delete button found on edit page.');
+    $this->assertRaw($edit['label'], 'Label found on file type edit page');
+    $this->assertText($edit['description'], 'Description found on file type edit page');
+    $this->assertText($edit['mimetypes'], 'Mime-type configuration found on file type edit page');
+    $this->assertText(t('Mimetype List'), 'Mimetype list present on edit form.');
+    $this->assertFieldChecked('edit-streams-public', 'File type configured to use public files.');
+    $this->assertNoFieldChecked('edit-streams-private', 'File type configured not to use private files.');
+
+    // Modify file type.
+    $edit['label'] = t('New type label');
+    $this->drupalPost(NULL, array('label' => $edit['label']), t('Save'));
+    $this->assertText(t('The file type @type has been updated.', array('@type' => $edit['label'])), 'File type was modified.');
+    $this->assertText($edit['label'], 'Modified label found on file types list.');
+
+    // Disable and re-enable file type.
+    $this->drupalGet('admin/structure/file-types/manage/' . $edit['type'] . '/disable');
+    $this->assertText(t('Are you sure you want to disable the file type @type?', array('@type' => $edit['label'])), 'Disable confirmation page found.');
+    $this->drupalPost(NULL, array(), t('Disable'));
+    $this->assertText(t('The file type @type has been disabled.', array('@type' => $edit['label'])), 'Disable confirmation message found.');
+    $this->assertFieldByXPath("//table//tr[5]//td[1]", $edit['label'], 'Disabled type moved to the tail of the list.');
+    $this->assertLink(t('enable'), 0, 'Able to re-enable newly created file type.');
+    $this->assertLinkByHref('admin/structure/file-types/manage/' . $edit['type'] . '/enable', 0, 'Enable link points to enable confirmation page.');
+    $this->drupalGet('admin/structure/file-types/manage/' . $edit['type'] . '/enable');
+    $this->assertText(t('Are you sure you want to enable the file type @type?', array('@type' => $edit['label'])), 'Enable confirmation page found.');
+    $this->drupalPost(NULL, array(), t('Enable'));
+    $this->assertText(t('The file type @type has been enabled.', array('@type' => $edit['label'])), 'Enable confirmation message found.');
+    $this->assertFieldByXPath("//table//tr[1]//td[1]", $edit['label'], 'Enabled type moved to the top of the list.');
+
+    // Delete newly created type.
+    $this->drupalGet('admin/structure/file-types/manage/' . $edit['type'] . '/delete');
+    $this->assertText(t('Are you sure you want to delete the file type @type?', array('@type' => $edit['label'])), 'Delete confirmation page found.');
+    $this->drupalPost(NULL, array(), t('Delete'));
+    $this->assertText(t('The file type @type has been deleted.', array('@type' => $edit['label'])), 'Delete confirmation message found.');
+    $this->drupalGet('admin/structure/file-types');
+    $this->assertNoText($edit['label'], 'File type successfully deleted.');
+
+    // Edit exported file type.
+    $this->drupalGet('admin/structure/file-types/manage/image/edit');
+    $this->assertRaw(t('Image'), 'Label found on file type edit page');
+    $this->assertText("image/jpeg\nimage/gif\nimage/png", 'Mime-type configuration found on file type edit page');
+    $this->assertFieldChecked('edit-streams-public', 'File type configured to use public files.');
+    $this->assertNoFieldChecked('edit-streams-private', 'File type configured not to use private files.');
+    $this->drupalPost(NULL, array('label' => t('Funky images')), t('Save'));
+    $this->assertText(t('The file type @type has been updated.', array('@type' => t('Funky images'))), 'File type was modified.');
+    $this->assertText(t('Funky image'), 'Modified label found on file types list.');
+    $this->assertFieldByXPath("//table//tr[1]//td[7]", t('Overridden'), 'Modified type overrides configuration from code.');
+    $this->assertLink(t('revert'), 0, 'Able to revert overridden file type.');
+    $this->assertLinkByHref('admin/structure/file-types/manage/image/revert', 0, 'Revert link points to revert confirmation page.');
+
+    // Revert file type.
+    $this->drupalGet('admin/structure/file-types/manage/image/revert');
+    $this->assertText(t('Are you sure you want to revert the file type @type?', array('@type' => t('Funky images'))), 'Revert confirmation page found.');
+    $this->drupalPost(NULL, array(), t('Revert'));
+    $this->assertText(t('The file type @type has been reverted.', array('@type' => t('Funky images'))), 'Revert confirmation message found.');
+    $this->assertText(t('Image'), 'Reverted file type found in list.');
+    $this->assertFieldByXPath("//table//tr[1]//td[7]", t('Default'), 'Reverted file type shows correct state.');
+  }
 }
 
 class FileEntityAccessTestCase extends FileEntityTestHelper {
