diff --git a/file_entity.admin.inc b/file_entity.admin.inc
index 9e9e83b..e65c55e 100644
--- a/file_entity.admin.inc
+++ b/file_entity.admin.inc
@@ -1,11 +1,156 @@
 <?php
 
+require_once dirname(__FILE__) . '/file_entity.pages.inc';
+
 /**
  * @file
  * Administrative interface for file type configuration.
  */
 
 /**
+ * Administrative form for browsing files and performing operations on them.
+ */
+function file_entity_admin_files($form, &$form_state) {
+  if (!empty($form_state['values']['operation'])) {
+    // The form is being rebuilt because an operation requiring confirmation
+    // was selected.  Hand off to the callback of the operation at this point
+    // which should return a confirm form.
+    $operation = $form_state['values']['operation'];
+    return call_user_func_array($operation['callback'], array($form_state['values']['files']));
+  }
+
+  $limit = variable_get('file_entity_admin_files_limit', 50);
+
+  // Build the 'Update options' form.
+  $form['options'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Update options'),
+    '#attributes' => array('class' => array('container-inline')),
+  );
+
+  $options = array();
+  $form['#operations'] = module_invoke_all('file_operations_info');
+  drupal_alter('file_entity_file_operations', $form['#operations']);
+
+  foreach ($form['#operations'] as $operation => $array) {
+    $options[$operation] = $array['label'];
+  }
+  $form['options']['operation'] = array(
+    '#type' => 'select',
+    '#title' => t('Operation'),
+    '#title_display' => 'invisible',
+    '#options' => $options,
+  );
+  $form['options']['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Update'),
+  );
+
+  // Build the sortable table header.
+  $header = array(
+    'title' => array('data' => t('Title'), 'field' => 'f.filename'),
+    'type' => array('data' => t('Type'), 'field' => 'f.filemime'),
+    'size' => array('data' => t('Size'), 'field' => 'f.filesize'),
+    'author' => array('data' => t('Author'), 'field' => 'u.name'),
+    'timestamp' => array('data' => t('Updated'), 'field' => 'f.timestamp', 'sort' => 'asc'),
+    'operations' => array('data' => t('Operations')),
+  );
+
+  $query = db_select('file_managed', 'f')->extend('PagerDefault')->extend('TableSort');
+  $query->join('users', 'u', 'f.uid = u.uid');
+
+  $query
+    ->fields('f')
+    ->fields('u', array('name'))
+    ->condition('f.status', FILE_STATUS_PERMANENT)
+    ->limit($limit)
+    ->orderByHeader($header);
+
+  foreach (array_keys(file_entity_get_hidden_stream_wrappers()) as $name) {
+    $query->condition('f.uri', $name . '%', 'NOT LIKE');
+  }
+
+  $result = $query->execute();
+
+  $destination = drupal_get_destination();
+  $files = array();
+  $options = array();
+
+  foreach ($result as $file) {
+    $options[$file->fid] = array(
+      'title' => theme('file_entity_file_link', array('file' => $file)),
+      'type' =>  check_plain($file->filemime),
+      'size' => format_size($file->filesize),
+      // It may be better to use a user_load_multiple() here and pass user objects
+      // so that modules like realname will work.  For now, this is okay though
+      // and simpler.
+      'author' => theme('username', array('account' => $file)),
+      'timestamp' => format_date($file->timestamp, 'short'),
+    );
+
+    $options[$file->fid]['operations'] = array(
+      'data' => array(
+        '#theme' => 'links__file_operations',
+        '#links' => array(),
+        '#attributes' => array('class' => array('links', 'inline')),
+      ),
+    );
+
+    $options[$file->fid]['operations']['data']['#links']['edit'] = array(
+      'title' => t('edit'),
+      'href' => 'file/' . $file->fid . '/edit',
+      'query' => $destination,
+    );
+
+    $options[$file->fid]['operations']['data']['#links']['delete'] = array(
+      'title' => t('delete'),
+      'href' => 'file/' . $file->fid . '/delete',
+      'query' => $destination,
+    );
+  }
+
+  $form['files'] = array(
+    '#type' => 'tableselect',
+    '#header' => $header,
+    '#options' => $options,
+    '#empty' => t('No files available.'),
+    '#attributes' => array('class' => array('file-display-table', 'clear')),
+  );
+  $form['pager'] = array('#markup' => theme('pager', array('tags' => NULL)));
+
+  return $form;
+}
+
+/**
+ * Submit handler for file_entity_admin_files.
+ */
+function file_entity_admin_files_submit($form, &$form_state) {
+  $operations = $form['#operations'];
+  $operation = $operations[$form_state['values']['operation']];
+
+  // In the case of an operation which needs confirmation, rebuild the form.
+  if (!empty($operation['confirm'])) {
+    $form_state['rebuild'] = TRUE;
+    $form_state['values']['operation'] = $operation;
+    return;
+  }
+
+  // Filter out unchecked nodes
+  $files = array_filter($form_state['values']['files']);
+  if ($function = $operation['callback']) {
+    // Add in callback arguments if present.
+    if (isset($operation['callback arguments'])) {
+      $args = array_merge(array($files), $operation['callback arguments']);
+    }
+    else {
+      $args = array($files);
+    }
+    call_user_func_array($function, $args);
+    cache_clear_all();
+  }
+}
+
+/**
  * Displays the file type admin overview page.
  */
 function file_entity_list_types_page() {
diff --git a/file_entity.file_api.inc b/file_entity.file_api.inc
index effd2aa..aa64fa5 100644
--- a/file_entity.file_api.inc
+++ b/file_entity.file_api.inc
@@ -487,3 +487,26 @@ function file_uri_to_object($uri, $use_existing = TRUE) {
 
   return $file;
 }
+
+/**
+ * A list of operations which can be called on files.
+ *
+ * @return
+ *  An associave array of operations keyed by a system name.
+ *    - label: A string to show in the operations dropdown.
+ *    - callback (string): A callback function to call for the operation. This
+ *        function will be passed an array of file_ids which were selected.
+ *    - confirm (boolean): Whether or not this operation requires a confirm form
+ *        In the case where confirm is set to true, callback should be a function
+ *        which can return a confirm form.
+ */
+function hook_file_operations_info() {
+  $operations = array(
+    'archive_and_email' => array(
+      'label' => t('Archive the selected files and email them'),
+      'callback' => 'file_archiver_confirm_form',
+      'confirm' => TRUE,
+    ),
+  );
+  return $operations;
+}
\ No newline at end of file
diff --git a/file_entity.module b/file_entity.module
index a10ddc9..ec68932 100644
--- a/file_entity.module
+++ b/file_entity.module
@@ -40,14 +40,27 @@ function file_entity_menu() {
   // File Configuration
   $items['admin/config/media/file-types'] = array(
     'title' => 'File types',
-    'description' => 'Manage files used on your site.',
+    'description' => 'Manage settings for the type of files used on your site.',
     'page callback' => 'file_entity_list_types_page',
     'access arguments' => array('administer site configuration'),
     'file' => 'file_entity.admin.inc',
   );
   $items['admin/config/media/file-types/manage/%'] = array(
     'title' => 'Manage file types',
+    'description' => 'Manage settings for the type of files used on your site.',
+  );
+  $items['admin/content/file'] = array(
+    'title' => 'Files',
     'description' => 'Manage files used on your site.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('file_entity_admin_files'),
+    'access arguments' => array('administer files'),
+    'type' => MENU_LOCAL_TASK | MENU_NORMAL_ITEM,
+    'file' => 'file_entity.admin.inc',
+  );
+  $items['admin/content/file/list'] = array(
+    'title' => 'List',
+    'type' => MENU_DEFAULT_LOCAL_TASK,
   );
   // general view, edit, delete for files
   $items['file/%file'] = array(
@@ -184,6 +197,9 @@ function file_entity_theme() {
       'render element' => 'element',
       'file' => 'file_entity.admin.inc',
     ),
+    'file_entity_file_link' => array(
+      'variables' => array('file' => NULL, 'icon_directory' => NULL),
+    )
   );
 }
 
@@ -644,3 +660,74 @@ function file_entity_view_mode_label($view_mode, $default = FALSE) {
   $labels = file_entity_view_mode_labels();
   return isset($labels[$view_mode]) ? $labels[$view_mode] : $default;
 }
+
+/**
+ * Implements hook_file_operations_info().
+ */
+function file_entity_file_operations_info() {
+  $operations = array(
+    'delete' => array(
+      'label' => t('Delete selected files'),
+      'callback' => 'file_entity_multiple_delete_confirm_operation',
+      'confirm' => TRUE,
+    ),
+  );
+  return $operations;
+}
+
+/**
+ * File operation to show a confirm form for file deletion.
+ *
+ * @param array $files
+ *   An array of file_ids to delete.
+ * @return type
+ */
+function file_entity_multiple_delete_confirm_operation($files) {
+  // This function is a form generation function.
+  $form = array();
+  $form_state = array();
+  return file_entity_multiple_delete_confirm($form, $form_state, $files);
+}
+
+/**
+ * Helper function to get a list of hidden stream wrappers.
+ *
+ * This is used in several places to filter queries for media so that files in
+ * temporary:// don't show up.
+ */
+function file_entity_get_hidden_stream_wrappers() {
+  return array_diff_key(file_get_stream_wrappers(STREAM_WRAPPERS_ALL), file_get_stream_wrappers(STREAM_WRAPPERS_VISIBLE));
+}
+
+/**
+ * @see theme_file_file_link.
+ * This is a copy of it, except we make the url file/$fid.
+ *
+ * @return type
+ */
+function theme_file_entity_file_link($variables) {
+  $file = $variables['file'];
+  $icon_directory = $variables['icon_directory'];
+
+  $url = 'file/' . $file->fid;
+  $icon = theme('file_icon', array('file' => $file, 'icon_directory' => $icon_directory));
+
+  // Set options as per anchor format described at
+  // http://microformats.org/wiki/file-format-examples
+  $options = array(
+    'attributes' => array(
+      'type' => $file->filemime . '; length=' . $file->filesize,
+    ),
+  );
+
+  // Use the description as the link text if available.
+  if (empty($file->description)) {
+    $link_text = $file->filename;
+  }
+  else {
+    $link_text = $file->description;
+    $options['attributes']['title'] = check_plain($file->filename);
+  }
+
+  return '<span class="file">' . $icon . ' ' . l($link_text, $url, $options) . '</span>';
+}
diff --git a/file_entity.pages.inc b/file_entity.pages.inc
index cbaddae..05bf54e 100644
--- a/file_entity.pages.inc
+++ b/file_entity.pages.inc
@@ -94,54 +94,42 @@ function file_entity_page_delete($file) {
     return t('The file %title is in use and cannot be deleted.', array('%title' => $file->filename));
   }
   else {
-    $files = array($file->fid => $file);
-    return drupal_get_form('file_entity_multiple_delete_confirm', $files, '<front>', 'media/' . $file->fid);
+    $files = array($file->fid => $file->fid);
+    return drupal_get_form('file_entity_multiple_delete_confirm', $files, 'file/' . $file->fid);
   }
 }
 
 /**
- * Form submit handler for the Delete button on the media edit form.
+ * Confirm form for the request to delete files.
+ *
+ * @param array $files
+ *   An array of file_ids to delete.
  */
-function file_entity_delete_submit($form, &$form_state) {
-  $fid = $form_state['values']['fid'];
-  $destination = array();
-  if (isset($_GET['destination'])) {
-    $destination = drupal_get_destination();
-    unset($_GET['destination']);
-  }
-  $form_state['redirect'] = array('file/' . $fid . '/delete', array('query' => $destination));
-}
+function file_entity_multiple_delete_confirm($form, &$form_state, $files, $redirect_path = NULL) {
+  $form = array();
+  $files = array_filter($files);
 
-/**
- * Confirm the request to delete files.
- */
-function file_entity_multiple_delete_confirm($form, &$form_state, $files, $redirect_on_success = NULL, $redirect_on_cancel = NULL) {
   $form['files'] = array('#tree' => TRUE);
   $form['file_titles'] = array('#theme' => 'item_list');
-  foreach ($files as $fid => $value) {
-    $title = db_query('SELECT filename FROM {file_managed} WHERE fid = :fid', array(':fid' => $fid))->fetchField();
+
+  $files = file_load_multiple($files);
+  foreach ($files as $fid => $file) {
     $form['files'][$fid] = array(
       '#type' => 'value',
       '#value' => $fid,
     );
-    $form['file_titles']['#items'][] = check_plain($title);
+    $form['file_titles']['#items'][] = check_plain($file->filename);
   }
   $form['operation'] = array('#type' => 'hidden', '#value' => 'delete');
-  if (isset($redirect_on_success)) {
-    $form['redirect_on_success'] = array(
-      '#type' => 'value',
-      '#value' => $redirect_on_success,
-    );
-  }
   $form['#submit'][] = 'file_entity_multiple_delete_confirm_submit';
 
   $confirm_question = format_plural(count($files),
-                                  'Are you sure you want to delete this item?',
-                                  'Are you sure you want to delete these items?');
+                                  'Are you sure you want to delete this file?',
+                                  'Are you sure you want to delete these files?');
 
   return confirm_form($form,
     $confirm_question,
-    isset($redirect_on_cancel) ? $redirect_on_cancel : current_path(),
+    $redirect_path,
     t('This action cannot be undone.'),
     t('Delete'),
     t('Cancel'));
@@ -152,29 +140,34 @@ function file_entity_multiple_delete_confirm($form, &$form_state, $files, $redir
  */
 function file_entity_multiple_delete_confirm_submit($form, &$form_state) {
   if ($form_state['values']['confirm']) {
-    $results = array();
-    $files = array_keys($form_state['values']['files']);
-    foreach ($files as $fid) {
-      $file = file_load($fid);
-      $files[$fid] = $file;
-      $results[$fid] = file_delete($file);
-    }
-    // The result of file_delete can be an array if the file is in use, or TRUE/FALSE.
-    foreach ($results as $fid => $result) {
+    $files = file_load_multiple(array_keys($form_state['values']['files']));
+    foreach ($files as $fid => $file) {
+      $result = file_delete($file);
       if (is_array($result)) {
-        drupal_set_message(t('The file @title is in use and cannot be deleted.', array('@title' => $files[$fid]->filename)), 'warning');
+        drupal_set_message(t('The file @title is in use and cannot be deleted.', array('@title' => $file->filename)), 'warning');
       }
       elseif (!$result) {
-        drupal_set_message(t('The file @title was not deleted due to an error.', array('@title' => $files[$fid]->filename)), 'error');
+        drupal_set_message(t('The file @title was not deleted due to an error.', array('@title' => $file->filename)), 'error');
       }
       else {
-        $message = t('File @title was deleted', array('@title' => $files[$fid]->filename));
-        watchdog('media', $message);
+        $message = t('File @title was deleted', array('@title' => $file->filename));
+        $form_state['redirect'] = '<front>';
+        watchdog('file', $message);
         drupal_set_message($message);
       }
     }
-    if (isset($form_state['values']['redirect_on_success'])) {
-      $form_state['redirect'] = $form_state['values']['redirect_on_success'];
-    }
   }
 }
+
+/**
+ * Form submit handler for the Delete button on the media edit form.
+ */
+function file_entity_delete_submit($form, &$form_state) {
+  $fid = $form_state['values']['fid'];
+  $destination = array();
+  if (isset($_GET['destination'])) {
+    $destination = drupal_get_destination();
+    unset($_GET['destination']);
+  }
+  $form_state['redirect'] = array('file/' . $fid . '/delete', array('query' => $destination));
+}
