diff --git a/twitter.inc b/twitter.inc
index 52f926c..33312fa 100644
--- a/twitter.inc
+++ b/twitter.inc
@@ -119,6 +119,7 @@ function twitter_account_load($id, $is_uid = TRUE) {
     $account->import = $values['import'];
     $account->mentions = $values['mentions'];
     $account->is_global = $values['is_global'];
+    $account->moderated = $values['moderated'];
     return $account;
   }
   return NULL;
@@ -240,6 +241,9 @@ function twitter_status_save($status) {
   );
   db_merge('twitter')
     ->key(array('twitter_id' => $row['twitter_id']))
+    ->insertFields(array(
+      'status' => (int) $status->status,
+    ))
     ->fields($row)
     ->execute();
   // Let other modules know that a status has been saved.
@@ -247,6 +251,24 @@ function twitter_status_save($status) {
 }
 
 /**
+ * Updates a tweets status
+ */
+function twitter_status_update($status) {
+  $row = array(
+    'twitter_id' => $status['twitter_id'],
+    'status' => (int) $status['status'],
+  );
+  db_merge('twitter')
+    ->key(array('twitter_id' => $row['twitter_id']))
+    ->fields($row)
+    ->execute();
+  // Let other modules know that a status has been saved.
+  module_invoke_all('twitter_status_update', $status);
+}
+
+/**
+
+/**
  * Post a message to twitter
  *
  * @param $twitter_account
@@ -294,7 +316,7 @@ function twitter_statuses_oembed($tweet_id) {
 /**
  * Fetches a user's timeline.
  */
-function twitter_fetch_user_timeline($id) {
+function twitter_fetch_user_timeline($id, $moderated) {
   $twitter_account = twitter_account_load($id);
   $since = db_query("SELECT MAX(twitter_id) FROM {twitter} WHERE screen_name = :screen_name", array(':screen_name' => $twitter_account->screen_name))->fetchField();
 
@@ -340,6 +362,7 @@ function twitter_fetch_user_timeline($id) {
     watchdog('twitter', 'Downloaded %count tweets for the %name account.', array('%count' => count($statuses), '%name' => $twitter_account->screen_name));
 
     foreach ($statuses as $status) {
+      $status->status = ! (bool) $moderated;
       twitter_status_save($status);
     }
   }
@@ -347,8 +370,10 @@ function twitter_fetch_user_timeline($id) {
   // Trigger hook_twitter_insert_statuses().
   module_invoke_all('twitter_insert_statuses', $statuses, $twitter_account);
 
-  // Update account details.
+
+  // Update account details, but keep current moderation
   if (count($statuses) > 0) {
+    $statuses[0]->user->moderated = $moderated;
     twitter_account_save($statuses[0]->user);
   }
 }
@@ -366,7 +391,7 @@ function twitter_retweet($twitter_account, $tweet_id) {
 /**
  * Fetches user's mentions of an authenticated account.
  */
-function twitter_fetch_mentions_timeline($id) {
+function twitter_fetch_mentions_timeline($id, $moderated) {
   $twitter_account = twitter_account_load($id);
 
   // Connect to Twitter's API using the authenticated account to fetch mentions.
@@ -379,6 +404,7 @@ function twitter_fetch_mentions_timeline($id) {
   $params = array();
   $statuses = $twitter->mentions_timeline($params);
   foreach ($statuses as $status) {
+    $status->status = ! (bool) $moderated;
     if (!twitter_account_load($status->user->id)) {
       twitter_account_save($status->user);
     }
@@ -394,7 +420,8 @@ function twitter_fetch_mentions_timeline($id) {
  */
 function twitter_tweets($screen_name = NULL) {
   $query = db_select('twitter', 't')
-    ->fields('t');
+    ->fields('t')
+    ->orderBy('created_time', 'DESC');
   if (isset($screen_name)) {
     $query->condition('t.screen_name', $screen_name);
   }
diff --git a/twitter.install b/twitter.install
index c218619..d4cee69 100644
--- a/twitter.install
+++ b/twitter.install
@@ -122,6 +122,13 @@ function twitter_schema() {
         'serialize' => TRUE,
         'description' => 'A serialized array of {twitter} post entities.',
       ),
+      'status' => array(
+        'description' => "Boolean indicating whether the tweet is published.",
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
     ),
     'primary key' => array('twitter_id'),
     'indexes' => array(
@@ -324,6 +331,13 @@ function twitter_schema() {
         'not null' => FALSE,
         'default' => 0,
       ),
+      'moderated' => array(
+        'description' => "Boolean indicating whether the account is moderated.",
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
     ),
     'indexes' => array(
       'screen_name' => array('screen_name'),
@@ -646,3 +660,27 @@ function twitter_update_7514() {
     variable_set('twitter_search', 'https://twitter.com/');
   }
 }
+
+/**
+ * Adds twitter.status and twitter_account.moderated fields to identify
+ * published and unpublished tweets and moderated accounts
+ */
+function twitter_update_7515() {
+  $data = array(
+    'description' => "Boolean indicating whether the tweet is published.",
+    'type' => 'int',
+    'unsigned' => TRUE,
+    'not null' => TRUE,
+    'default' => 1,
+  );
+  db_add_field('twitter', 'status', $data);
+  $data = array(
+    'description' => "Boolean indicating whether the account is moderated.",
+    'type' => 'int',
+    'unsigned' => TRUE,
+    'not null' => TRUE,
+    'default' => 0,
+  );
+  db_add_field('twitter_account', 'moderated', $data);
+}
+
diff --git a/twitter.lib.php b/twitter.lib.php
index a37a972..88ef0c8 100644
--- a/twitter.lib.php
+++ b/twitter.lib.php
@@ -164,7 +164,7 @@ class Twitter {
       throw new TwitterException($error);
     }
   }
-  
+
   /**
    *
    * @see https://dev.twitter.com/docs/api/1/post/statuses/retweet/%3Aid
@@ -1291,11 +1291,20 @@ class TwitterStatus {
 
   public $retweeted_status;
 
+  public $status;
+
   /**
    * Constructor for TwitterStatus
    */
   public function __construct($values = array()) {
     $this->created_at = $values['created_at'];
+    if (!empty($values['moderated'])) {
+      $this->moderated = $values['moderated'];
+    }
+    else
+    {
+      $this->moderated = 0;
+    }
     $this->id = $values['id'];
     $this->text = $values['text'];
     $this->source = $values['source'];
diff --git a/twitter.module b/twitter.module
index 4080979..387d15e 100644
--- a/twitter.module
+++ b/twitter.module
@@ -58,6 +58,15 @@ function twitter_menu() {
     'type' => MENU_LOCAL_TASK,
   );
 
+  $items['admin/config/services/twitter/tweets'] = array(
+    'title' => 'Tweets',
+    'description' => 'Tweets list.',
+    'page callback' => 'twitter_tweets_list',
+    'access arguments' => array('moderate tweets'),
+    'file' => 'twitter.pages.inc',
+    'type' => MENU_LOCAL_TASK,
+  );
+
   return $items;
 }
 
@@ -78,6 +87,9 @@ function twitter_permission() {
     'administer twitter accounts' => array(
       'title' => t('Administer Twitter accounts'),
     ),
+    'moderate tweets' => array(
+      'title' => t('Moderate tweets'),
+    ),
   );
 }
 
@@ -133,6 +145,9 @@ function twitter_theme() {
         'accounts' => array(),
       ),
     ),
+    'twitter_tweet_list_form' => array(
+      'render element' => 'form',
+    ),
   );
 }
 
@@ -218,7 +233,7 @@ function twitter_cron() {
   // Pull up a list of Twitter accounts that are flagged for updating, sorted
   // by how long it's been since we last updated them. This ensures that the
   // most out-of-date accounts get updated first.
-  $result = db_query_range("SELECT twitter_uid
+  $result = db_query_range("SELECT twitter_uid, moderated
     FROM {twitter_account}
     WHERE uid > 0 AND import = 1
     ORDER BY last_refresh ASC",
@@ -226,12 +241,12 @@ function twitter_cron() {
   try {
     foreach ($result as $account) {
       // Fetch tweets for this account.
-      twitter_fetch_user_timeline($account->twitter_uid);
+      twitter_fetch_user_timeline($account->twitter_uid, $account->moderated);
       $twitter_account = twitter_account_load($account->twitter_uid);
 
       // Optionally fetch mentions.
       if ($twitter_account->is_auth() && $twitter_account->mentions) {
-        twitter_fetch_mentions_timeline($twitter_account->id);
+        twitter_fetch_mentions_timeline($twitter_account->id, $account->moderated);
       }
 
       // Mark the time this account was updated.
diff --git a/twitter.pages.inc b/twitter.pages.inc
index 5465b7c..dee5704 100644
--- a/twitter.pages.inc
+++ b/twitter.pages.inc
@@ -122,6 +122,143 @@ function twitter_admin_form($form, &$form_state) {
 }
 
 /**
+ * Form builder that lists Tweets.
+ *
+ * @param object $account
+ *   Optional user account.
+ * @return
+ *   A list of Tweets.
+ */
+function twitter_tweets_list($account = NULL) {
+  // Verify OAuth keys.
+  if (!twitter_api_keys()) {
+    $output = t('<p>You need to authenticate at least one Twitter account in order to use the Twitter API. Please fill out the OAuth fields at <a href="/admin/config/services/twitter/settings">Twitter Settings</a> and then return here.</p>');
+  }
+  else {
+    module_load_include('inc', 'twitter');
+    if (!$account) {
+      $tweets = twitter_tweets();
+    }
+    else {
+      $tweets = twitter_tweets($account->screen_name);
+    }
+
+    $output = array();
+    if (count($tweets)) {
+      // List Twitter accounts.
+      $output['header']['#markup'] = '';
+      if (user_access('administer site configuration')) {
+        $output['header']['#markup'] = t('<p>Tweets are pulled from Twitter by ' .
+          '<a href="/admin/reports/status/run-cron?destination=admin/config/services/twitter/tweets">running cron</a>. ');
+      }
+      $output['list_form'] = drupal_get_form('twitter_tweet_list_form', $tweets);
+    }
+    else {
+      // No accounts added. Inform about how to add one.
+      $output['header'] = array(
+        '#markup' => t('<p>No Twitter accounts have been added yet. Click on the following button to add one.</p>'),
+      );
+    }
+  }
+  return $output;
+}
+
+/**
+ * Formats each Tweet as a row within a form.
+ */
+function twitter_tweet_list_form($form, $form_state, $tweets = array()) {
+  $form['#tree'] = TRUE;
+  $form['tweets'] = array();
+
+  foreach ($tweets as $tweet) {
+    $form['tweets'][] = _twitter_tweet_list_row($tweet);
+  }
+
+  if (!empty($tweets)) {
+    $form['buttons']['submit'] = array(
+      '#type' => 'submit',
+      '#value' => t('Save changes'),
+    );
+  }
+
+  return $form;
+}
+
+/**
+ * Returns the form fields to manage a Tweet.
+ */
+function _twitter_tweet_list_row($tweet) {
+  $form['#tweet'] = $tweet;
+
+  $form['twitter_id'] = array(
+    '#type' => 'value',
+    '#value' => $tweet->twitter_id,
+  );
+
+  $form['screen_name'] = array(
+    '#type' => 'value',
+    '#value' => $tweet->screen_name,
+  );
+
+  $form['visible_name'] = array(
+    '#markup' => _twitter_user_profile($tweet->screen_name),
+  );
+
+  $form['text'] = array(
+    '#markup' => filter_xss(_twitter_filter_link(_twitter_filter_hashtag(_twitter_filter_username($tweet->text, NULL), NULL), NULL)),
+  );
+
+  $form['status'] = array(
+    '#type' => 'checkbox',
+    '#default_value' => $tweet->status ? $tweet->status : '',
+  );
+
+  return $form;
+}
+
+/**
+ * Themes the list of Tweets.
+ */
+function theme_twitter_tweet_list_form($variables) {
+  $form = $variables['form'];
+
+  $header = array(
+    t('Name'),
+    t('Text'),
+    t('Published'),
+  );
+
+  $rows = array();
+  foreach (element_children($form['tweets']) as $key) {
+    $element = &$form['tweets'][$key];
+    $row = array(
+      drupal_render($element['id']) . drupal_render($element['screen_name']) .
+      drupal_render($element['visible_name']).
+      drupal_render($element['screen_name']),
+      drupal_render($element['text']),
+      drupal_render($element['status']),
+    );
+    $rows[] = $row;
+  }
+
+  $output = theme('table', array('header' => $header, 'rows' => $rows));
+  $output .= drupal_render_children($form);
+  return $output;
+}
+
+/**
+ * Form submit handler for altering the list of Tweets.
+ */
+function twitter_tweet_list_form_submit($form, &$form_state) {
+  $tweets = $form_state['values']['tweets'];
+  foreach ($tweets as $tweet) {
+    twitter_status_update($tweet);
+  }
+  drupal_set_message(t('The Tweets settings were updated.'));
+}
+
+
+/**
  * Form builder that lists Twitter accounts.
  *
  * @param object $account
@@ -284,6 +421,18 @@ function _twitter_account_list_row($account) {
     );
   }
 
+  if ($account->import == TRUE || $account->mentions == TRUE) {
+    $form['moderated'] = array(
+      '#type' => 'checkbox',
+      '#default_value' => $account->moderated ? $account->moderated : '',
+    );
+  }
+  else {
+    $form['moderated'] = array(
+      '#markup' => '',
+    );
+  }
+
   $form['delete'] = array(
     '#type' => 'checkbox',
   );
@@ -311,6 +460,7 @@ function theme_twitter_account_list_form($variables) {
     t('Tweets'),
     t('Mentions'),
     t('Global'),
+    t('Moderated'),
     t('Delete'),
   ));
 
@@ -332,6 +482,7 @@ function theme_twitter_account_list_form($variables) {
       drupal_render($element['import']),
       drupal_render($element['mentions']),
       drupal_render($element['is_global']),
+      drupal_render($element['moderated']),
       drupal_render($element['delete']),
     ));
     $rows[] = $row;
diff --git a/twitter.views.inc b/twitter.views.inc
index 8792b65..b41d3ad 100644
--- a/twitter.views.inc
+++ b/twitter.views.inc
@@ -182,6 +182,22 @@ function twitter_views_data() {
     ),
   );
 
+  // Twitter account protected
+  $data['twitter']['status'] = array(
+    'title' => t('Publishing status'),
+    'help' => t('Whether this Tweet should be visible to the general public.'),
+    'field' => array(
+      'handler' => 'views_handler_field_boolean',
+      'click sortable' => TRUE,
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_boolean_operator',
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+  );
+
   // Table twitter_account.
   $data['twitter_account']['table']['group']  = t('Twitter');
   $data['twitter_account']['table']['group']  = t('Twitter Account');
diff --git a/twitter.views_default.inc b/twitter.views_default.inc
index 9caaa6a..6d2ee94 100644
--- a/twitter.views_default.inc
+++ b/twitter.views_default.inc
@@ -81,6 +81,13 @@ function twitter_views_default_views() {
   $handler->display->display_options['filters']['protected']['value'] = 0;
   $handler->display->display_options['filters']['protected']['group'] = '0';
   $handler->display->display_options['filters']['protected']['expose']['operator'] = FALSE;
+  /* Filter criterion: Twitter: Published status */
+  $handler->display->display_options['filters']['status']['id'] = 'status';
+  $handler->display->display_options['filters']['status']['table'] = 'twitter';
+  $handler->display->display_options['filters']['status']['field'] = 'status';
+  $handler->display->display_options['filters']['status']['value'] = 1;
+  $handler->display->display_options['filters']['status']['group'] = '0';
+  $handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
 
   /* Display: Tweets Raw */
   $handler = $view->new_display('page', 'Tweets Raw', 'page_all_tweets');
