diff --git a/nodequeue_generate.drush.inc b/nodequeue_generate.drush.inc
new file mode 100644
index 0000000..e6db77b
--- /dev/null
+++ b/nodequeue_generate.drush.inc
@@ -0,0 +1,105 @@
+<?php
+
+/**
+ * @file
+ *   Nodequeue generate drush integration.
+ */
+
+/**
+ * Implementation of hook_drush_command().
+ *
+ * @See drush_parse_command() for a list of recognized keys.
+ *
+ * @return
+ *   An associative array describing your command(s).
+ */
+function nodequeue_generate_drush_command() {
+  $items = array();
+
+  $items['nodequeue-generate'] = array(
+    'description' => "Re-populates specified nodequeues with random nodes.",
+    'drupal dependencies' => array('nodequeue_generate'),
+    'arguments' => array(
+      'queue' => 'Machine name of queue to be re-populated.',
+    ),
+    'aliases' => array('nqg'),
+  );
+  $items['nodequeue-generate-all'] = array(
+    'description' => "Re-populates nodequeues with random nodes.",
+    'drupal dependencies' => array('nodequeue_generate'),
+    'aliases' => array('nqga'),
+  );
+  $items['nodequeue-generate-rehash'] = array(
+    'description' => "Rehashes smartqueue subqueues for taxonomy smartqueue.",
+    'drupal dependencies' => array('nodequeue_generate', 'smartqueue'),
+    'aliases' => array('nqr'),
+  );
+
+  return $items;
+}
+
+/**
+ * Implementation of hook_drush_help().
+ */
+function nodequeue_generate_drush_help($section) {
+  switch ($section) {
+    case 'drush:nodequeue-generate':
+      return dt("Re-populates specified nodequeues with random nodes.");
+    case 'drush:nodequeue-generate-all':
+      return dt("Re-populates all nodequeues with random nodes.");
+    case 'drush:nodequeue-generate-rehash':
+      return dt("Rehashes smartqueue subqueues for taxonomy smartqueue.");
+  }
+}
+
+/**
+ * Re-populates specified nodequeues with random nodes.
+ */
+function drush_nodequeue_generate() {
+  $args = func_get_args();
+
+  // At least one queue must be specified.
+  if (count($args) < 1) {
+    drush_set_error('error', dt('At least one queue must be specified.'));
+  }
+
+  // Get qids from machine names.
+  $qids = array();
+  foreach ($args as $queue) {
+
+    $qid = db_select('nodequeue_queue', 'nq')
+      ->fields('nq', array('qid'))
+      ->condition('name', $queue)
+      ->execute()
+      ->fetchField();
+
+    if ($qid) {
+      $qids[] = $qid;
+    }
+    else {
+      drush_set_error('error', dt('Queue @queue was not found.', array('@queue' => $queue)));
+    }
+
+  }
+
+  nodequeue_generate_repopulate_queues($qids);
+}
+
+/**
+ * Re-populates all nodequeues with random nodes.
+ */
+function drush_nodequeue_generate_all() {
+  $qids = db_select('nodequeue_queue', 'nq')
+    ->fields('nq', array('qid'))
+    ->execute()
+    ->fetchAll(PDO::FETCH_COLUMN, 'qid');
+
+  nodequeue_generate_repopulate_queues($qids);
+}
+
+/**
+ * Rehashes smartqueue subqueues for taxonomy smartqueue.
+ */
+function drush_nodequeue_generate_rehash() {
+  nodequeue_generate_rehash();
+}
diff --git a/nodequeue_generate.module b/nodequeue_generate.module
index 52dc7bf..03856e4 100644
--- a/nodequeue_generate.module
+++ b/nodequeue_generate.module
@@ -13,114 +13,79 @@ function nodequeue_generate_menu() {
 }
 
 function nodequeue_generate_form() {
-  $form['help'] = array('#value' => '<p>' . t('Select which queues shall be <strong>emptied</strong> and re-populated with new nodes.') . '</p>');
+  $form['help'] = array(
+    '#markup' => '<p>' . t('Select which queues shall be <strong>emptied</strong> and re-populated with new nodes.') . '</p>'
+  );
 
   $queues = nodequeue_load_queues(nodequeue_get_all_qids(25));
-  if (empty($queues)) {
-    form_set_error('', t('No queues exist.'));
-    return array();
-  }
 
-  $qids = array();
-  // For every queue that has exactly 1 subqueue,
-  foreach ($queues as $queue) {
-    if ($queue->subqueues == 1) {
-      $qids[] = $queue->qid;
-    }
-  }
-
-  $subqueues = nodequeue_load_subqueues_by_queue($qids);
-  // Relate all the subqueues we loaded back to our queues.
-  foreach ($subqueues as $subqueue) {
-    $queues[$subqueue->qid]->subqueue = $subqueue;
-  }
+  // Tableselect header.
+  $header = array(
+    'name' => 'Queue name',
+    'max_nodes' => 'Max nodes',
+    'subqueues' => 'Subqueues',
+  );
 
+  // Tableselect data.
+  $data = array();
   foreach ($queues as $queue) {
-    $sub_text = $queue->subqueues;
-    if ($sub_text == 1) {
-      $sub_text .= " (" . nodequeue_subqueue_size_text($queue->size, $queue->subqueue->count) . ")";
-    }
-    $form['rows']['cb'][$queue->qid] = array('#type' => 'checkbox', '#default_value' => 0);
-    $form['rows'][$queue->qid]['nodequeue-title'] = array('#value' => check_plain($queue->title));
-    $form['rows'][$queue->qid]['nodequeue-max-nodes'] = array('#value' => $queue->size == 0 ? t('Infinite') : $queue->size);
-    $form['rows'][$queue->qid]['nodequeue-subqueues'] = array('#value' => $sub_text);
-    $form['rows'][$queue->qid]['limit'] = array('#type' => 'value', '#value' => ($queue->size == 0 || $queue->size > 20) ? 10 : $queue->size);
+    $data[$queue->qid]['name'] = check_plain($queue->title);
+    $data[$queue->qid]['max_nodes'] = $queue->size == 0 ? t('Infinite') : $queue->size;
+    $data[$queue->qid]['subqueues'] = $queue->subqueues;
   }
 
-  $form['qids'] = array('#type' => 'value', '#value' => array_keys($queues));
+  // Table select element.
+  $form['nodequeues'] = array(
+    '#type' => 'tableselect',
+    '#header' => $header,
+    '#options' => $data,
+    '#empty' => t('There are no queues.'),
+  );
+
   $form['submit'] = array(
     '#type' => 'submit',
     '#value' => t('Generate'),
   );
-  $form['#tree'] = TRUE;
+
   return $form;
 }
 
+function nodequeue_generate_form_submit($form, &$form_state) {
+  // Get qids of all nodequeues that need to be re-populated and repopulate them.
+  $qids = array_keys(array_filter($form_state['values']['nodequeues']));
+  //nodequeue_generate_repopulate_queues($qids);
+  nodequeue_generate_rehash();
+}
+
 /**
- * Implements hook_theme().
+ * Re-populates nodequeues with nodes.
  *
- * @return unknown
+ * @param $qids Array of queues, that need to be repopulated.
  */
-function nodequeue_generate_theme() {
-  return array(
-    'nodequeue_generate_form' => array(
-      'arguments' => array('form' => NULL),
-    ),
-  );
-}
-
-function theme_nodequeue_generate_form($form) {
-  $output = drupal_render($form['help']);
-  $children = element_children($form['rows']);
-  unset($children[array_search('cb', $children)]);
-  foreach ($children as $qid) {
-    $rows[] = array(
-      drupal_render($form['rows']['cb'][$qid]),
-      drupal_render($form['rows'][$qid]['nodequeue-title']),
-      drupal_render($form['rows'][$qid]['nodequeue-max-nodes']),
-      drupal_render($form['rows'][$qid]['nodequeue-subqueues']),
-    );
-  }
-  $header = array(theme('table_select_header_cell'), t('Title'), t('Max nodes'), t('Subqueues'));
-  $output .= theme('table', array('header' => $header, 'rows' => $rows));
-  $output .= theme('pager', array('tags' => NULL));
-  $output .= drupal_render($form);
-
-  return $output;
-}
-
-function nodequeue_generate_form_submit($form, &$form_state) {
-  $qids = array_keys(array_filter($form_state['values']['rows']['cb']));
+function nodequeue_generate_repopulate_queues($qids) {
+  // Remove existing nodes from queues.
   db_query("DELETE FROM {nodequeue_nodes} WHERE qid IN (:qids)", array(':qids' => $qids));
 
+  // Load all queues and their subqueues.
   $queues = nodequeue_load_queues($qids);
   $subqueues = nodequeue_load_subqueues_by_queue($qids);
-  // TODO: handle non smart_taxonomy subqueues.
-  foreach ($subqueues as $subqueue) {
-    // dpr($queues[$subqueue->qid]);
-    // we don't know what kind of nodes to out in, so skip. is this a good idea?
-    if (empty($queues[$subqueue->qid]->types)) {
-      next;
-    }
 
-    $placeholders = implode(', ', array_fill(0, count($queues[$subqueue->qid]->types), '\'%s\''));
-    $args = $queues[$subqueue->qid]->types;
-    // smartqueue_taxonomy pulls nodes from the proper terms. nodequeue type queues don't care about taxo.
-    if ($queues[$subqueue->qid]->owner == 'nodequeue') {
-      $sql = "SELECT n.nid FROM {node} n WHERE n.status = 1 AND n.type IN ($placeholders) ORDER BY RAND()";
-      $result = db_query_range($sql, $args, 0, $form_state['values']['rows'][$subqueue->qid]['limit']);
-      foreach ($result as $row) {
-        nodequeue_subqueue_add($subqueue, $subqueue, $row->nid);
-      }
-    }
-    elseif ($queues[$subqueue->qid]->owner == 'smartqueue_taxonomy') {
-      $args[] = $subqueue->reference;
-      $sql = "SELECT tn.nid FROM {term_node} tn INNER JOIN {node} n ON tn.nid=n.nid WHERE n.status = 1 AND n.type IN ($placeholders) AND tn.tid = %d ORDER BY RAND()";
-      $result = db_query_range($sql, $args, 0, $form_state['values']['rows'][$subqueue->qid]['limit']);
-      foreach ($result as $row) {
-        nodequeue_subqueue_add($subqueue, $subqueue, $row->nid);
+  // Re-populate subqueues
+  foreach ($qids as $qid) {
+    $queue = nodequeue_load($qid);
+
+    // Skip nodequeues that do not belong to any node types.
+    if (!empty($queue->types)) {
+
+      $limit = $queue->size ? $queue->size : variable_get('nodequeue_generate_nodes_limit', 20);
+      $callback = $queue->owner . '_nodequeue_generate';
+
+      if (function_exists($callback)) {
+        $callback($queue, $limit);
       }
+
     }
+
   }
 
   drupal_set_message(format_plural(count($qids), '1 queue populated', '@count queues populated.'));
@@ -133,21 +98,100 @@ function nodequeue_generate_form_submit($form, &$form_state) {
  * @param vids
  *   An array of vocabulary ids.
  **/
-function nodequeue_generate_rehash($vids) {
+function nodequeue_generate_rehash() {
   // Delete existing smartqueue taxonomy subqueues
   db_query("DELETE ns FROM nodequeue_subqueue ns INNER JOIN nodequeue_queue nq ON ns.qid=nq.qid WHERE nq.owner = 'smartqueue_taxonomy'");
 
-  // Re-add those subqueues
-  $node = new stdClass;
-  $tree = array();
-  foreach ($vids as $vid) {
-    $tree += taxonomy_get_tree($vid);
+  // Get all queues, owned by Smartqueue taxonomy.
+  $qids = db_select('nodequeue_queue', 'nq')
+    ->fields('nq', array('qid'))
+    ->condition('owner', 'smartqueue_taxonomy')
+    ->execute()
+    ->fetchAll();
+
+  foreach ($qids as $qid) {
+    $queue = nodequeue_load($qid->qid);
+    $field = $queue->reference;
+
+    // Get all possible tids from this field.
+    $tids = db_select('field_data_' . $field, 'f');
+    $tids->condition('f.entity_type', 'node');
+    $tids->condition('f.bundle', $queue->types, 'IN');
+    $tids->condition('f.deleted', FALSE);
+    $tids->addField('f', $field . '_tid', 'tid');
+    $tids->distinct();
+    $tids = $tids->execute();
+    $tids = $tids->fetchAll();
+
+    // Rehash for each tid.
+    foreach ($tids as $tid) {
+      $nids = db_select('field_data_' . $field, 'f')
+        ->condition('f.entity_type', 'node')
+        ->condition('f.bundle', $queue->types, 'IN')
+        ->condition('f.deleted', FALSE)
+        ->condition('f.' . $field . '_tid', $tid->tid)
+        ->fields('f', array('entity_id'))
+        ->range(0, 1)
+        ->execute()
+        ->fetchAll();
+
+      foreach ($nids as $nid) {
+        $node = node_load($nid->entity_id);
+        nodequeue_api_subqueues($queue, $node);
+      }
+
+    }
+
   }
-  $node->taxonomy = $tree;
-  $queues = nodequeue_load_queues(nodequeue_get_all_qids(200));
-  foreach ($queues as $queue) {
-    if ($queue->owner == 'smartqueue_taxonomy') {
-      nodequeue_api_subqueues($queue, $node);
+}
+
+/**
+ * Implements hook_nodequeue_generate() for owner 'nodequeue'.
+ */
+function nodequeue_nodequeue_generate($queue, $limit) {
+  $subqueues = nodequeue_load_subqueues_by_queue($queue->qid);
+  foreach ($subqueues as $subqueue) {
+    $nodes = db_select('node', 'n')
+      ->condition('n.status', NODE_PUBLISHED)
+      ->condition('n.type', $queue->types, 'IN')
+      ->orderRandom()
+      ->fields('n', array('nid'))
+      ->range(0, $limit)
+      ->execute()
+      ->fetchAll();
+
+    foreach ($nodes as $node) {
+      nodequeue_subqueue_add($queue, $subqueue, $node->nid);
     }
   }
 }
+
+/**
+ * Implements hook_nodequeue_generate() for owner 'smartqueue_taxonomy'.
+ */
+function smartqueue_taxonomy_nodequeue_generate($queue, $limit) {
+  $subqueues = nodequeue_load_subqueues_by_queue($queue->qid);
+  foreach ($subqueues as $subqueue) {
+    $nodes = db_select('taxonomy_index', 'tn');
+    $nodes->join('node', 'n', 'n.nid=tn.nid');
+    $nodes->fields('n', array('nid'));
+    $nodes->condition('n.status', NODE_PUBLISHED);
+    $nodes->condition('n.type', $queue->types, 'IN');
+    $nodes->condition('tn.tid', $subqueue->reference);
+    $nodes->orderRandom();
+    $nodes->range(0, $limit);
+    $nodes = $nodes->execute();
+    $nodes = $nodes->fetchAll();
+
+    foreach ($nodes as $node) {
+      nodequeue_subqueue_add($queue, $subqueue, $node->nid);
+    }
+  }
+}
+
+/**
+ * Implementation of hook_uninstall().
+ */
+function nodequeue_generate_uninstall() {
+  variable_del('nodequeue_generate_nodes_limit');
+}
