diff --git a/rocketship.css b/rocketship.css
new file mode 100644
index 0000000..29f88e9
--- /dev/null
+++ b/rocketship.css
@@ -0,0 +1,97 @@
+
+.rocketship-issues table {
+  width: 100%;
+}
+.rocketship-issues table tr.odd {
+  background-color: #FFFFFF;
+}
+.rocketship-issues table tr td {
+  vertical-align: top;
+  width: 33%;
+}
+.rocketship-node {
+  margin-bottom: 1em;
+  border-radius: 5px;
+  padding: 3px 5px 3px 8px;
+  -moz-box-shadow:0px 0px 6px rgba(0,0,0,0.4);
+  -webkit-box-shadow:0px 0px 6px rgba(0,0,0,0.4);
+  border-left-width: 8px;
+  border-left-color: transparent;
+  border-left-style: solid;
+  border-left-color: #F5F5F5;
+  cursor: hand;
+}
+.rocketship-node a {
+  font-weight: bold;
+}
+.rocketship-focus {
+  border-left-color: #336699;
+}
+.rocketship-major {
+  border-left-color: #FF9900;
+}
+.rocketship-critical {
+  border-left-color: #FF0000;
+}
+.rocketship-term {
+  background-color: #F5F5F5;
+  margin: 2px 6px 2px 0;
+  display: inline-block;
+  border-radius: 3px;
+  font-size: 0.8em;
+  padding: 1px 3px;
+}
+.rocketship-needs-tests {
+  font-weight: bold;
+}
+.rocketship-legend {
+  float: right;
+  font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
+  font-size: 0.8em;
+  margin-top: 0.2em;
+}
+.rocketship-legend div {
+  display: inline-block;
+  margin-left: 2px;
+}
+.rocketship-node .assigned {
+  background-color: #F5F5F5;
+  margin: 3px -5px 3px -8px;
+  padding: 1px 8px;
+  border-top: 1px dotted #DDDDDD;
+}
+.rocketship-cloud-wrapper {
+  border-bottom: 1px solid #2d2d2d;
+  border-top: 1px solid #2d2d2d;
+  margin-bottom: 2em;
+}
+.rocketship-cloud-wrapper p {
+  font-size: 0.8em;
+  margin-top: 1.3em;
+  font-style: italic;
+}
+.rocketship-cloud {
+  line-height: 1.3em;
+  text-align: justify;
+}
+.rocketship-cloud-1 {
+  font-size: 0.8em;
+}
+.rocketship-cloud-2 {
+  font-size: 1em;
+}
+.rocketship-cloud-3 {
+  font-size: 1.4em;
+}
+.rocketship-cloud-4 {
+  font-size: 1.6em;
+}
+.rocketship-cloud-5 {
+  font-size: 1.8em;
+}
+.rocketship-cloud-6 {
+  font-size: 2em;
+}
+.rocketship-cloud-recent a {
+  font-weight: bold;
+}
\ No newline at end of file
diff --git a/rocketship.install b/rocketship.install
new file mode 100644
index 0000000..2185a78
--- /dev/null
+++ b/rocketship.install
@@ -0,0 +1,329 @@
+<?php
+
+/**
+ * @file
+ * Install file.
+ */
+
+/**
+ * Implements hook_install().
+ */
+function rocketship_install() {
+
+  // Create the initiative issue content type.
+  $type = array(
+    'type' => 'initiative_issue',
+    'name' => st('Initiative issue'),
+    'description' => st('Content type used to generate issues which are pulled in from d.o.'),
+    'base' => 'node_content',
+    'custom' => 1,
+    'modified' => 1,
+    'locked' => 0,
+  );
+  $type = node_type_set_defaults($type);
+  node_type_save($type);
+
+  // Default variables for the initiative issue content type.
+  variable_set('node_preview_initiative_issue', 0);
+  variable_set('node_submitted_initiative_issue', 0);
+  variable_set('menu_options_initiative_issue', array());
+  variable_set('node_options_initiative_issue', array('status'));
+  variable_set('comment_initiative_issue', COMMENT_NODE_HIDDEN);
+
+  // Create a vocabulary named "Initiative issue tags".
+  $description = st('Use tags to group issues on similar topics into categories.');
+  $help = st('Enter a comma-separated list of words to describe the issue.');
+  $issue_tags_vocabulary = (object) array(
+    'name' => st('Iniative issue tags'),
+    'description' => $description,
+    'machine_name' => 'initiative_tags',
+    'help' => $help,
+
+  );
+  taxonomy_vocabulary_save($issue_tags_vocabulary);
+
+  // Save the vocabulary id.
+  variable_set('rocketship_issue_tags_vid', $issue_tags_vocabulary->vid);
+
+  $field = array(
+    'field_name' => 'field_initiative_issue_tags',
+    'type' => 'taxonomy_term_reference',
+    // Set cardinality to unlimited for tagging.
+    'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+    'settings' => array(
+      'allowed_values' => array(
+        array(
+          'vocabulary' => $issue_tags_vocabulary->machine_name,
+          'parent' => 0,
+        ),
+      ),
+    ),
+  );
+  field_create_field($field);
+
+  $instance = array(
+    'field_name' => 'field_initiative_issue_tags',
+    'entity_type' => 'node',
+    'label' => 'Initiative issue tags',
+    'bundle' => 'initiative_issue',
+    'description' => $issue_tags_vocabulary->help,
+    'widget' => array(
+      'type' => 'taxonomy_autocomplete',
+      'weight' => -4,
+    ),
+    'display' => array(
+      'default' => array(
+        'type' => 'taxonomy_term_reference_link',
+        'weight' => 10,
+      ),
+      'teaser' => array(
+        'type' => 'taxonomy_term_reference_link',
+        'weight' => 10,
+      ),
+    ),
+  );
+  field_create_instance($instance);
+
+  // Create a textfield named "Assigned".
+  $field = array(
+    'field_name' => 'field_initiative_issue_assigned',
+    'type' => 'text',
+    'cardinality' => 1,
+    'settings' => array()
+  );
+  field_create_field($field);
+
+  $instance = array(
+    'field_name' => 'field_initiative_issue_assigned',
+    'entity_type' => 'node',
+    'label' => 'Assigned',
+    'bundle' => 'initiative_issue',
+    'description' => st("The d.o username to whom this issue is assigned."),
+    'widget' => array(
+      'type' => 'text_textfield',
+      'weight' => -3,
+    ),
+    'display' => array(
+      'default' => array(
+        'type' => 'text_default',
+        'label' => 'inline',
+        'weight' => 9,
+      ),
+      'teaser' => array(
+        'type' => 'text_default',
+        'label' => 'inline',
+        'weight' => 9,
+      ),
+    ),
+  );
+  field_create_instance($instance);
+
+  // Create a vocabulary named "Initiative issue tags".
+  $description = st('Use tags for projects.');
+  $project_tag_vocabulary = (object) array(
+    'name' => st('Project'),
+    'description' => $description,
+    'machine_name' => 'initiative_project',
+
+  );
+  taxonomy_vocabulary_save($project_tag_vocabulary);
+
+  // Save the vocabulary id.
+  variable_set('rocketship_issue_project_vid', $project_tag_vocabulary->vid);
+
+  $field = array(
+    'field_name' => 'field_initiative_issue_project',
+    'type' => 'taxonomy_term_reference',
+    // Set cardinality to unlimited for tagging.
+    'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+    'settings' => array(
+      'allowed_values' => array(
+        array(
+          'vocabulary' => $project_tag_vocabulary->machine_name,
+          'parent' => 0,
+        ),
+      ),
+    ),
+  );
+  field_create_field($field);
+
+  $instance = array(
+    'field_name' => 'field_initiative_issue_project',
+    'entity_type' => 'node',
+    'label' => 'Initiative project tag',
+    'bundle' => 'initiative_issue',
+    'description' => $project_tag_vocabulary->help,
+    'widget' => array(
+      'type' => 'taxonomy_autocomplete',
+      'weight' => -4,
+    ),
+    'display' => array(
+      'default' => array(
+        'type' => 'taxonomy_term_reference_link',
+        'weight' => 10,
+      ),
+      'teaser' => array(
+        'type' => 'taxonomy_term_reference_link',
+        'weight' => 10,
+      ),
+    ),
+  );
+  field_create_instance($instance);
+  
+  // Create the initiative page content type.
+  $initiative_page_type = array(
+    'type' => 'initiative_page',
+    'name' => st('Initiative page'),
+    'description' => st('Use this content type to create initiative pages.'),
+    'base' => 'node_content',
+    'custom' => 1,
+    'modified' => 1,
+    'locked' => 0,
+  );
+  $initiative_page_type = node_type_set_defaults($initiative_page_type);
+  node_type_save($initiative_page_type);
+
+  // Default variables for the initiative pages content type.
+  variable_set('node_preview_initiative_page', 0);
+  variable_set('node_submitted_initiative_page', 0);
+  variable_set('menu_options_initiative_page', array());
+  variable_set('node_options_initiative_page', array('status'));
+  variable_set('comment_initiative_page', COMMENT_NODE_HIDDEN);
+
+  // Create a vocabulary named "Initiative master tags".
+  $description = st('Enter the master tags which will be used to grab issues from d.o for this initiative.');
+  $help = st('Select the main master tag');
+  $master_tag_vocabulary = (object) array(
+    'name' => st('Iniative master tag'),
+    'description' => $description,
+    'machine_name' => 'initiative_master_tags',
+    'help' => $help,
+
+  );
+  taxonomy_vocabulary_save($master_tag_vocabulary);
+
+  // Save the vocabulary id.
+  variable_set('rocketship_master_tags_vid', $master_tag_vocabulary->vid);
+
+  $field = array(
+    'field_name' => 'field_initiative_master_tag',
+    'type' => 'taxonomy_term_reference',
+    'cardinality' => 1,
+    'settings' => array(
+      'allowed_values' => array(
+        array(
+          'vocabulary' => $master_tag_vocabulary->machine_name,
+          'parent' => 0,
+        ),
+      ),
+    ),
+  );
+  field_create_field($field);
+
+  $instance = array(
+    'field_name' => 'field_initiative_master_tag',
+    'entity_type' => 'node',
+    'label' => 'Initiative master tag',
+    'bundle' => 'initiative_page',
+    'description' => $master_tag_vocabulary->help,
+    'widget' => array(
+      'type' => 'taxonomy_select',
+      'weight' => -4,
+      'required' => TRUE,
+    ),
+    'display' => array(
+      'default' => array(
+        'type' => 'taxonomy_term_reference_link',
+        'weight' => 10,
+      ),
+      'teaser' => array(
+        'type' => 'taxonomy_term_reference_link',
+        'weight' => 10,
+      ),
+    ),
+  );
+  field_create_instance($instance);
+
+  // Issue display tag, on initiative page.
+  $field = array(
+    'field_name' => 'field_initiative_display_tag',
+    'type' => 'taxonomy_term_reference',
+    'cardinality' => 1,
+    'settings' => array(
+      'allowed_values' => array(
+        array(
+          'vocabulary' => $issue_tags_vocabulary->machine_name,
+          'parent' => 0,
+        ),
+      ),
+    ),
+  );
+  field_create_field($field);
+
+  $instance = array(
+    'field_name' => 'field_initiative_display_tag',
+    'entity_type' => 'node',
+    'label' => 'Initiative display tag',
+    'bundle' => 'initiative_page',
+    'description' => st('Select one tag to display issues from.'),
+    'widget' => array(
+      'type' => 'taxonomy_autocomplete',
+      'weight' => -3,
+    ),
+    'display' => array(
+      'default' => array(
+        'type' => 'taxonomy_term_reference_link',
+        'weight' => 10,
+      ),
+      'teaser' => array(
+        'type' => 'taxonomy_term_reference_link',
+        'weight' => 10,
+      ),
+    ),
+  );
+  field_create_instance($instance);
+
+  // Issue project tag, on initiative page.
+  $field = array(
+    'field_name' => 'field_initiative_display_project',
+    'type' => 'taxonomy_term_reference',
+    'cardinality' => 1,
+    'settings' => array(
+      'allowed_values' => array(
+        array(
+          'vocabulary' => $project_tag_vocabulary->machine_name,
+          'parent' => 0,
+        ),
+      ),
+    ),
+  );
+  field_create_field($field);
+
+  $instance = array(
+    'field_name' => 'field_initiative_display_project',
+    'entity_type' => 'node',
+    'label' => 'Initiative project tag',
+    'bundle' => 'initiative_page',
+    'description' => st('Select one project to display issues from.'),
+    'widget' => array(
+      'type' => 'taxonomy_autocomplete',
+      'weight' => -3,
+    ),
+    'display' => array(
+      'default' => array(
+        'type' => 'taxonomy_term_reference_link',
+        'weight' => 10,
+      ),
+      'teaser' => array(
+        'type' => 'taxonomy_term_reference_link',
+        'weight' => 10,
+      ),
+    ),
+  );
+  field_create_instance($instance);
+  
+  // Create initiative page body field. We do this here, so it
+  // appears at the bottom of the node form.
+  node_add_body_field($initiative_page_type);
+
+}
\ No newline at end of file
diff --git a/rocketship.js b/rocketship.js
new file mode 100644
index 0000000..2f27d74
--- /dev/null
+++ b/rocketship.js
@@ -0,0 +1,15 @@
+
+(function ($) {
+
+// UX: Extend click from rocketship-node container to the link inside.
+// I know this looks ugly. It is a quick stop-gap, tips welcome.
+$(document).ready(function() {
+  $('.rocketship-node').click(function() {
+    var link = $(this).find('a');
+    if (link.length) {
+      window.location = link.attr('href');
+    }
+  });
+});
+
+})(jQuery);
\ No newline at end of file
diff --git a/rocketship.module b/rocketship.module
index a42eccc..fff66c4 100644
--- a/rocketship.module
+++ b/rocketship.module
@@ -5,6 +5,8 @@
  * Issue crawler/scraper and display module built for the Drupal 8 Multilingual Initiative.
  */
 
+define('ROCKETSHIP_VERBOSE_MODE', TRUE);
+
 /**
  * All issues should be tagged with this tag.
  */
@@ -16,31 +18,44 @@ define('ROCKETSHIP_MASTER_TAG', 'D8MI');
 define('ROCKETSHIP_LEAD_USER', 'Gábor Hojtsy');
 
 /**
- * Local node type for storing the cached issues.
- *
- * Assumptions about this node type:
- * - it has a regular title and body
- * - it has a field_assigned single value, one line text field
- * - it has a tags reference field named "field_issue_tags" using tags from ROCKETSHIP_TAGS_VID
- */
-define('ROCKETSHIP_NODE_TYPE', 'issue');
-
-/**
- * Vocabulary ID for the local issue tags vocabulary.
+ * Node type for storing the cached issues.
  */
-define('ROCKETSHIP_TAGS_VID', 6);
+define('ROCKETSHIP_NODE_TYPE', 'initiative_issue');
 
 /**
  * Implements hook_menu().
  */
 function rocketship_menu() {
-  // Quick and dirty menu item to invoke local cache refresh.
-  $items['admin/rocketship'] = array(
+
+  $items['admin/config/rocketship'] = array(
     'title' => 'Rocketship',
+    'description' => 'Syntra configuration.',
+    'position' => 'left',
+    'weight' => -50,
+    'page callback' => 'system_admin_menu_block_page',
+    'access arguments' => array('access administration pages'),
+    'file' => 'system.admin.inc',
+    'file path' => drupal_get_path('module', 'system'),
+  );
+
+  $items['admin/config/rocketship/settings'] = array(
+    'title' => 'Settings',
+    'description' => 'Configure Rocketship settings.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('rocketship_settings_form'),
+    'access arguments' => array('adminster rocketship'),
+    'weight' => -1,
+  );
+
+  $items['admin/config/rocketship/manual'] = array(
+    'title' => 'Manual',
+    'description' => 'Manually parse the issues instead of cron.',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('rocketship_launch_form'),
-    'access arguments' => array('access administration pages'),
+    'access arguments' => array('adminster rocketship'),
+    'weight' => 0,
   );
+
   return $items;
 }
 
@@ -50,12 +65,52 @@ function rocketship_menu() {
 function rocketship_cron() {
   // An hour should pass at least inbetween local cache refreshes.
   if (variable_get('rocketship_parse_time', 0) < time()-60*60) {
-    rocketship_parse_all();
+    $issue_page = "http://drupal.org/project/issues/flot?version=7.x";
+      rocketship_parse_all($issue_page);
+    $issue_page = "http://drupal.org/project/user/829198";
+      rocketship_parse_all($issue_page);
+    $issue_page = "http://drupal.org/project/issues/user/105002";
+      rocketship_parse_all($issue_page);
     variable_set('rocketship_parse_time', time());
   }
 }
 
 /**
+ * Form callback for general settings form.
+ */
+function rocketship_settings_form() {
+
+  $vocabulary_options = array();
+  $vocabulary_names = taxonomy_vocabulary_get_names();
+  foreach ($vocabulary_names as $key => $info) {
+    $vocabulary_options[$info->vid] = $info->name;
+  }
+
+  $form['rocketship_issue_tags_vid'] = array(
+    '#type' => 'select',
+    '#title' => t('Issue tags vocabulary ID'),
+    '#default_value' => variable_get('rocketship_issue_tags_vid'),
+    '#options' => $vocabulary_options,
+    '#required' => TRUE,
+  );
+  $form['rocketship_issue_project_vid'] = array(
+    '#type' => 'select',
+    '#title' => t('Project vocabulary ID'),
+    '#default_value' => variable_get('rocketship_issue_project_vid'),
+    '#options' => $vocabulary_options,
+    '#required' => TRUE,
+  );
+  $form['rocketship_master_tags_vid'] = array(
+    '#type' => 'select',
+    '#title' => t('Master tags vocabulary ID'),
+    '#default_value' => variable_get('rocketship_master_tags_vid'),
+    '#options' => $vocabulary_options,
+    '#required' => TRUE,
+  );
+  return system_settings_form($form);
+}
+
+/**
  * Form callback for launching a manual rocketship refresh.
  */
 function rocketship_launch_form() {
@@ -71,35 +126,65 @@ function rocketship_launch_form() {
  * Form submission callback for rocketship launch.
  */
 function rocketship_launch_form_submit() {
-  rocketship_parse_all();
+  $issue_page = "http://drupal.org/project/issues/flot?version=7.x";
+    rocketship_parse_all($issue_page);
+  $issue_page = "http://drupal.org/project/user/829198";
+    rocketship_parse_all($issue_page);
+  $issue_page = "http://drupal.org/project/issues/user/105002";
+    rocketship_parse_all($issue_page);
+  drupal_set_message(t('Issues have been parsed.'));
 }
 
 /**
  * Crawler for drupal.org issue listings.
  */
-function rocketship_parse_all() {
+function rocketship_parse_all($issue_page = '') {
+  if (empty($issue_page)) {
+    $issue_page = 'http://drupal.org/project/issues/search/drupal?issue_tags=' . ROCKETSHIP_MASTER_TAG;
+  }
+  if (ROCKETSHIP_VERBOSE_MODE) {
+    watchdog('Rocketship', 'Parsing ' . $issue_page);
+  }
   // Grab the first page of the listings of issues for this tag.
-  $issue_page = 'http://drupal.org/project/issues/search/drupal?issue_tags=' . ROCKETSHIP_MASTER_TAG;
   $page_output = drupal_http_request($issue_page);
   if ($page_output->code == 200 && !empty($page_output->data)) {
 
     // Figure out the index number of the last issue list page by scraping.
     $last_page_num = 0;
     if (preg_match('!href="([^"]+)" title="Go to last page"!', $page_output->data, $last_page)) {
-  	  if (preg_match('!\?page=(\d+)&!', $last_page[1], $last_page_find)) {
+
+  	  if (preg_match('!\?page=(\d+)!', $last_page[1], $last_page_find)) {
         $last_page_num = $last_page_find[1];
       }
     }
 
     // Parse this page for issue links and grab those issue nodes.
-    rocketship_parse_issue_page($page_output->data);
+    if (!rocketship_parse_issue_page($page_output->data)) {
+      if (ROCKETSHIP_VERBOSE_MODE) {
+        watchdog('Rocketship', 'Bailing out');
+      }
+      return;
+    }
 
     // If we have more pages, go on to the rest of the pages as well.
     if (!empty($last_page_num)) {
       for ($page_num = 1; $page_num <= $last_page_num; $page_num++) {
-        $page_output = drupal_http_request($issue_page . '&page='. $page_num);
+        if (strpos($issue_page, '?')) {
+          $page_output = drupal_http_request($issue_page . '&page='. $page_num);
+        }
+        else {
+          $page_output = drupal_http_request($issue_page . '?page='. $page_num);
+        }
         if ($page_output->code == 200 && !empty($page_output->data)) {
-          rocketship_parse_issue_page($page_output->data);
+          if (!rocketship_parse_issue_page($page_output->data)) {
+            if (ROCKETSHIP_VERBOSE_MODE) {
+              watchdog('Rocketship', 'Bailing out');
+            }
+            return;
+          }
+        }
+        else {
+          watchdog('attiks', 'paging failed for page ' . $page_num . ' (' . $issue_page . '?page='. $page_num . ')');
         }
       }
     }
@@ -163,6 +248,9 @@ function rocketship_parse_issue_page(&$issue_page_content) {
         $nid = db_query("SELECT nid FROM {node} WHERE type = :type AND title LIKE '#" . (int) $match . ":%'", array(':type' => ROCKETSHIP_NODE_TYPE))->fetchField();
         if ($nid) {
           $node = node_load($nid);
+          if (ROCKETSHIP_VERBOSE_MODE) {
+            watchdog('Rocketship', 'Found node ' . $node->title . ' (' . $node->changed . ')');
+          }
         }
         else {
           // Save nodes as published. Although this would "litter" your tracker
@@ -175,6 +263,7 @@ function rocketship_parse_issue_page(&$issue_page_content) {
         // Grab node title based on drupal.org HTML markup.
         if (preg_match('!<h1 id="page-subtitle">([^<]+)</h1>!', $issue_node->data, $page_title)) {
           $node->title = '#'. (int) $match . ': '. htmlspecialchars_decode($page_title[1], ENT_QUOTES);
+          $node->field_initiative_drupalorg_nid['und'][0]['value'] = (int) $match;
         }
 
         // Grab time created based on the markup.
@@ -183,15 +272,55 @@ function rocketship_parse_issue_page(&$issue_page_content) {
         }
 
         // Find all participats and count their comments.
+        $last_update = '';
         if (preg_match_all('!<div class="submitted">Posted by <a href="/user/(\d+)"[^>]+>([^<]+)</a> on <em>(.+)</em>!', $issue_node->data, $participants)) {
           foreach ($participants[2] as $i => $participant) {
             rocketship_stat_add_username($participant, $participants[1][$i], strtotime(str_replace(' at ', ', ', $participants[3][$i])));
           }
+          $last_update = array_pop($participants[3]);
+          $last_update = strtotime(str_replace(' at ', ', ', $last_update));
+        }
+        
+        // If last_update <= $node->changed, return
+        if (isset($node->nid)) {
+          if (!empty($last_update) && $node->changed == $last_update) {
+            if (ROCKETSHIP_VERBOSE_MODE) {
+              watchdog('Rocketship', 'No updated needed for ' . $node->title);
+            }
+            return FALSE;
+          }
+          else {
+            if (ROCKETSHIP_VERBOSE_MODE) {
+              watchdog('Rocketship', 'Updated needed for ' . $node->title . ': ' . $node->changed . ' - ' . $last_update);
+            }
+          }
         }
 
         // Assumes a "field_assigned" text field is present on this node type.
         if (preg_match('!<td>Assigned:</td><td>(.*)</td>!', $issue_node->data, $assigned)) {
-          $node->field_assigned['und'][0]['value'] = strip_tags($assigned[1]);
+          $node->field_initiative_issue_assigned['und'][0]['value'] = strip_tags($assigned[1]);
+        }
+
+        if (preg_match('!<td>Project:</td><td>(.*)</td>!', $issue_node->data, $project)) {
+          $project = $project[1];
+          $node->field_initiative_issue_project['und'] = array();
+          $matching_terms = taxonomy_get_term_by_name($project, variable_get('rocketship_issue_project_vid'));
+          if (!empty($matching_terms)) {
+            foreach ($matching_terms as $term) {
+              if ($term->vid == variable_get('rocketship_issue_project_vid')) {
+                $node->field_initiative_issue_project['und'][] = array('tid' => $term->tid);
+              }
+            }
+          }
+          else {
+            // Not found, so create a new tag and assign.
+            $term = (object) array(
+              'vid' => variable_get('rocketship_issue_project_vid'),
+              'name' => $project,
+            );
+            taxonomy_term_save($term);
+            $node->field_initiative_issue_project['und'][] = array('tid' => $term->tid);
+          }
         }
 
         // Store all kinds of metadata as plain tags on this node. We can then
@@ -220,41 +349,50 @@ function rocketship_parse_issue_page(&$issue_page_content) {
 
         // Now try and find existing tags with matching names if present or
         // create the new tags if needed.
-        $node->field_issue_tags['und'] = array();
+        $node->field_initiative_issue_tags['und'] = array();
         foreach($tags as $tag) {
           // This is an ugly pattern but there might be multiple matching
           // terms, so we need to find the one matching in our vocabulary.
           $matching_terms = taxonomy_get_term_by_name($tag);
           if (!empty($matching_terms)) {
             foreach ($matching_terms as $term) {
-              if ($term->vid == ROCKETSHIP_TAGS_VID) {
-                $node->field_issue_tags['und'][] = array('tid' => $term->tid);
+              if ($term->vid == variable_get('rocketship_issue_tags_vid')) {
+                $node->field_initiative_issue_tags['und'][] = array('tid' => $term->tid);
               }
             }
           }
           else {
             // Not found, so create a new tag and assign.
             $term = (object) array(
-              'vid' => ROCKETSHIP_TAGS_VID,
+              'vid' => variable_get('rocketship_issue_tags_vid'),
               'name' => $tag,
             );
             taxonomy_term_save($term);
-            $node->field_issue_tags['und'][] = array('tid' => $term->tid);
+            $node->field_initiative_issue_tags['und'][] = array('tid' => $term->tid);
           }
         }
 
         // Save our updated / created node.
         node_save($node);
+        if (!empty($last_update)) {
+          db_update('node') // Table name no longer needs {}
+            ->fields(array(
+              'changed' => $last_update,
+            ))
+            ->condition('nid', $node->nid, '=')
+            ->execute();          
+        }
       }
     }
   }
+  return TRUE;
 }
 
 /**
  * Display controlled for nodes.
  *
  * This assumes nodes where we want to display a list of issues have a
- * "field_issue_tag_display" single value taxonomy term reference field,
+ * "field_initiative_display_tag" single value taxonomy term reference field,
  * which designates the tag that we want to dive into (from all the)
  * issues that we gathered. This can be equal to ROCKETSHIP_MASTER_TAG
  * if we want a list of all locally cached issues.
@@ -263,17 +401,29 @@ function rocketship_parse_issue_page(&$issue_page_content) {
  * display them by their group to help produce a visual overview.
  */
 function rocketship_node_view($node, $view_mode, $langcode) {
-  if (!empty($node->field_issue_tag_display['und'])) {
+  if ((!empty($node->field_initiative_display_tag) || !empty($node->field_initiative_display_project)) && $view_mode == 'full') {
+
+    // Javascript and CSS.
+    $attached = array(
+      'css' => array(drupal_get_path('module', 'rocketship') . '/rocketship.css'),
+      'js' => array(drupal_get_path('module', 'rocketship') . '/rocketship.js'),
+    );
 
     // Get more info on the term we are presenting this list for.
-    $tid_for_list = $node->field_issue_tag_display['und'][0]['tid'];
-    $term_for_list = taxonomy_term_load($tid_for_list);
+    if (!empty($node->field_initiative_display_tag)) {
+      $tid_for_list = $node->field_initiative_display_tag['und'][0]['tid'];
+      $term_for_list = taxonomy_term_load($tid_for_list);
+    }
+    elseif (!empty($node->field_initiative_display_project)) {
+      $tid_for_list = $node->field_initiative_display_project['und'][0]['tid'];
+      $term_for_list = taxonomy_term_load($tid_for_list);
+    }
 
     // Get all the issue nodes that have the tag we need.
     $nids = db_query('SELECT nid FROM {taxonomy_index} WHERE tid = :tid', array(':tid' => $tid_for_list))->fetchAll();
 
     // Look up a cached version for this term if we have it and
-    // it is not yet expired (no newer nodes of the issue type
+    // if is not yet expired (no newer nodes of the issue type
     // available yet).
     if ($cache = cache_get('rocketship:' . $tid_for_list)) {
       $last_issue_update = db_query("SELECT changed FROM {node} WHERE type = :type ORDER BY created DESC", array(':type' => ROCKETSHIP_NODE_TYPE))->fetchField();
@@ -282,6 +432,7 @@ function rocketship_node_view($node, $view_mode, $langcode) {
           '#markup' => $cache->data,
           // Place at the end of the page after book navigation (if present).
           '#weight' => 200,
+          '#attached' => $attached,
         );
         return;
       }
@@ -319,7 +470,7 @@ function rocketship_node_view($node, $view_mode, $langcode) {
       foreach ($terms[0] as &$term_name) {
         if ($matching_terms = taxonomy_get_term_by_name($term_name)) {
           foreach ($matching_terms as $term) {
-            if ($term->vid == ROCKETSHIP_TAGS_VID) {
+            if ($term->vid == variable_get('rocketship_issue_tags_vid')) {
               // Replace term name in $columns with term ID (the variable
               // is taken by reference, so we directly modify the arary here).
               $term_name = $term->tid;
@@ -343,9 +494,9 @@ function rocketship_node_view($node, $view_mode, $langcode) {
     $nodes = array();
     foreach($nids as $nid) {
       $issue_node = node_load($nid->nid);
-      // Tags on the issue node should be referenced in field_issue_tags[].
-      if (!empty($issue_node->field_issue_tags['und'])) {
-        foreach ($issue_node->field_issue_tags['und'] as $tag_info) {
+      // Tags on the issue node should be referenced in field_initiative_issue_tags[].
+      if (!empty($issue_node->field_initiative_issue_tags['und'])) {
+        foreach ($issue_node->field_initiative_issue_tags['und'] as $tag_info) {
           if (in_array($tag_info['tid'], $status_tids)) {
             // If this was a status tid, look at which group it is in,
             // in which case we found where to categorize the node.
@@ -376,7 +527,7 @@ function rocketship_node_view($node, $view_mode, $langcode) {
           $classes = 'rocketship-node';
           $cell_terms = '';
           $priority = 0;
-          foreach ($issue_node->field_issue_tags['und'] as $tag_info) {
+          foreach ($issue_node->field_initiative_issue_tags['und'] as $tag_info) {
             $term = taxonomy_term_load($tag_info['tid']);
             $term_class = 'rocketship-term';
             switch($term->name) {
@@ -407,7 +558,7 @@ function rocketship_node_view($node, $view_mode, $langcode) {
             // already represented, and the current page tag is presented on
             // the page, so again no need to repeat it on all nodes (it is not
             // a distinguishing factor).
-            if (!in_array($term->name, array(ROCKETSHIP_MASTER_TAG, 'reviewed & tested by the community', 'needs review', '8.x-dev', $term_for_list->name))) {
+            if (!in_array($term->name, array(variable_get('rocketship_master_tag'), 'reviewed & tested by the community', 'needs review', '8.x-dev', $term_for_list->name))) {
               // Add up all terms with their respective tags.
               $cell_terms .= '<span class="'. $term_class . '">'. check_plain($term->name) .'</span>';
             }
@@ -422,8 +573,8 @@ function rocketship_node_view($node, $view_mode, $langcode) {
           $drupalorg_nid = preg_replace('!#(\d+):(.*)$!', '\1', $issue_node->title);
           $cell[$priority] .= '<div class="' . $classes . '">'. l($issue_node->title, 'http://drupal.org/node/'. $drupalorg_nid) .'<br />';
           $cell[$priority] .= $cell_terms;
-          if (!empty($issue_node->field_assigned['und'][0]['value']) && $issue_node->field_assigned['und'][0]['value'] != 'Unassigned') {
-            $cell[$priority] .= '<div class="assigned">' . t('Assigned to @assigned', array('@assigned' => $issue_node->field_assigned['und'][0]['value'])) . "</div>";
+          if (!empty($issue_node->field_initiative_issue_assigned['und'][0]['value']) && $issue_node->field_initiative_issue_assigned['und'][0]['value'] != 'Unassigned') {
+            $cell[$priority] .= '<div class="assigned">' . t('Assigned to @assigned', array('@assigned' => $issue_node->field_initiative_issue_assigned['und'][0]['value'])) . "</div>";
           }
           $cell[$priority] .= '</div>';
         }
@@ -438,121 +589,7 @@ function rocketship_node_view($node, $view_mode, $langcode) {
       $header_data[$columns_data[1]][] = $header;
     }
 
-    // Styling and some usabiltiy improvement JS included inline. This is indeed
-    // very ugly but is quickly accessible for development and can be refactored
-    // later.
-    $output .= <<<STYLE
-<div class="rocketship-issues">
-<script>
-// UX: Extend click from rocketship-node container to the link inside.
-// I know this looks ugly. It is a quick stop-gap, tips welcome.
-jQuery(document).ready(function($) {
-  $('.rocketship-node').click(function() {
-    var link = $(this).find('a');
-    if (link.length) {
-      window.location = link.attr('href');
-    }
-  });
-});
-</script>
-<style>
-  .rocketship-issues table {
-    width: 100%;
-  }
-  .rocketship-issues table tr.odd {
-    background-color: #FFFFFF;
-  }
-  .rocketship-issues table tr td {
-    vertical-align: top;
-    width: 33%;
-  }
-  .rocketship-node {
-    margin-bottom: 1em;
-    border-radius: 5px;
-    padding: 3px 5px 3px 8px;
-    -moz-box-shadow:0px 0px 6px rgba(0,0,0,0.4);
-    -webkit-box-shadow:0px 0px 6px rgba(0,0,0,0.4);
-    border-left-width: 8px;
-    border-left-color: transparent;
-    border-left-style: solid;
-    border-left-color: #F5F5F5;
-  }
-  .rocketship-node a {
-    font-weight: bold;
-  }
-  .rocketship-focus {
-    border-left-color: #336699;
-  }
-  .rocketship-major {
-    border-left-color: #FF9900;
-  }
-  .rocketship-critical {
-    border-left-color: #FF0000;
-  }
-  .rocketship-term {
-    background-color: #F5F5F5;
-    margin: 2px 6px 2px 0;
-    display: inline-block;
-    border-radius: 3px;
-    font-size: 0.8em;
-    padding: 1px 3px;
-  }
-  .rocketship-needs-tests {
-    font-weight: bold;
-  }
-  .rocketship-legend {
-    float: right;
-    font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
-    font-size: 0.8em;
-    margin-top: 0.2em;
-  }
-  .rocketship-legend div {
-    display: inline-block;
-    margin-left: 2px;
-  }
-  .rocketship-node .assigned {
-    background-color: #F5F5F5;
-    margin: 3px -5px 3px -8px;
-    padding: 1px 8px;
-    border-top: 1px dotted #DDDDDD;
-  }
-  .rocketship-cloud-wrapper {
-    border-bottom: 1px solid #2d2d2d;
-    border-top: 1px solid #2d2d2d;
-    margin-bottom: 2em;
-  }
-  .rocketship-cloud-wrapper p {
-    font-size: 0.8em;
-    margin-top: 1.3em;
-    font-style: italic;
-  }
-  .rocketship-cloud {
-    line-height: 1.3em;
-    text-align: justify;
-  }
-  .rocketship-cloud-1 {
-    font-size: 0.8em;
-  }
-  .rocketship-cloud-2 {
-    font-size: 1em;
-  }
-  .rocketship-cloud-3 {
-    font-size: 1.4em;
-  }
-  .rocketship-cloud-4 {
-    font-size: 1.6em;
-  }
-  .rocketship-cloud-5 {
-    font-size: 1.8em;
-  }
-  .rocketship-cloud-6 {
-    font-size: 2em;
-  }
-  .rocketship-cloud-recent a {
-    font-weight: bold;
-  }
-</style>
-STYLE;
+    $output = '';
 
     // Produce a short legend to be included with each table.
     $legend = '<div class="rocketship-legend">Legend: <div class="rocketship-critical rocketship-node">Critical issue</div> <div class="rocketship-major rocketship-node">Major issue</div> <div class="rocketship-focus rocketship-node">Current top priority</div></div>';
@@ -571,7 +608,7 @@ STYLE;
 
     // Include username cloud if the master tag is displayed.
     $participant_stats = variable_get('rocketship_participant_stats', array());
-    if ($term_for_list->name == ROCKETSHIP_MASTER_TAG && !empty($participant_stats)) {
+    if (!empty($participant_stats)) {
       $participant_uids = variable_get('rocketship_participant_uids', array());
       $participant_recent = variable_get('rocketship_participant_recent', array());
 
@@ -609,6 +646,7 @@ STYLE;
       '#markup' => $output,
       // Place at the end of the page after book navigation (if present).
       '#weight' => 200,
+      '#attached' => $attached,
     );
   }
 }
