diff --git a/project_solr.module b/project_solr.module
index c1828e3..a16a902 100644
--- a/project_solr.module
+++ b/project_solr.module
@@ -1,5 +1,9 @@
 <?php
 
+// Split out the forms and blocks to separate files for easier readability
+module_load_include('inc', 'project_solr', 'project_solr.blocks');
+module_load_include('inc', 'project_solr', 'project_solr.forms');
+
 //----------------------------------------
 // Core hooks
 //----------------------------------------
@@ -14,6 +18,7 @@ function project_solr_menu() {
     'description' => '',
     'page callback' => 'project_solr_browse_summary_page',
     'access arguments' => array('access content'),
+    'file' => 'project_solr.pages.inc',
     'type' => MENU_NORMAL_ITEM,
   );
   $items['project/%'] = array(
@@ -22,6 +27,7 @@ function project_solr_menu() {
     'page callback' => 'project_solr_browse_page',
     'page arguments' => array(1),
     'access arguments' => array('access content'),
+    'file' => 'project_solr.pages.inc',
     'type' => MENU_NORMAL_ITEM,
   );
   $items['project/%project_type/categories'] = array(
@@ -29,6 +35,7 @@ function project_solr_menu() {
     'page callback' => 'project_solr_category_page',
     'page arguments' => array(1),
     'access arguments' => array('access content'),
+    'file' => 'project_solr.pages.inc',
     'type' => MENU_NORMAL_ITEM,
   );
   return $items;
@@ -111,7 +118,7 @@ function project_solr_facetapi_facet_info($searcher_info) {
   $facets = array();
   if (module_exists('project_usage')) {
     $facets['sort_most_installed'] = array(
-      'field' => 'sis_project_release_usage',
+      'field' => 'iss_project_release_usage',
       'label' => t('Most installed'),
       'description' => t('Filter Most installed'),
       'default sorts' => array(
@@ -121,6 +128,39 @@ function project_solr_facetapi_facet_info($searcher_info) {
       ),
     );
   }
+  $facets["im_vid_" . _project_get_vid()] = array(
+    'field' => "im_vid_" . _project_get_vid(),
+    'label' => t('Project Category'),
+    'description' => t('Project Category'),
+    'map callback' => 'facetapi_map_taxonomy_terms',
+    'hierarchy callback' => 'facetapi_get_taxonomy_hierarchy',
+    'default sorts' => array(
+      array('active', SORT_DESC),
+      array('count', SORT_DESC),
+      array('display', SORT_DESC),
+    ),
+  );
+  $facets['im_project_release_api_tids'] = array(
+    'field' => 'im_project_release_api_tids',
+    'field alias' => variable_get('project_solr_project_release_api_tids_alias', 'drupal_core'),
+    'label' => t('Drupal Core API Version'),
+    'description' => t('Drupal Core API Version'),
+    'default sorts' => array(
+      array('active', SORT_DESC),
+      array('count', SORT_DESC),
+      array('display', SORT_DESC),
+    ),
+  );
+  $facets['bs_project_sandbox'] = array(
+    'field' => 'bs_project_sandbox',
+    'label' => t('Release Status'),
+    'description' => t('Release Status'),
+    'default sorts' => array(
+      array('active', SORT_DESC),
+      array('count', SORT_DESC),
+      array('display', SORT_DESC),
+    ),
+  );
   return $facets;
 }
 
@@ -136,14 +176,24 @@ function project_solr_facetapi_facet_info($searcher_info) {
  * to access any project-specifc data.
  */
 function project_solr_apachesolr_index_document_build_node(ApacheSolrDocument $document, $node, $env_id) {
+  // Adding a single string field of the uri of the project
   if (!empty($node->project['uri'])) {
     $document->addField('ss_project_uri', $node->project['uri']);
   }
+  // Adding a single boolean field wether it is a sandbox or not
   if (!empty($node->project)) {
-    // The initial "bs" is for boolean/single.
     $project_is_sandbox = !empty($node->project['sandbox']) ? '1' : '0';
     $document->addField('bs_project_sandbox', $project_is_sandbox);
   }
+
+  // Adding the Project vocabulary term manually to the document
+  $terms = taxonomy_node_get_terms_by_vocabulary($node, _project_get_vid());
+  if (!empty($terms)) {
+    foreach ($terms as $term_id => $term) {
+      $document->setMultiValue("im_vid_" . _project_get_vid(), $term->tid);
+    }
+  }
+
   if (module_exists('project_release') && !empty($node->project_release['releases'])) {
     $document->addField('bs_project_has_releases', '1');
 
@@ -169,6 +219,7 @@ function project_solr_apachesolr_index_document_build_node(ApacheSolrDocument $d
         ORDER BY f.timestamp DESC";
       $latest_activity = db_fetch_object(db_query_range($raw_latest_activity_query, $term->tid, $node->nid, 0, 1));
       $filetime = $latest_activity->timestamp;
+      // Adding a date single field of the latest activity of the term
       $key = 'ds_project_latest_activity_'. $term->tid;
       $document->addField($key, apachesolr_date_iso($filetime));
       if ($filetime > $max_filetime) {
@@ -179,6 +230,7 @@ function project_solr_apachesolr_index_document_build_node(ApacheSolrDocument $d
       $key = 'ds_project_latest_release_'. $term->tid;
       if ($latest_activity->rebuild == 0) {
         // The latest activity is official, we're done.
+        // Adding a date single field of the latest activity of the term
         $document->addField($key, apachesolr_date_iso($filetime));
         if ($filetime > $max_official_filetime) {
           $max_official_filetime = $filetime;
@@ -195,6 +247,7 @@ function project_solr_apachesolr_index_document_build_node(ApacheSolrDocument $d
           ORDER BY f.timestamp DESC";
         $filetime = db_result(db_query_range($raw_filetime_query, $term->tid, $node->nid, 0, 1));
         if (!empty($filetime)) {
+          // Adding a date single field of the latest activity of the term
           $document->addField($key, apachesolr_date_iso($filetime));
         }
         if ($filetime > $max_official_filetime) {
@@ -209,19 +262,21 @@ function project_solr_apachesolr_index_document_build_node(ApacheSolrDocument $d
       $document->addField("ds_project_latest_release", apachesolr_date_iso($max_official_filetime));
     }
 
+    // Project usage specific index values. Used for
     if (module_exists('project_usage')) {
       $weeks = variable_get('project_usage_active_weeks', array());
       $week = reset($weeks);
       $total_usage = 0;
       $query = db_query("SELECT * FROM {project_usage_week_project} WHERE nid = %d AND timestamp = %d", $node->nid, $week);
       while ($usage = db_fetch_object($query)) {
-        $key = 'sis_project_release_usage_'. $usage->tid;
+        $key = 'iss_project_release_usage_'. $usage->tid;
         $document->addField($key, $usage->count);
         $total_usage += $usage->count;
       }
-      $document->addField('sis_project_release_usage' ,$total_usage);
+      $document->addField('iss_project_release_usage' ,$total_usage);
     }
   }
+
 }
 
 /**
@@ -272,14 +327,14 @@ function project_solr_apachesolr_query_alter(SolrBaseQuery &$query) {
     // above to exclude sandbox content won't have been added yet, so we won't
     // have the filter for releases, either, unless we add it here ourselves
     // (but only if we're building a query for project nodes).
-    if ($query->hasFilter('type', 'project_project') && module_exists('project_release')) {
+    if ($query->hasFilter('bundle', 'project_project') && module_exists('project_release')) {
       $query->addFilter('bs_project_has_releases', '1');
     }
   }
 }
 
 /**
- * Implementation of hook_apachesolr_prepare_query().
+ * Implementation of hook_apachesolr_query_prepare().
  *
  * This just adds an alias to allow the im_project_release_api_tids to present
  * itself as something different in the url. In the default case, instead of
@@ -287,162 +342,13 @@ function project_solr_apachesolr_query_alter(SolrBaseQuery &$query) {
  * in the url, making the url more user-friendly.
  */
 function project_solr_apachesolr_query_prepare(SolrBaseQuery &$query) {
-  if (module_exists('project_release')) {
-    // Add a human-readable alias for the release filter.
-    $query->addFieldAliases(array('im_project_release_api_tids' => variable_get('project_solr_project_release_api_tids_alias', 'api_version')));
-  }
   // Only add the project-specific sort if the query is filtering on projects.
-  if ($query->hasFilter('type', 'project_project')) {
+  if ($query->hasFilter('bundle', 'project_project')) {
     project_solr_add_sorts($query);
   }
 }
 
 //----------------------------------------
-// Page callbacks
-//----------------------------------------
-
-/**
- * Summary project browsing page.
- */
-function project_solr_browse_summary_page() {
-  $items = array();
-  $project_types = project_get_project_types();
-  foreach ($project_types as $term) {
-    $items[] = theme('project_type', $term);
-  }
-  drupal_set_title(t('Project types'));
-  return theme('item_list', $items);
-}
-
-/*
- * @todo : This page should become a search page
- */
-function project_solr_browse_page($term_name) {
-  try {
-    $output = '';
-
-    $project_type = db_fetch_object(db_query("SELECT t.tid, t.name, t.description FROM {term_data} t WHERE t.vid = %d AND LOWER(t.name) = LOWER('%s')", _project_get_vid(), $term_name));
-
-    if (!$project_type) {
-      // XXX: this is the Drupal 5 way...
-      return drupal_not_found();
-    }
-    drupal_set_title(check_plain($project_type->name));
-    if (!empty($project_type->description)) {
-      $output .= theme('project_type_description', $project_type);
-    }
-
-    $text_query = isset($_GET['text']) ? $_GET['text'] : '';
-    $filters = isset($_GET['filters']) ? $_GET['filters'] : '';
-    $sort = isset($_GET['solrsort']) ? check_plain($_GET['solrsort']) : '';
-
-    // Validate sort parameter.
-    if ((!isset($sort) || !preg_match('/^([a-z0-9_]+ (asc|desc)(,)?)+$/i', $sort)) && empty($text_query)) {
-      $sort = variable_get('project_solr_default_sort', 'sort_title asc');
-    }
-
-    $params = array(
-      'q' => $text_query,
-      'fl' => 'id,entity_id,label,content,is_comment_count,bundle,ds_created,ds_changed,url,is_uid,ss_name,sis_project_release_usage,ds_project_latest_release,ds_project_latest_activity',
-      'rows' => variable_get('apachesolr_rows', 10),
-      'facet' => 'true',
-      'facet.mincount' => 1,
-      'facet.sort' => 'true',
-      'facet.field' => array(
-        'im_vid_'. _project_get_vid(),
-        'im_project_release_api_tids',
-      ),
-      'facet.limit' => 200,
-    );
-    if (!empty($filters)) {
-      // @todo: Ensure this is correctly filtered.
-      $params['fq'] = $filters;
-    }
-    $page = isset($_GET['page']) ? $_GET['page'] : 0;
-    $params['start'] = $page * $params['rows'];
-
-    // This is the object that does the communication with the solr server.
-    $env_id = apachesolr_default_environment();
-    $solr = apachesolr_get_solr($env_id);
-    $query = new SolrBaseQuery($env_id, $solr, $params, $sort, 'project/' . drupal_strtolower($project_type->name));
-    if (is_null($query)) {
-      throw new Exception(t('Could not construct a Solr query.'));
-    }
-
-    // @todo: Identify whether this is truly necessary/true anymore.
-    // We add addFilter() parameters here to include all the constant
-    // filters for the query -- project nodes of the given top-level type that
-    // have releases (if project_release is enabled).
-    // We use addFilter() rather than $params['fq'] so that our filters
-    // are correctly passed to anything that uses our cached query.
-    $query->addFilter('bundle', 'project_project');
-    $query->addFilter('im_vid_'. _project_get_vid(), $project_type->tid);
-    // We can only filter on bs_project_has_releases for just official projects,
-    // since sandbox projects can never have releases.
-    if (module_exists('project_release') && $query->hasFilter('bs_project_sandbox', '0')) {
-      $query->addFilter('bs_project_has_releases', '1');
-    }
-
-    // Allow modules to alter the query prior to statically caching it.
-    // This can e.g. be used to add available sorts.
-    foreach (module_implements('apachesolr_prepare_query') as $module) {
-      $function_name = $module . '_apachesolr_prepare_query';
-      $function_name($query, $params, 'project_solr_browse_page');
-    }
-
-    // Cache the built query. Since all the built queries go through
-    // this process, all the hook_invocations will happen later.
-    apachesolr_current_query($env_id, $query);
-
-    if (!$query) {
-      return array();
-    }
-
-    // Force sort to be by the corresponding core compatibility if filtered.
-    $sort = $query->getSolrsort();
-    if (in_array($sort['#name'], array('ds_project_latest_release', 'ds_project_latest_activity'))
-      && ($api_filters = $query->getFilters('im_project_release_api_tids'))) {
-      $first_filter = reset($api_filters);
-      $query->setSolrsort($sort['#name'] .'_'. $first_filter['#value'], $sort['#direction']);
-    }
-    $response = $query->search($text_query);
-
-    // The response is cached so that it is accessible to the blocks and anything
-    // else that needs it beyond the initial search.
-    $total = $response->response->numFound;
-    apachesolr_static_response_cache($response);
-    apachesolr_has_searched($env_id, TRUE);
-
-    // Set breadcrumb.
-    $breadcrumb = menu_get_active_breadcrumb();
-    drupal_set_breadcrumb($breadcrumb);
-
-    $output .= '<div id="project-overview">';
-    pager_query("SELECT %d", $params['rows'], 0, NULL, $total);
-    if ($total > 0) {
-      foreach ($response->response->docs as $doc) {
-        $doc->created = strtotime($doc->created);
-        $doc->changed = strtotime($doc->changed);
-        $output .= project_solr_render_search_result($doc);
-      }
-    }
-    else {
-      $output .= t('No projects found in this category.');
-    }
-
-    $output .= '</div>'; // id="project-overview"
-    $output .= theme('pager', NULL, $query->getParam('rows'), 0);
-    $output = drupal_get_form('project_solr_browse_projects_form', $project_type, 'project/' . drupal_strtolower($project_type->name)) . $output;
-  }
-  catch (Exception $e) {
-    watchdog('Apache Solr', $e->getMessage(), NULL, WATCHDOG_ERROR);
-    apachesolr_failure(t('Solr search'), is_null($query) ? $keys : $query->getParam('q'));
-  }
-
-  return $output;
-}
-
-//----------------------------------------
 // Blocks
 //----------------------------------------
 
@@ -502,6 +408,7 @@ function project_solr_block_info() {
  * @see project_solr_block_info()
  */
 function project_solr_block_view($delta) {
+  module_load_include('inc', 'project_solr', 'project_solr.blocks');
   // None of these blocks make sense unless there's been a solr search.
   $env_id = apachesolr_default_environment();
   if (!apachesolr_has_searched($env_id)) {
@@ -510,374 +417,23 @@ function project_solr_block_view($delta) {
 
   $query = apachesolr_current_query($env_id);
   $response = apachesolr_static_response_cache($query->getSearcher());
-
   switch ($delta) {
     case 'project_solr_categories':
-      // Find the parent term for this query.
-      $project_vid = _project_get_vid();
-      if (isset($response->responseHeader->params->fq)) {
-        foreach ($response->responseHeader->params->fq as $query_snippet) {
-          if (preg_match('/^im_vid_'. _project_get_vid() .':(.*)$/', $query_snippet, $matches)) {
-            $tid = trim($matches[1]);
-            $term = taxonomy_get_term($tid);
-            if ($term->vid == $project_vid) {
-              $project_type = $term;
-              break;
-            }
-          }
-        }
-      }
-
-      if (!isset($project_type)) {
-        // This facet cannot process generic queries.
-        return;
-      }
-
-      $facet = 'im_vid_'.  _project_get_vid();
-      $terms = array();
-
-      // Get the terms at the current depth.
-      $current_tid = $project_type->tid;
-      foreach ($query->getFilters() as $filter) {
-        if ($filter['#name'] == 'tid') {
-          $current_tid = $filter['#value'];
-          break;
-        }
-      }
-      $current_level_terms = array();
-      $tree = taxonomy_get_tree(_project_get_vid(), $current_tid, -1, 1);
-      foreach ($tree as $term) {
-        $current_level_terms[$term->tid] = $term;
-      }
-
-      foreach ($response->facet_counts->facet_fields->$facet as $tid => $count) {
-        $active = $query->hasFilter('tid', $tid);
-        if (!isset($current_level_terms[$tid]) && (!$active || $tid != $current_tid)) {
-          continue;
-        }
-        $unclick_link = '';
-        $term = taxonomy_get_term($tid);
-        $new_query = clone $query;
-
-        $path = $new_query->getPath();
-        $options = array();
-        if ($active) {
-          $new_query->removeFilter('tid', $term->tid);
-          $options['query'] = $new_query->getSolrsortUrlQuery();
-          $link = theme('apachesolr_unclick_link', $term->name, $path, $options);
-        }
-        else {
-          $new_query->addFilter('tid', $term->tid);
-          $options['query'] = $new_query->getSolrsortUrlQuery();
-          $link = theme('apachesolr_facet_link', $term->name, $path, $options, $count, $active, $response->numFound);
-        }
-        $countsort = $count == 0 ? '' : 1 / $count;
-        // if numdocs == 1 and !active, don't add.
-        if ($response->numFound == 1 && !$active) {
-          // skip
-        }
-        else {
-          $terms[$active ? $countsort . $term->name : 1 + $countsort . $term->name] = $link;
-        }
-      }
-      $vocab = taxonomy_vocabulary_load(_project_get_vid());
-
-      if (!empty($terms)) {
-        ksort($terms);
-
-        // The currently selected term should be first.
-        if (isset($terms[$current_tid])) {
-          $current_term = $terms[$current_tid];
-          unset($terms[$current_tid]);
-          $terms = array_merge(array($current_tid => $current_term), $terms);
-        }
-
-        return array(
-          'subject' => $vocab->name,
-          'content' => theme('apachesolr_facet_list', $terms, 200),
-        );
-      }
+      return project_solr_block_project_solr_categories($query, $response);
       break;
-
     case 'project_solr_compatibility':
-      if (module_exists('project_release')) {
-        $facet = 'im_project_release_api_tids';
-        $terms = array();
-        $active_terms = project_release_compatibility_list();
-
-        $active_term_counts = array();
-        if (isset($response->facet_counts->facet_fields->$facet)) {
-          foreach ($response->facet_counts->facet_fields->$facet as $tid => $count) {
-            if (!empty($active_terms[$tid])) {
-              $active_term_counts[$tid] = $count;
-            }
-          }
-        }
-
-        foreach ($active_terms as $tid => $term_name) {
-          if (!empty($active_term_counts[$tid])) {
-            $active = $query->hasFilter('im_project_release_api_tids', $tid);
-            $new_query = clone $query;
-            $path = $new_query->getPath();
-            $new_query->removeFilter('im_project_release_api_tids', $term->tid);
-            $options = array();
-            if ($active) {
-              $options['query'] = $new_query->getSolrsortUrlQuery();
-              $link = theme('apachesolr_unclick_link', $term_name, $path, $options);
-            }
-            else {
-              $new_query->add_filter('im_project_release_api_tids', $tid);
-              $options['query'] = project_solr_append_api_term($new_query->get_url_queryvalues(), $tid);
-              $link = theme('project_solr_no_count_facet_link', $term_name, $path, $options, $active, $response->response->numFound);
-            }
-            $terms[$term_name] = $link;
-          }
-        }
-
-        if (!empty($terms)) {
-          return array(
-            'subject' => t('Filter by compatibility'),
-            'content' => theme('apachesolr_facet_list', $terms, 200),
-          );
-        }
-      }
-      break;
-
-    case 'project_solr_text':
-      return array(
-        'subject' => t('Search @project_type', array('@project_type' => $query->getParam('q'))),
-        'content' => drupal_get_form('project_sort_freetext', $query->getPath()),
-      );
-
-  }
-}
-
-/**
- * Build project browsing navigation form.
- */
-function project_solr_browse_projects_form(&$form_state, $project_type, $path) {
-  drupal_add_css(drupal_get_path('module', 'project_solr') .'/project_solr.css');
-  $env_id = apachesolr_default_environment();
-  $query = apachesolr_current_query($env_id);
-  $response = apachesolr_static_response_cache($query->getSearcher());
-  $text = $query->getParam('q');
-
-  // Get the terms at the current depth.
-  $current_tid = '';
-  foreach ($query->getFilters() as $field) {
-    if ($field['#name'] == 'tid') {
-      $current_tid = $field['#value'];
+      return project_solr_block_project_solr_compatibility($query, $response);
       break;
-    }
-  }
-
-  // Create a drop-down for sub-terms of primary project terms.
-  $tree = taxonomy_get_tree(_project_get_vid(), $project_type->tid, -1, 1);
-  foreach ($tree as $term) {
-    $terms[$term->tid] = $term->name;
-  }
-  if (!empty($terms)) {
-    $vocab = taxonomy_vocabulary_load(_project_get_vid());
-    asort($terms);
-    $terms = array('' => t('- Any -')) + $terms;
-    $form['tid'] = array(
-      '#type' => 'select',
-      '#options' => $terms,
-      '#title' => t('@type categories', array('@type' => $project_type->name)),
-      '#default_value' => $current_tid,
-    );
-  }
-
-  // Add the version selection field to our form.
-  $form['api_version'] = project_solr_get_api_version_field($query);
-
-  // Retrieve all the vocabularies related to project so that the facets can be built.
-  $vocabs = project_get_related_tids_map(TRUE);
-  foreach ($vocabs as $vid => $vocab) {
-    if ($project_type->tid == variable_get('project_type_associated_tid_' . $vid, NULL)) {
-      $selected = array();
-      // Extract selected values from our filters.
-      foreach ($query->getFilters() as $filter) {
-        if ($filter['#name'] == 'im_vid_'. $vid) {
-          $selected[] = $filter['#value'];
-        }
-      }
-
-      // Build checkbox items for all terms in related vocabularies.
-      $terms = array();
-      $project_types = project_get_project_types();
-      foreach ($project_types as $term) {
-        $terms[$term->tid] = $term->name;
-      }
-      asort($terms);
-
-      $form['im_vid_' . $vid] = array(
-        '#title' => t($vocab->name),
-        '#type' => 'checkboxes',
-        '#options' => $terms,
-        '#default_value' => $selected,
-      );
-    }
-  }
-
-  // Add the project sandbox fields. Solr allows use of 0 and 1 to match false and true.
-  $form['bs_project_sandbox'] = array(
-    '#title' => t('Status'),
-    '#type' => 'select',
-    '#options' => array(
-      '0' => t('Full projects'),
-      '[* TO *]' => t('All projects'),
-      '1' => t('Only sandbox projects'),
-    ),
-    '#default_value' => '0',
-  );
-
-  // Extract the project sandbox value from our filters.
-  if ($filters = $query->getFilters('bs_project_sandbox')) {
-    // There can be only one.
-    $filter = end($filters);
-    $form['bs_project_sandbox']['#default_value'] = $filter['#value'];
-  }
-
-  $form['bs_project_sandbox']['#access'] = variable_get('project_solr_show_sandbox_ui', FALSE);
-
-  $form['text'] = array(
-    '#title' => t('Search @project_type', array('@project_type' => $project_type->name)),
-    '#type' => 'textfield',
-    '#default_value' => $text,
-    '#size' => 20,
-  );
-
-  // Add the sort selection field to our form.
-  $form['solrsort'] = project_solr_get_solrsort_field();
-
-  $form['path'] = array(
-    '#type' => 'value',
-    '#value' => $path,
-  );
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Search'),
-  );
-  return $form;
-}
-
-/**
- * Return a Form API array for a sort selector field.
- *
- * @param string $label
- *   Optional form label for the sort selector field.
- *
- * @return
- *   Form array for the sort selector field.
- */
-function project_solr_get_solrsort_field($label = NULL) {
-  // Get search environment.
-  $env_id = apachesolr_default_environment();
-
-  // Pull the current query, so that we can default the sorts
-  // and provide an accurate list of available sorting methods.
-  $query = apachesolr_current_query($env_id);
-
-  // Pull the currently selected sort.
-  $solrsort = $query->getSolrsort();
-
-  // Pull all of the available sorts and create an options array.
-  $options = array();
-  $available_sorts = $query->getAvailableSorts();
-  foreach ($available_sorts as $name => $field) {
-    $options[$name . ' ' . $field['default']] = $field['title'];
   }
-
-  if (!isset($label)) {
-    $label = t('Sort by');
-  }
-
-  return array(
-    '#title' => $label,
-    '#type' => 'select',
-    '#default_value' => $solrsort['#name'] . ' ' . $solrsort['#direction'],
-    '#options' => $options,
-  );
 }
 
-function project_solr_browse_projects_form_submit($form, &$form_state) {
-  $env_id = apachesolr_default_environment();
-  $solr = apachesolr_get_solr($env_id);
-  $params = array(
-    'text' => $form_state['values']['text'],
-  );
-  $query = new SolrBaseQuery($env_id, $solr, $params, '', $form_state['values']['path']);
-
-  if (!empty($form_state['values']['tid'])) {
-    $query->addFilter('tid', $form_state['values']['tid']);
-  }
-
-  if (!empty($form_state['values']['api_version'])) {
-    $query->addFilter(variable_get('project_solr_project_release_api_tids_alias', 'api_version'), $form_state['values']['api_version']);
-  }
-
-  // Loop over all project-related vocabularies and create filters
-  // for any values that have been posted.
-  $vocabs = project_get_related_tids_map(TRUE);
-  foreach ($vocabs as $vid => $vocab) {
-    $values = array_filter($form_state['values']['im_vid_' . $vid]);
-    if (!empty($values)) {
-      foreach($values as $value) {
-        $query->addFilter('im_vid_'. $vid, $value);
-      }
-    }
-  }
-
-  // Rewrite solrsort parameter with API version tid, if necessary.
-  $solrsort = explode(' ', $form_state['values']['solrsort']);
-  if (module_exists('project_release') && !empty($form_state['values']['api_version'])) {
-    if ($solrsort[0] == 'ds_project_latest_release' || $solrsort[0] == 'ds_project_latest_activity') {
-      $solrsort[0] .= '_'. $form_state['values']['api_version'];
-    }
-  }
-
-  if ($solrsort[0] == '' && empty($form_state['values']['text'])) {
-    drupal_set_message(t('No search text submitted for a relevancy sort.  The default sorting method was used instead.'));
-  }
-
-  // Add the project sandbox filter.
-  $query->addFilter('bs_project_sandbox', $form_state['values']['bs_project_sandbox']);
-
-  // Add all project-specific sorts so that the sort set in set_solrsort() will
-  // work as intended.
-  project_solr_add_sorts($query, variable_get('project_solr_project_release_api_tids_alias', 'api_version'));
-  $query->setSolrSort($solrsort[0], $solrsort[1]);
-
-  // @todo: Much of this is unfortunate in an attempt to keep similar patterns
-  // for project & project_solr searches. See if we can blaze our own path to
-  // remove all this silliness.
-  $query_values = array();
-  if (!empty($form_state['values']['text']) && $text = $query->getParam('text')) {
-    $query_values['text'] = array_pop($text);
-  }
-  $filters = $query->getParam('fq');
-  if (isset($filters)) {
-    $query_values['filters'] = $filters;
-  }
-  if ($sort = $query->getParam('sort')) {
-    $query_values['solrsort'] = array_pop($sort);
-  }
-  // By setting this as an array, FAPI is going to hand it to drupal_goto().
-  // drupal_goto() itself doesn't care about the keys, but we define them here
-  // to make the code more self-documenting, especially if people are trying
-  // to alter this form (e.g. in drupalorg_search.module).
-  $form_state['redirect'] = array(
-    'path' => $query->getPath(),
-    'query' => $query_values,
-  );
-}
+/// Helper functions
 
 /**
  * Append the API tid to selected fields that might be in the string.
  */
 function project_solr_append_api_term($values, $tid) {
-  $api_fields = array('ds_project_latest_release', 'sis_project_release_usage', 'ds_project_latest_activity');
+  $api_fields = array('ds_project_latest_release', 'iss_project_release_usage', 'ds_project_latest_activity');
   foreach($values as $k => $v) {
     if (in_array($k, $api_fields)) {
       unset($values[$k]);
@@ -887,44 +443,6 @@ function project_solr_append_api_term($values, $tid) {
   return $values;
 }
 
-/**
- * Form callback; display a free text form.
- */
-function project_sort_freetext(&$form_state, $base_path) {
-  $form = array();
-  $form['text'] = array(
-    '#type' => 'textfield',
-    '#default_value' => $_GET['text'],
-    '#size' => 20,
-  );
-  $form['path'] = array(
-    '#type' => 'value',
-    '#value' => $base_path,
-  );
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Submit'),
-  );
-  return $form;
-}
-
-/**
- * Submit handler for project_sort_freetext().
- */
-function project_sort_freetext_submit($form, &$form_state) {
-  $env_id = apachesolr_default_environment($env_id);
-  if ($query = apachesolr_current_query($env_id)) {
-    $query = new SolrBaseQuery($env_id);
-    $queryvalues = $query->getSolrsortUrlQuery();
-  }
-  else {
-    $queryvalues = array();
-  }
-  $queryvalues['text'] = $form_state['values']['text'];
-  unset($queryvalues['solrsort']);
-  $form_state['redirect'] = array($form_state['values']['path'], $queryvalues);
-}
-
 //----------------------------------------
 // Public helper methods
 //----------------------------------------
@@ -942,25 +460,16 @@ function project_sort_freetext_submit($form, &$form_state) {
  */
 function project_solr_run_project_query($base_path, $filters = array()) {
   $env_id = apachesolr_default_environment();
-  $filterstring = isset($_GET['filters']) ? $_GET['filters'] : '';
-  $query = apachesolr_drupal_query('project_solr_run_project_query', array('fq' => $filterstring), '', $base_path);
 
   // Figure out all the fields we need to use as facets.
   // First handle all the implicit filters we're going to add ourselves.
   $facet_fields = array(
-    'type',
     'im_project_release_api_tids',
   );
-  // Now add any fields used for optional filters from our caller.
-  if (!empty($filters)) {
-    foreach ($filters as $filter) {
-      $facet_fields[] = $filter['key'];
-    }
-  }
 
   $params = array(
     // The fields to return.
-    'fl' => 'id,nid,title',
+    'fl' => 'id,entity_id,label,im_project_release_api_tids',
     'start' => 0,
     'rows' => 5,  // TODO: make this configurable.
     'facet.field' => $facet_fields,
@@ -970,7 +479,7 @@ function project_solr_run_project_query($base_path, $filters = array()) {
     'sort' => variable_get('project_solr_default_sort', 'sort_title asc'),
   );
 
-  $query->addParams($params);
+  $query = apachesolr_drupal_query('project_solr_run_project_query', $params, '', $base_path);
 
   // Allow modules to alter the query prior to statically caching it.
   // This can e.g. be used to add available sorts.
@@ -979,6 +488,12 @@ function project_solr_run_project_query($base_path, $filters = array()) {
     $function_name($query, $params, 'project_solr_run_project_query');
   }
 
+  if (!empty($filters)) {
+    foreach ($filters as $filter) {
+      $query->addFilter($filter['key'], $filter['value']);
+    }
+  }
+
   // We add our fields after the prepare_query() because prepare_query()
   // generates a call to parse_filters() which destroys anything that
   // does not get passed into the query on construction.
@@ -987,21 +502,14 @@ function project_solr_run_project_query($base_path, $filters = array()) {
   // ourselves to ensure we only get the content we want.
   $query->addFilter('bundle', 'project_project');
 
-  if (!empty($filters)) {
-    foreach ($filters as $filter) {
-      $query->addFilter($filter['key'], $filter['value']);
-    }
-  }
-
   // Cache the built query. Since all the built queries go through
   // this process, all the hook_invocations will happen later.
   apachesolr_current_query($env_id, $query);
 
-  // This hook allows modules to modify the query and params objects.
-  //apachesolr_modify_query($query, $params, 'project_solr_run_project_query');
-
   $solr = apachesolr_get_solr($env_id);
-  $response = $solr->search($query, $params);
+  $params = $query->getParams();
+  $response = $solr->search('', $params);
+
 
   apachesolr_static_response_cache($query->getSearcher(), $response);
   apachesolr_has_searched($env_id, TRUE);
@@ -1025,12 +533,16 @@ function project_solr_get_api_version_field($query, $label = NULL) {
     $current_tid = '';
     $terms = array();
     $active_terms = project_release_compatibility_list();
-    foreach ($active_terms as $tid => $term_name) {
-      $active = $query->hasFilter('im_project_release_api_tids', $tid);
-      if ($active) {
-        $current_tid = $tid;
+    $facet = variable_get('project_solr_project_release_api_tids_alias', 'drupal_core');
+
+    if ($query) {
+      foreach ($active_terms as $tid => $term_name) {
+        $active = $query->hasFilter('im_project_release_api_tids', $tid);
+        if ($active) {
+          $current_tid = $tid;
+        }
+        $terms[$tid] = $term_name;
       }
-      $terms[$tid] = $term_name;
     }
     if (!empty($terms)) {
       $terms = array('' => t('- Any -')) + $terms;
@@ -1096,8 +608,66 @@ function project_solr_add_sorts(&$query, $api_filter = 'im_project_release_api_t
     }
   }
   if (module_exists('project_usage')) {
-    $query->setAvailableSort('sis_project_release_usage', array('title' => t('Most installed'), 'default' => 'desc'));
+    $query->setAvailableSort('iss_project_release_usage', array('title' => t('Most installed'), 'default' => 'desc'));
+  }
+}
+
+/**
+ * Gather the items for a given project category.
+ *
+ * @param $project_type
+ *   The fully-loaded taxonomy term for the project type.
+ * @param $category_term
+ *   The fully-loaded taxonomy term for the category.
+ *
+ * @return
+ *   Array of projects from the given category.
+ */
+function project_solr_fetch_category_items($project_type, $category_term) {
+  $project_vid = _project_get_vid();
+  $filters = array();
+  $filters[] = array(
+    'key' => 'im_vid_' . $project_vid,
+    'value' => $category_term->tid,
+  );
+
+  $filters_url = $_GET['f'];
+  foreach ($filters_url as $filter_url) {
+    $filter_url = explode(':', $filter_url);
+    if (is_array($filter_url)) {
+      $facet_alias = variable_get('project_solr_project_release_api_tids_alias', 'drupal_core');
+      if ($filter_url[0] == $facet_alias) {
+        $filter_url = array('key' => 'im_project_release_api_tids', 'value' => $filter_url[1]);
+      }
+      else {
+        $filter_url = array('key' => $filter_url[0], 'value' => $filter_url[1]);
+      }
+      $filters = array_merge($filters, array($filter_url));
+    }
   }
+
+  $base_path = 'project/' . drupal_strtolower($project_type->name);
+
+  $query = project_solr_run_project_query($base_path, $filters);
+
+  $response = apachesolr_static_response_cache($query->getSearcher());
+
+  $items = array();
+  if ($response->response->numFound > 0) {
+    foreach ($response->response->docs as $doc) {
+      $items[] = l($doc->label, 'node/' . $doc->entity_id);
+    }
+  }
+
+  if ($items) {
+    // Add the "more" link.
+    $items[] = array(
+      'data' => l(t('More @category', array('@category' => $category_term->name)), 'project/' . $category_term->name),
+      'class' => 'more',
+    );
+  }
+
+  return $items;
 }
 
 //----------------------------------------
@@ -1140,105 +710,6 @@ function theme_project_solr_no_count_facet_link($facet_text, $path, $options = a
   return apachesolr_l($facet_text,  $path, $options);
 }
 
-//----------------------------------------
-// Version-selector form
-//----------------------------------------
-
-/**
- * This generates a form containing version selection and a submit button.
- *
- * Generate a form with a version selection to allow filtering page content
- * based on the API compatibility version. Also includes path to allow the
- * form to potentially submit to other urls if desired.
- *
- * @param string $path
- *   The base path to which the version form will redirect.
- * @param string $label
- *   An optional label for the form element.
- */
-function project_solr_version_form(&$form_state, $path, $label = NULL) {
-  $query = apachesolr_current_query();
-
-  $form = array(
-    '#attributes' => array('class' => 'clear-block'),
-  );
-
-  // Add version select field to our form.
-  $version_alias = variable_get('project_solr_project_release_api_tids_alias', 'api_version');
-
-  $form[$version_alias] = project_solr_get_api_version_field($query, $label);
-
-  $form['path'] = array(
-    '#type' => 'value',
-    '#value' => $path,
-  );
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Search'),
-  );
-  return $form;
-}
-
-/**
- * Create a query with the right version filter and redirect to the right page.
- *
- * Create a new query, add any version filtering if it was selected in the
- * form, and redirect back to the relevant page with the appropriate filter
- * string.
- */
-function project_solr_version_form_submit($form, &$form_state) {
-  // We create a new query with our base path so that we don't need to remove
-  // any existing drupal_core selection, and so that the implict type and
-  // module tid filters don't end up in the url string.
-  $query = apachesolr_drupal_query('project_solr_version_form_submit', '', '', $form_state['values']['path']);
-
-  $version_alias = variable_get('project_solr_project_release_api_tids_alias', 'api_version');
-
-  if (!empty($form_state['values'][$version_alias])) {
-    $query->addFilter($version_alias, $form_state['values'][$version_alias]);
-  }
-
-  $form_state['redirect'] = array($query->getPath(), $query->getSolrsortUrlQuery());
-}
-
-//----------------------------------------
-// Category page and related functions
-//----------------------------------------
-
-/**
- * Page callback for the listing of per-type categories.
- *
- * @param $project_type
- *   Fully-loaded taxonomy term object for the project type.
- *
- * @return
- *   Rendered page output for the project/%project_type/categories pages.
- */
-function project_solr_category_page($project_type) {
-  $tree = taxonomy_get_tree(_project_get_vid(), $project_type->tid);
-  if (empty($tree)) {
-    return drupal_not_found();
-  }
-
-  drupal_set_title(t('@project_type categories', array('@project_type' => $project_type->name)));
-
-  $categories = array();
-  foreach ($tree as $category_term) {
-    $items = project_solr_fetch_category_items($project_type, $category_term);
-    if (!empty($items)) {
-      $categories[$category_term->tid] = array(
-        'title' => check_plain($category_term->name),
-        'items' => $items,
-      );
-    }
-  }
-
-  $search_path = 'project/' . drupal_strtolower($project_type->name) . '/categories';
-  $version_form = drupal_get_form('project_solr_version_form', $search_path);
-
-  return theme('project_solr_category_page', $project_type, $categories, $version_form);
-}
-
 /**
  * Render the markup for the per-project type categories landing pages.
  *
@@ -1270,48 +741,6 @@ function theme_project_solr_category_page($project_type, $categories, $version_f
 }
 
 /**
- * Gather the items for a given project category.
- *
- * @param $project_type
- *   The fully-loaded taxonomy term for the project type.
- * @param $category_term
- *   The fully-loaded taxonomy term for the category.
- *
- * @return
- *   Array of projects from the given category.
- */
-function project_solr_fetch_category_items($project_type, $category_term) {
-  $filters = array();
-  $filters[] = array(
-    'key' => 'tid',
-    'value' => $category_term->tid,
-  );
-  $base_path = 'project/' . drupal_strtolower($project_type->name);
-  $query = project_solr_run_project_query($base_path, $filters);
-
-  $query_values = $query->getSolrsortUrlQuery();
-
-  $response = apachesolr_static_response_cache($query->getSearcher());
-
-  $items = array();
-  if ($response->response->numFound > 0) {
-    foreach ($response->response->docs as $doc) {
-      $items[] = l($doc->title, 'node/' . $doc->nid);
-    }
-  }
-
-  if ($items) {
-    // Add the "more" link.
-    $items[] = array(
-      'data' => l(t('More @category', array('@category' => $category_term->name)), $query->getPath(), array('query' => $query_values)),
-      'class' => 'more',
-    );
-  }
-
-  return $items;
-}
-
-/**
  * Render the final markup for a list of projects from a given category.
  *
  * @param array $items
