diff --git a/client/query/query.js b/client/query/query.js
index efca0dd..e20f8f6 100644
--- a/client/query/query.js
+++ b/client/query/query.js
@@ -9,491 +9,506 @@
   new Atmos(catalog, config);
 });
 
-/**
- * Atmos
- * @version 2.0
- * 
- * Configures an Atmos object. This manages the atmos interface.
- * 
- * @constructor 
- * @param {string} catalog - NDN path
- * @param {Object} config - Object of configuration options for a Face. 
- */
-function Atmos(catalog, config){
+var Atmos = (function(){
   "use strict";
-  //Internal variables.
-  this.results = []
-  this.resultCount = 0;
-  this.page = 1;
-  this.totalPages = 1;
-  this.selectedSearch = {};
-  this.dropdown = [];
-  this.state = {};
-  this.currentViewIndex = 0;
+  /**
+   * Atmos
+   * @version 2.0
+   * 
+   * Configures an Atmos object. This manages the atmos interface.
+   * 
+   * @constructor 
+   * @param {string} catalog - NDN path
+   * @param {Object} config - Object of configuration options for a Face. 
+   */
+  function Atmos(catalog, config){
 
-  this.catalog = catalog;
+    //Internal variables.
+    this.results = [];
+      this.resultCount = 0;
+    this.page = 1;
+    this.totalPages = 1;
+    this.selectedSearch = {};
+    this.dropdown = [];
+    this.state = {};
+    this.currentViewIndex = 0;
 
-  this.face = new Face(config);
-  this.categories = $('#side-menu');
-  this.resultTable = $('#resultTable');
-  this.filters = $('#filters');
+    this.catalog = catalog;
 
-  var scope = this;
+    this.face = new Face(config);
+    this.categories = $('#side-menu');
+    this.resultTable = $('#resultTable');
+    this.filters = $('#filters');
 
-  this.resultTable.on('click', '.interest-button', function(){
-    var button = $(this);
+    var scope = this;
 
-    if (button.is(':disabled')){
-      console.warn("Attempt to request again!");
-    }
+    this.resultTable.on('click', '.interest-button', function(){
+      var button = $(this);
 
-    var name = button.parent().prev().text();
-    var interest = new Interest(new Name('/retrieve' + name));
-    scope.face.expressInterest(interest, function(){}, function(){});
-
-    button.text("Requested!")
-    .removeClass('btn-primary')
-    .addClass('btn-default')
-    .addClass('disabled')
-    .prop('disabled', true);
-
-  });
-
-  $.getJSON("search_catagories.json").done(function (data) {
-    $.each(data, function (pageSection, contents) {
-      if (pageSection == "SearchCatagories") {
-        $.each(contents, function (search, searchOptions) {
-          var e = $('<li><a href="#">' + search.replace(/\_/g, " ") + '</a><ul class="subnav nav nav-pills nav-stacked"></ul></li>');
-
-          var sub = e.find('ul.subnav');
-          $.each(searchOptions, function(index, name){
-            var item = $('<li><a href="#">' + name + '</a></li>');
-            sub.append(item);
-            item.click(function(){
-              scope.addFilter(name, search);
-            });
-          });
-
-          //Toggle the menus. (Only respond when the immediate tab is clicked.)
-          e.find('> a').click(function(){
-            scope.categories.find('.subnav').slideUp();
-            var t = $(this).siblings('.subnav');
-            if ( !t.is(':visible')){
-              t.slideDown().triggerHandler('focus'); //Cancel other animations and slide down.
-            }
-          });
-
-          scope.categories.append(e);
-        });
+      if (button.is(':disabled')){
+        console.warn("Attempt to request again!");
       }
+
+      var name = button.parent().prev().text();
+      var interest = new Interest(new Name('/retrieve' + name));
+      scope.face.expressInterest(interest, function(){}, function(){});
+
+      button.text("Requested!")
+        .removeClass('btn-primary')
+        .addClass('btn-default')
+        .addClass('disabled')
+        .prop('disabled', true);
+
     });
-  });
 
-  $('#searchBar').submit(function(e){
-    e.preventDefault();
-    console.log("Search started!", $('#search'));
-  })
+    $.getJSON("search_catagories.json").done(function (data) {
+      $.each(data, function (pageSection, contents) {
+        if (pageSection == "SearchCatagories") {
+          $.each(contents, function (search, searchOptions) {
+            var e = $('<li><a href="#">' + search.replace(/\_/g, " ") + '</a><ul class="subnav nav nav-pills nav-stacked"></ul></li>');
 
-}
+            var sub = e.find('ul.subnav');
+            $.each(searchOptions, function(index, name){
+              var item = $('<li><a href="#">' + name + '</a></li>');
+              sub.append(item);
+              item.click(function(){
+                scope.addFilter(name, search);
+              });
+            });
 
-Atmos.prototype.onData = function(data) {
-  var payloadStr = data.content.toString().split("\n")[0];
+            //Toggle the menus. (Only respond when the immediate tab is clicked.)
+            e.find('> a').click(function(){
+              scope.categories.find('.subnav').slideUp();
+              var t = $(this).siblings('.subnav');
+              if ( !t.is(':visible')){
+                t.slideDown().triggerHandler('focus'); //Cancel other animations and slide down.
+              }
+            });
 
-  if (!payloadStr || payloadStr.length === 0){
-    this.populateResults();
-    return; //No results were returned.
+            scope.categories.append(e);
+          });
+        }
+      });
+    });
+
+    $('#searchBar').submit(function(e){
+      e.preventDefault();
+      console.log("Search started!", $('#search'));
+    })
+
   }
 
-  var queryResults = JSON.parse(payloadStr);
+  Atmos.prototype.onData = function(data) {
+    console.log("Recieved data", data);
 
-  var scope = this;
+    var payloadStr = data.content.toString().split("\n")[0];
 
-  $.each(queryResults, function (queryResult, field) {
-
-    if (queryResult == "next") {
-      scope.populateAutocomplete(field);
+    if (!payloadStr || payloadStr.length === 0){
+      this.populateResults();
+      return; //No results were returned.
     }
 
-    if (queryResult == "results" && field == null){
-      return; //Sometimes the results are null. (We should skip this.)
-    }
+    var queryResults = JSON.parse(payloadStr);
 
-    $.each(field, function (entryCount, name) {
-      scope.results.push(name);
+    var scope = this;
+
+    $.each(queryResults, function (queryResult, field) {
+
+      if (queryResult == "next") {
+        scope.populateAutocomplete(field);
+      }
+
+      if (queryResult == "results" && field == null){
+        return; //Sometimes the results are null. (We should skip this.)
+      }
+
+      $.each(field, function (entryCount, name) {
+        scope.results.push(name);
+      });
     });
-  });
 
-  // Calculating the current page and the view
-  this.populateResults();
+    // Calculating the current page and the view
+    this.populateResults();
 
-}
+  }
 
-Atmos.prototype.query = function(prefix, parameters, callback, pipeline) {
-  this.results = [];
-  this.dropdown = [];
-  this.resultTable.empty();
+  Atmos.prototype.query = function(prefix, parameters, callback, pipeline) {
+    this.results = [];
+    this.dropdown = [];
+    this.resultTable.empty();
 
-  var queryPrefix = new Name(prefix);
-  queryPrefix.append("query");
+    var queryPrefix = new Name(prefix);
+    queryPrefix.append("query");
 
-  var jsonString = JSON.stringify(parameters);
-  queryPrefix.append(jsonString);
+    var jsonString = JSON.stringify(parameters);
+    queryPrefix.append(jsonString);
 
-  this.state = {
+    this.state = {
       prefix: new Name(prefix),
       userOnData: callback,
       outstanding: {},
       nextSegment: 0,
       parameters: jsonString
-  };
+    };
 
-  /*if (state.hasOwnProperty("version")) {
-                console.log("state already has version");
-            }*/
+    /*if (state.hasOwnProperty("version")) {
+      console.log("state already has version");
+      }*/
 
-  var queryInterest = new Interest(queryPrefix);
-  queryInterest.setInterestLifetimeMilliseconds(10000);
+    var queryInterest = new Interest(queryPrefix);
+    queryInterest.setInterestLifetimeMilliseconds(10000);
 
-  var scope = this;
-
-  this.face.expressInterest(queryInterest,
-    function(interest, data){
-      scope.onQueryData(interest, data);
-    }, function(interest){
-      scope.onQueryTimeout(interest);
-    }
-  );
-
-  this.state["outstanding"][queryInterest.getName().toUri()] = 0;
-}
-
-/**
- * @deprecated
- * Use applyFilters/addFilters as appropriate.
- */
-Atmos.prototype.submitCatalogSearch = function(field) {
-  console.warn("Use of deprecated function submitCatalogSearch! (Use applyFilters/addFilters as appropriate)");
-}
-
-Atmos.prototype.expressNextInterest = function() {
-  // @todo pipelines
-  var nextName = new Name(this.state["results"]);
-  nextName.appendSegment(this.state["nextSegment"]);
-
-  var nextInterest = new Interest(nextName);
-  nextInterest.setInterestLifetimeMilliseconds(10000);
-
-  var scope = this;
-
-  this.face.expressInterest(nextInterest,
-      function(interest, data){
-        scope.onQueryResultsData(interest, data);
-      },
-      function(interest){
-        scope.onQueryResultsTimeout(interest);
-      });
-
-  this.state["nextSegment"] ++;
-  this.state["outstanding"][nextName.toUri()] = 0;
-}
-
-Atmos.prototype.onQueryData = function(interest, data) {
-  var name = data.getName();
-
-  delete this.state["outstanding"][interest.getName().toUri()];
-
-  this.state["version"] = name.get(this.state["prefix"].size() + 2).toVersion();
-
-  this.state["results"] = new Name(this.state["prefix"]).append("query-results").append(this.state['parameters']).appendVersion(this.state["version"]);
-
-  this.expressNextInterest();
-}
-
-Atmos.prototype.onQueryResultsData = function(interest, data) {
-  var name = data.getName();
-  delete this.state["outstanding"][interest.getName().toUri()];
-  if (!name.get(-1).equals(data.getMetaInfo().getFinalBlockId())) {
-    this.expressNextInterest();
-  } //else {
-    //alert("found final block");
-  //}
-
-  this.state["userOnData"](data);
-}
-
-Atmos.prototype.onQueryTimeout = function(interest) {
-  var uri = interest.getName().toUri();
-  if (this.state["outstanding"][uri] < 1) {
-    this.state["outstanding"][uri] ++;
     var scope = this;
-    this.face.expressInterest(interest,
+
+    this.face.expressInterest(queryInterest,
         function(interest, data){
           scope.onQueryData(interest, data);
+        }, function(interest){
+          scope.onQueryTimeout(interest);
+        }
+        );
+
+    this.state["outstanding"][queryInterest.getName().toUri()] = 0;
+  }
+
+  /**
+   * @deprecated
+   * Use applyFilters/addFilters as appropriate.
+   */
+  Atmos.prototype.submitCatalogSearch = function(field) {
+    console.warn("Use of deprecated function submitCatalogSearch! (Use applyFilters/addFilters as appropriate)");
+  }
+
+  Atmos.prototype.expressNextInterest = function() {
+    // @todo pipelines
+    var nextName = new Name(this.state["results"]);
+    nextName.appendSegment(this.state["nextSegment"]);
+
+    var nextInterest = new Interest(nextName);
+    nextInterest.setInterestLifetimeMilliseconds(10000);
+
+    var scope = this;
+
+    this.face.expressInterest(nextInterest,
+        function(interest, data){
+          scope.onQueryResultsData(interest, data);
         },
         function(interest){
-          scope.onQueryTimeout(interest);
+          scope.onQueryResultsTimeout(interest);
         });
-  } else {
-    delete this.state["outstanding"][uri];
 
-    // We modify the autocomplete box here because we need to know
-    // we have all of the entries first. Fairly hacky.
-    /* TODO FIXME
-    var autocompleteFullName = this.autocompleteText.value;
-    for (var i = 0; i < dropdown.length; ++i) {
-      if (this.dropdown[i].substr(0, dropdown[i].length - 1).toUpperCase === this.autocompleteText.value.toUpperCase || dropdown.length == 1) {
-        autocompleteText.value = dropdown[i];
-      }
+    this.state["nextSegment"] ++;
+    this.state["outstanding"][nextName.toUri()] = 0;
+  }
+
+  Atmos.prototype.onQueryData = function(interest, data) {
+    var name = data.getName();
+
+    delete this.state["outstanding"][interest.getName().toUri()];
+
+    this.state["version"] = name.get(this.state["prefix"].size() + 2).toVersion();
+
+    this.state["results"] = new Name(this.state["prefix"]).append("query-results").append(this.state['parameters'])
+    .appendVersion(this.state["version"]).append(name.getComponent(name.getComponentCount() - 2));
+
+    console.log("Requested URI", this.state.results.toUri());
+
+    this.expressNextInterest();
+  }
+
+  Atmos.prototype.onQueryResultsData = function(interest, data) {
+    var name = data.getName();
+    delete this.state["outstanding"][interest.getName().toUri()];
+    if (!name.get(-1).equals(data.getMetaInfo().getFinalBlockId())) {
+      this.expressNextInterest();
+    } //else {
+    //alert("found final block");
+    //}
+
+    this.state["userOnData"](data);
+  }
+
+  Atmos.prototype.onQueryTimeout = function(interest) {
+    var uri = interest.getName().toUri();
+    if (this.state["outstanding"][uri] < 1) {
+      this.state["outstanding"][uri] ++;
+      var scope = this;
+      this.face.expressInterest(interest,
+          function(interest, data){
+            scope.onQueryData(interest, data);
+          },
+          function(interest){
+            scope.onQueryTimeout(interest);
+          });
+    } else {
+      delete this.state["outstanding"][uri];
+
+      // We modify the autocomplete box here because we need to know
+      // we have all of the entries first. Fairly hacky.
+      /* TODO FIXME
+         var autocompleteFullName = this.autocompleteText.value;
+         for (var i = 0; i < dropdown.length; ++i) {
+         if (this.dropdown[i].substr(0, dropdown[i].length - 1).toUpperCase === this.autocompleteText.value.toUpperCase || dropdown.length == 1) {
+         autocompleteText.value = dropdown[i];
+         }
+         }
+         */
     }
-    */
   }
-}
 
-Atmos.prototype.onQueryResultsTimeout = function(interest) {
-  var uri = interest.getName().toUri();
-  if (this.state["outstanding"][uri] < 1) {
-    this.state["outstanding"][uri] ++;
-    var scope = this;
-    this.face.expressInterest(interest,
-        function(){
-          scope.onQueryResultsData.apply(scope, arguments);
-        },
-        function(){
-          scope.onQueryResultsTimeout.apply(scope, arguments);
-        });
-  } else {
-    delete this.state["outstanding"][uri];
-    // We modify the autocomplete box here because we need to know
-    // we have all of the entries first. Fairly hacky.
-    /* TODO FIXME
-    var autocompleteFullName = autocompleteText.value;
-    for (var i = 0; i < dropdown.length; ++i) {
-      if (dropdown[i].substr(0, dropdown[i].length - 1).toUpperCase === autocompleteText.value.toUpperCase || dropdown.length == 1) {
-        autocompleteText.value = dropdown[i];
-      }
+  Atmos.prototype.onQueryResultsTimeout = function(interest) {
+    var uri = interest.getName().toUri();
+    if (this.state["outstanding"][uri] < 1) {
+      this.state["outstanding"][uri] ++;
+      var scope = this;
+      this.face.expressInterest(interest,
+          function(){
+            scope.onQueryResultsData.apply(scope, arguments);
+          },
+          function(){
+            scope.onQueryResultsTimeout.apply(scope, arguments);
+          });
+    } else {
+      delete this.state["outstanding"][uri];
+      // We modify the autocomplete box here because we need to know
+      // we have all of the entries first. Fairly hacky.
+      /* TODO FIXME
+         var autocompleteFullName = autocompleteText.value;
+         for (var i = 0; i < dropdown.length; ++i) {
+         if (dropdown[i].substr(0, dropdown[i].length - 1).toUpperCase === autocompleteText.value.toUpperCase || dropdown.length == 1) {
+         autocompleteText.value = dropdown[i];
+         }
+         }
+         */
     }
-    */
-  }
-}
-
-Atmos.prototype.populateResults = function() {
-
-  //TODO Check only for page changes and result length
-
-  this.resultTable.empty();
-
-  for (var i = startIndex; i < startIndex + 20 && i < this.results.length; ++i) {
-    this.resultTable.append('<tr><td>' + this.results[i]
-    + '</td><td><button class="interest-button btn btn-primary btn-xs">Retrieve</button></td></tr>');
   }
 
-  if (this.results.length <= 20) {
-    this.page = 1;
-  } else {
-    this.page = startIndex / 20 + 1;
-  }
+  Atmos.prototype.populateResults = function() {
 
-  this.totalPages = Math.ceil(this.results.length / 20);
+    //TODO Check only for page changes and result length
 
-  //TODO Fix the page to fit the theme.
-  var currentPage = $(".page");
-  currentPage.empty();
-  if (this.page != 1) {
-    currentPage.append('<a href="#" onclick="getPage(this.id);" id="<"><</a>');
-  }
-  // This section of code creates the paging for the results.
-  // To prevent it from having a 1000+ pages, it will only show the 5 pages before/after
-  // the current page and the total pages (expect users not to really jump around a lot).
-  for (var i = 1; i <= this.totalPages; ++i) {
-    if (i == 1 || i == this.totalPages      // Min or max
-        || (i <= this.page && i + 5 >= this.page)    // in our current page range
-        || (i >= this.page && i - 5 <= this.page)) { // in our current page range
-      if (i != this.page) {
-        currentPage.append(' <a href="#" onclick="getPage(' + i + ');">' + i + '</a>')
-        if (i == 1 && this.page > i + 5) {
-          currentPage.append(' ... ');
+    this.resultTable.empty();
+
+    for (var i = startIndex; i < startIndex + 20 && i < this.results.length; ++i) {
+      this.resultTable.append('<tr><td>' + this.results[i]
+          + '</td><td><button class="interest-button btn btn-primary btn-xs">Retrieve</button></td></tr>');
+    }
+
+    if (this.results.length <= 20) {
+      this.page = 1;
+    } else {
+      this.page = startIndex / 20 + 1;
+    }
+
+    this.totalPages = Math.ceil(this.results.length / 20);
+
+    //TODO Fix the page to fit the theme.
+    var currentPage = $(".page");
+    currentPage.empty();
+    if (this.page != 1) {
+      currentPage.append('<a href="#" onclick="getPage(this.id);" id="<"><</a>');
+    }
+    // This section of code creates the paging for the results.
+    // To prevent it from having a 1000+ pages, it will only show the 5 pages before/after
+    // the current page and the total pages (expect users not to really jump around a lot).
+    for (var i = 1; i <= this.totalPages; ++i) {
+      if (i == 1 || i == this.totalPages      // Min or max
+          || (i <= this.page && i + 5 >= this.page)    // in our current page range
+          || (i >= this.page && i - 5 <= this.page)) { // in our current page range
+        if (i != this.page) {
+          currentPage.append(' <a href="#" onclick="getPage(' + i + ');">' + i + '</a>')
+            if (i == 1 && this.page > i + 5) {
+              currentPage.append(' ... ');
+            }
+        } else {
+          currentPage.append(' ' + i);
         }
-      } else {
-        currentPage.append(' ' + i);
-      }
-    } else { // Need to skip ahead
-      if (i == this.page + 6) {
-        currentPage.append(' ... ');
+      } else { // Need to skip ahead
+        if (i == this.page + 6) {
+          currentPage.append(' ... ');
 
-        currentPage.append(' <a href="#" onclick="getPage(this.id);" id=">">></a>')
-        i = this.totalPages - 1;
+          currentPage.append(' <a href="#" onclick="getPage(this.id);" id=">">></a>')
+            i = this.totalPages - 1;
+        }
       }
     }
-  }
-  currentPage.append('  ' + this.results.length + ' results');
-}
-
-Atmos.prototype.getPage = function(clickedPage) {
-  console.log(clickedPage);
-
-  var nextPage = clickedPage;
-  if (clickedPage === "<") {
-    nextPage = this.page - 5;
-  } else if (clickedPage === ">") {
-    console.log("> enabled");
-
-    nextPage = this.page + 5;
+    currentPage.append('  ' + this.results.length + ' results');
   }
 
-  nextPage--; // Need to adjust for starting at 0
+  Atmos.prototype.getPage = function(clickedPage) {
+    console.log(clickedPage);
 
-  if (nextPage < 0 ) {
-    nextPage = 0;
-    console.log("0 enabled");
-  } else if (nextPage > this.totalPages - 1) {
-    nextPage = this.totalPages - 1;
-    console.log("total enabled");
-  }
+    var nextPage = clickedPage;
+    if (clickedPage === "<") {
+      nextPage = this.page - 5;
+    } else if (clickedPage === ">") {
+      console.log("> enabled");
 
-  this.populateResults(nextPage * 20);
-  return false;
-}
-
-
-Atmos.prototype.submitAutoComplete = function() {
-  /* FIXME TODO
-  if (autocompleteText.value.length > 0) {
-    var selection = autocompleteText.value;
-    $.each(dropdown, function (i, dropdownEntry) {
-      if (dropdownEntry.substr(0, dropdownEntry.length - 1) == selection) {
-        selection = dropdownEntry;
-      }
-    });
-
-    selectedSearch["?"] = selection;
-    query(catalog, selectedSearch, onData, 1);
-    delete selectedSearch["?"];
-  }
-  */
-}
-
-Atmos.prototype.populateAutocomplete = function(fields) {
-  /* FIXME TODO
-  var isAutocompleteFullName = (autocompleteText.value.charAt(autocompleteText.value.length - 1) === "/");
-  var autocompleteFullName = autocompleteText.value;
-  for (var i = 0; i < fields.length; ++i) {
-    var fieldFullName = fields[i];
-    var entry = autocompleteFullName;
-    var skipahead = "";
-
-    if (isAutocompleteFullName) {
-      skipahead = fieldFullName.substr(autocompleteText.value.length, fieldFullName.length);
-    } else {
-      if (fieldFullName.charAt(autocompleteText.value.length) === "/") {
-        entry += "/";
-        skipahead = fieldFullName.substr(autocompleteText.value.length + 1, fieldFullName.length);
-      } else {
-        skipahead = fieldFullName.substr(autocompleteText.value.length, fieldFullName.length);
-      }
-    }
-    if (skipahead.indexOf("/") != -1) {
-      entry += skipahead.substr(0, skipahead.indexOf("/") + 1);
-    } else {
-      entry += skipahead;
+      nextPage = this.page + 5;
     }
 
-    var added = false;
-    for (var j = 0; j < dropdown.length && !added; ++j) {
-      if (dropdown[j] === entry) {
-        added = true;
-      } else if (dropdown[j] > entry) {
-        dropdown.splice(j, 0, entry);
-        added = true;
-      }
-    }
-    if (!added) {
-      dropdown.push(entry);
+    nextPage--; // Need to adjust for starting at 0
+
+    if (nextPage < 0 ) {
+      nextPage = 0;
+      console.log("0 enabled");
+    } else if (nextPage > this.totalPages - 1) {
+      nextPage = this.totalPages - 1;
+      console.log("total enabled");
     }
 
+    this.populateResults(nextPage * 20);
+    return false;
   }
-  $("#autocompleteText").autocomplete({
-    source: dropdown
-  });
-  */
-}
 
-/**
- * Adds a filter to the list of filters.
- * If a filter is already added, it will be removed instead.
- * 
- * @param {string} filter
- */
-Atmos.prototype.addFilter = function(name, category){
-  var existing = this.filters.find('span:contains(' + name + ')');
-  if (existing.length){
-    //If the category is clicked twice, then we delete it.
-    existing.remove();
-    this.applyFilters();
 
-  } else {
+  Atmos.prototype.submitAutoComplete = function() {
+    console.log("Submitted autoComplete");
+    /* FIXME TODO
+       if (autocompleteText.value.length > 0) {
+       var selection = autocompleteText.value;
+       $.each(dropdown, function (i, dropdownEntry) {
+       if (dropdownEntry.substr(0, dropdownEntry.length - 1) == selection) {
+       selection = dropdownEntry;
+       }
+       });
 
-    var filter = $('<span class="label label-default"></span>');
-    filter.text(category + ':' + name);
+       selectedSearch["?"] = selection;
+       query(catalog, selectedSearch, onData, 1);
+       delete selectedSearch["?"];
+       }
+       */
+  }
 
-    this.filters.append(filter);
+  Atmos.prototype.populateAutocomplete = function(fields) {
+    console.log(fields);
+    /* FIXME TODO
+       var isAutocompleteFullName = (autocompleteText.value.charAt(autocompleteText.value.length - 1) === "/");
+       var autocompleteFullName = autocompleteText.value;
+       for (var i = 0; i < fields.length; ++i) {
+       var fieldFullName = fields[i];
+       var entry = autocompleteFullName;
+       var skipahead = "";
 
-    this.applyFilters();
+       if (isAutocompleteFullName) {
+       skipahead = fieldFullName.substr(autocompleteText.value.length, fieldFullName.length);
+       } else {
+       if (fieldFullName.charAt(autocompleteText.value.length) === "/") {
+       entry += "/";
+       skipahead = fieldFullName.substr(autocompleteText.value.length + 1, fieldFullName.length);
+       } else {
+       skipahead = fieldFullName.substr(autocompleteText.value.length, fieldFullName.length);
+       }
+       }
+       if (skipahead.indexOf("/") != -1) {
+       entry += skipahead.substr(0, skipahead.indexOf("/") + 1);
+       } else {
+       entry += skipahead;
+       }
 
-    var scope = this;
-    filter.click(function(){
-      $(this).remove();
-      scope.applyFilters();
-    });
+       var added = false;
+       for (var j = 0; j < dropdown.length && !added; ++j) {
+       if (dropdown[j] === entry) {
+       added = true;
+       } else if (dropdown[j] > entry) {
+       dropdown.splice(j, 0, entry);
+       added = true;
+       }
+       }
+       if (!added) {
+       dropdown.push(entry);
+       }
+
+       }
+       $("#autocompleteText").autocomplete({
+       source: dropdown
+       });
+       */
+  }
+
+  /**
+   * Adds a filter to the list of filters.
+   * If a filter is already added, it will be removed instead.
+   * 
+   * @param {string} filter
+   */
+  Atmos.prototype.addFilter = function(name, category){
+    var existing = this.filters.find('span:contains(' + name + ')');
+        if (existing.length){
+          //If the category is clicked twice, then we delete it.
+          existing.remove();
+          this.applyFilters();
+
+        } else {
+
+          var filter = $('<span class="label label-default"></span>');
+          filter.text(category + ':' + name);
+
+          this.filters.append(filter);
+
+          this.applyFilters();
+
+          var scope = this;
+          filter.click(function(){
+            $(this).remove();
+            scope.applyFilters();
+          });
+
+        }
 
   }
-  
-}
 
-Atmos.prototype.applyFilters = function(){
-  var filters = this.filters.children().toArray().reduce(function(prev, current){
+  Atmos.prototype.applyFilters = function(){
+    var filters = this.filters.children().toArray().reduce(function(prev, current){
       var data = $(current).text().split(/:/);
       prev[data[0]] = data[1];
       return prev;
-  }, {});
-  console.log('Collected filters:', filters);
-  var scope = this;
-  this.query(this.catalog, filters, function(data){
-    scope.onData(data);
-  }, 1);
-}
+    }, {});
+    console.log('Collected filters:', filters);
+    var scope = this;
+    this.query(this.catalog, filters, function(data){
+      scope.onData(data);
+    }, 1);
+  }
 
-/**
- * @deprecated
- * Use addFilter instead.
- */
-Atmos.prototype.populateCurrentSelections = function() {
-  console.warn("Use of deprecated function populateCurrentSelections! (Use addFilter instead)");
-  /*
-  var currentSelection = $(".currentSelections");
-  currentSelection.empty();
+  /**
+   * @deprecated
+   * Use addFilter instead.
+   */
+  Atmos.prototype.populateCurrentSelections = function() {
+    console.warn("Use of deprecated function populateCurrentSelections! (Use addFilter instead)");
+    /*
+       var currentSelection = $(".currentSelections");
+       currentSelection.empty();
 
-  currentSelection.append("<p>Filtering on:");
+       currentSelection.append("<p>Filtering on:");
 
-  var scope = this;
+       var scope = this;
 
-  $.each(this.selectedSearch, function (searchMenuCatagory, selection) {
-    var e = $('<a href="#">[X] ' + searchMenuCatagory + ":" + selection + '</a>');
-    e.onclick(function(){
-      var searchFilter = $(this).text();
+       $.each(this.selectedSearch, function (searchMenuCatagory, selection) {
+       var e = $('<a href="#">[X] ' + searchMenuCatagory + ":" + selection + '</a>');
+       e.onclick(function(){
+       var searchFilter = $(this).text();
 
-      var search = "";
-      for (var j = 0; j < searchFilter.length; ++j) {
-        search += searchFilter[j] + " ";
-      }
-      console.log("Split values: '" + search + "'");
+       var search = "";
+       for (var j = 0; j < searchFilter.length; ++j) {
+       search += searchFilter[j] + " ";
+       }
+       console.log("Split values: '" + search + "'");
 
-      delete this.selectedSearch[searchFilter[0]];
-      this.query(catalog, selectedSearch, onData, 1);
-      populateCurrentSelections();
-    });
-    currentSelection.append(e);
-  });
+       delete this.selectedSearch[searchFilter[0]];
+       this.query(catalog, selectedSearch, onData, 1);
+       populateCurrentSelections();
+       });
+       currentSelection.append(e);
+       });
 
-  currentSelection.append("</p>");
-  */
-}
+       currentSelection.append("</p>");
+       */
+  }
+
+  return Atmos;
+
+})();
+
+
