From b14833fbb56bcd5bff0750c16fd9214009b955be Mon Sep 17 00:00:00 2001
From: Zara Gebru <zgebru@thoughtworks.com>
Date: Fri, 2 Dec 2016 15:25:23 +0100
Subject: [refactor] move app dir into public dir

---
 web-ui/app/js/dispatchers/left_pane_dispatcher.js  |  62 --
 .../app/js/dispatchers/middle_pane_dispatcher.js   |  74 ---
 web-ui/app/js/dispatchers/right_pane_dispatcher.js | 117 ----
 web-ui/app/js/features/features.js                 |  61 --
 web-ui/app/js/feedback/feedback_cache.js           |  35 --
 web-ui/app/js/feedback/feedback_trigger.js         |  39 --
 web-ui/app/js/foundation/initialize_foundation.js  |   5 -
 web-ui/app/js/foundation/off_canvas.js             |  46 --
 web-ui/app/js/helpers/browser.js                   |  36 --
 web-ui/app/js/helpers/contenttype.js               | 184 ------
 web-ui/app/js/helpers/iterator.js                  |  60 --
 web-ui/app/js/helpers/monitored_ajax.js            |  67 ---
 web-ui/app/js/helpers/sanitizer.js                 | 126 ----
 web-ui/app/js/helpers/triggering.js                |  29 -
 web-ui/app/js/helpers/view_helper.js               | 163 ------
 web-ui/app/js/lib/highlightRegex.js                | 127 ----
 web-ui/app/js/lib/html4-defs.js                    | 640 ---------------------
 web-ui/app/js/mail_list/domain/refresher.js        |  43 --
 web-ui/app/js/mail_list/ui/mail_item_factory.js    |  59 --
 .../app/js/mail_list/ui/mail_items/draft_item.js   |  55 --
 .../mail_list/ui/mail_items/generic_mail_item.js   |  97 ----
 web-ui/app/js/mail_list/ui/mail_items/mail_item.js |  88 ---
 web-ui/app/js/mail_list/ui/mail_items/sent_item.js |  61 --
 web-ui/app/js/mail_list/ui/mail_list.js            | 182 ------
 .../mail_list_actions/ui/archive_many_trigger.js   |  29 -
 .../app/js/mail_list_actions/ui/compose_trigger.js |  57 --
 .../js/mail_list_actions/ui/delete_many_trigger.js |  47 --
 .../js/mail_list_actions/ui/mail_list_actions.js   |  93 ---
 .../mail_list_actions/ui/mark_as_unread_trigger.js |  47 --
 .../ui/mark_many_as_read_trigger.js                |  47 --
 .../js/mail_list_actions/ui/pagination_trigger.js  |  66 ---
 .../mail_list_actions/ui/recover_many_trigger.js   |  47 --
 .../app/js/mail_list_actions/ui/refresh_trigger.js |  44 --
 .../ui/toggle_check_all_trigger.js                 |  49 --
 web-ui/app/js/mail_view/data/feedback_sender.js    |  49 --
 web-ui/app/js/mail_view/data/mail_builder.js       | 102 ----
 web-ui/app/js/mail_view/data/mail_sender.js        |  93 ---
 web-ui/app/js/mail_view/ui/attachment_icon.js      |  61 --
 web-ui/app/js/mail_view/ui/attachment_list.js      | 210 -------
 web-ui/app/js/mail_view/ui/compose_box.js          |  84 ---
 web-ui/app/js/mail_view/ui/draft_box.js            | 109 ----
 web-ui/app/js/mail_view/ui/draft_save_status.js    |  42 --
 web-ui/app/js/mail_view/ui/feedback_box.js         |  69 ---
 web-ui/app/js/mail_view/ui/forward_box.js          |  97 ----
 web-ui/app/js/mail_view/ui/mail_actions.js         |  84 ---
 web-ui/app/js/mail_view/ui/mail_view.js            | 255 --------
 .../app/js/mail_view/ui/no_mails_available_pane.js |  50 --
 .../js/mail_view/ui/no_message_selected_pane.js    |  41 --
 web-ui/app/js/mail_view/ui/recipients/recipient.js | 112 ----
 .../app/js/mail_view/ui/recipients/recipients.js   | 193 -------
 .../js/mail_view/ui/recipients/recipients_input.js | 180 ------
 .../mail_view/ui/recipients/recipients_iterator.js |  59 --
 web-ui/app/js/mail_view/ui/reply_box.js            | 116 ----
 web-ui/app/js/mail_view/ui/reply_section.js        | 129 -----
 web-ui/app/js/mail_view/ui/send_button.js          | 130 -----
 web-ui/app/js/main.js                              |  84 ---
 web-ui/app/js/mixins/with_auto_refresh.js          |  47 --
 web-ui/app/js/mixins/with_compose_inline.js        |  84 ---
 .../app/js/mixins/with_enable_disable_on_event.js  |  48 --
 web-ui/app/js/mixins/with_feature_toggle.js        |  40 --
 web-ui/app/js/mixins/with_hide_and_show.js         |  31 -
 web-ui/app/js/mixins/with_mail_edit_base.js        | 263 ---------
 web-ui/app/js/mixins/with_mail_sandbox.js          |  80 ---
 web-ui/app/js/mixins/with_mail_tagging.js          |  69 ---
 web-ui/app/js/monkey_patching/all.js               |  17 -
 web-ui/app/js/monkey_patching/array.js             |  27 -
 web-ui/app/js/monkey_patching/post_message.js      |  32 --
 web-ui/app/js/page/default.js                      | 146 -----
 web-ui/app/js/page/events.js                       | 222 -------
 web-ui/app/js/page/logout.js                       |  43 --
 web-ui/app/js/page/logout_shortcut.js              |  33 --
 web-ui/app/js/page/pane_contract_expand.js         |  51 --
 web-ui/app/js/page/pix_logo.js                     |  62 --
 web-ui/app/js/page/router.js                       |  71 ---
 web-ui/app/js/page/router/url_params.js            |  57 --
 web-ui/app/js/page/unread_count_title.js           |  53 --
 web-ui/app/js/page/version.js                      |  41 --
 web-ui/app/js/sandbox.js                           |  11 -
 web-ui/app/js/search/results_highlighter.js        |  97 ----
 web-ui/app/js/search/search_trigger.js             |  81 ---
 web-ui/app/js/services/delete_service.js           |  59 --
 web-ui/app/js/services/mail_service.js             | 335 -----------
 web-ui/app/js/services/model/mail.js               | 126 ----
 web-ui/app/js/services/recover_service.js          |  38 --
 web-ui/app/js/style_guide/main.js                  |  33 --
 web-ui/app/js/tags/data/tags.js                    |  66 ---
 web-ui/app/js/tags/ui/tag.js                       | 154 -----
 web-ui/app/js/tags/ui/tag_base.js                  |  68 ---
 web-ui/app/js/tags/ui/tag_list.js                  | 105 ----
 web-ui/app/js/user_alerts/ui/user_alerts.js        |  57 --
 web-ui/app/js/user_settings/data/user_settings.js  |  52 --
 .../app/js/user_settings/ui/user_settings_box.js   |  77 ---
 .../app/js/user_settings/ui/user_settings_icon.js  |  57 --
 web-ui/app/js/views/i18n.js                        |  62 --
 web-ui/app/js/views/recipientListFormatter.js      |  33 --
 web-ui/app/js/views/templates.js                   |  85 ---
 96 files changed, 8444 deletions(-)
 delete mode 100644 web-ui/app/js/dispatchers/left_pane_dispatcher.js
 delete mode 100644 web-ui/app/js/dispatchers/middle_pane_dispatcher.js
 delete mode 100644 web-ui/app/js/dispatchers/right_pane_dispatcher.js
 delete mode 100644 web-ui/app/js/features/features.js
 delete mode 100644 web-ui/app/js/feedback/feedback_cache.js
 delete mode 100644 web-ui/app/js/feedback/feedback_trigger.js
 delete mode 100644 web-ui/app/js/foundation/initialize_foundation.js
 delete mode 100644 web-ui/app/js/foundation/off_canvas.js
 delete mode 100644 web-ui/app/js/helpers/browser.js
 delete mode 100644 web-ui/app/js/helpers/contenttype.js
 delete mode 100644 web-ui/app/js/helpers/iterator.js
 delete mode 100644 web-ui/app/js/helpers/monitored_ajax.js
 delete mode 100644 web-ui/app/js/helpers/sanitizer.js
 delete mode 100644 web-ui/app/js/helpers/triggering.js
 delete mode 100644 web-ui/app/js/helpers/view_helper.js
 delete mode 100644 web-ui/app/js/lib/highlightRegex.js
 delete mode 100644 web-ui/app/js/lib/html4-defs.js
 delete mode 100644 web-ui/app/js/mail_list/domain/refresher.js
 delete mode 100644 web-ui/app/js/mail_list/ui/mail_item_factory.js
 delete mode 100644 web-ui/app/js/mail_list/ui/mail_items/draft_item.js
 delete mode 100644 web-ui/app/js/mail_list/ui/mail_items/generic_mail_item.js
 delete mode 100644 web-ui/app/js/mail_list/ui/mail_items/mail_item.js
 delete mode 100644 web-ui/app/js/mail_list/ui/mail_items/sent_item.js
 delete mode 100644 web-ui/app/js/mail_list/ui/mail_list.js
 delete mode 100644 web-ui/app/js/mail_list_actions/ui/archive_many_trigger.js
 delete mode 100644 web-ui/app/js/mail_list_actions/ui/compose_trigger.js
 delete mode 100644 web-ui/app/js/mail_list_actions/ui/delete_many_trigger.js
 delete mode 100644 web-ui/app/js/mail_list_actions/ui/mail_list_actions.js
 delete mode 100644 web-ui/app/js/mail_list_actions/ui/mark_as_unread_trigger.js
 delete mode 100644 web-ui/app/js/mail_list_actions/ui/mark_many_as_read_trigger.js
 delete mode 100644 web-ui/app/js/mail_list_actions/ui/pagination_trigger.js
 delete mode 100644 web-ui/app/js/mail_list_actions/ui/recover_many_trigger.js
 delete mode 100644 web-ui/app/js/mail_list_actions/ui/refresh_trigger.js
 delete mode 100644 web-ui/app/js/mail_list_actions/ui/toggle_check_all_trigger.js
 delete mode 100644 web-ui/app/js/mail_view/data/feedback_sender.js
 delete mode 100644 web-ui/app/js/mail_view/data/mail_builder.js
 delete mode 100644 web-ui/app/js/mail_view/data/mail_sender.js
 delete mode 100644 web-ui/app/js/mail_view/ui/attachment_icon.js
 delete mode 100644 web-ui/app/js/mail_view/ui/attachment_list.js
 delete mode 100644 web-ui/app/js/mail_view/ui/compose_box.js
 delete mode 100644 web-ui/app/js/mail_view/ui/draft_box.js
 delete mode 100644 web-ui/app/js/mail_view/ui/draft_save_status.js
 delete mode 100644 web-ui/app/js/mail_view/ui/feedback_box.js
 delete mode 100644 web-ui/app/js/mail_view/ui/forward_box.js
 delete mode 100644 web-ui/app/js/mail_view/ui/mail_actions.js
 delete mode 100644 web-ui/app/js/mail_view/ui/mail_view.js
 delete mode 100644 web-ui/app/js/mail_view/ui/no_mails_available_pane.js
 delete mode 100644 web-ui/app/js/mail_view/ui/no_message_selected_pane.js
 delete mode 100644 web-ui/app/js/mail_view/ui/recipients/recipient.js
 delete mode 100644 web-ui/app/js/mail_view/ui/recipients/recipients.js
 delete mode 100644 web-ui/app/js/mail_view/ui/recipients/recipients_input.js
 delete mode 100644 web-ui/app/js/mail_view/ui/recipients/recipients_iterator.js
 delete mode 100644 web-ui/app/js/mail_view/ui/reply_box.js
 delete mode 100644 web-ui/app/js/mail_view/ui/reply_section.js
 delete mode 100644 web-ui/app/js/mail_view/ui/send_button.js
 delete mode 100644 web-ui/app/js/main.js
 delete mode 100644 web-ui/app/js/mixins/with_auto_refresh.js
 delete mode 100644 web-ui/app/js/mixins/with_compose_inline.js
 delete mode 100644 web-ui/app/js/mixins/with_enable_disable_on_event.js
 delete mode 100644 web-ui/app/js/mixins/with_feature_toggle.js
 delete mode 100644 web-ui/app/js/mixins/with_hide_and_show.js
 delete mode 100644 web-ui/app/js/mixins/with_mail_edit_base.js
 delete mode 100644 web-ui/app/js/mixins/with_mail_sandbox.js
 delete mode 100644 web-ui/app/js/mixins/with_mail_tagging.js
 delete mode 100644 web-ui/app/js/monkey_patching/all.js
 delete mode 100644 web-ui/app/js/monkey_patching/array.js
 delete mode 100644 web-ui/app/js/monkey_patching/post_message.js
 delete mode 100644 web-ui/app/js/page/default.js
 delete mode 100644 web-ui/app/js/page/events.js
 delete mode 100644 web-ui/app/js/page/logout.js
 delete mode 100644 web-ui/app/js/page/logout_shortcut.js
 delete mode 100644 web-ui/app/js/page/pane_contract_expand.js
 delete mode 100644 web-ui/app/js/page/pix_logo.js
 delete mode 100644 web-ui/app/js/page/router.js
 delete mode 100644 web-ui/app/js/page/router/url_params.js
 delete mode 100644 web-ui/app/js/page/unread_count_title.js
 delete mode 100644 web-ui/app/js/page/version.js
 delete mode 100644 web-ui/app/js/sandbox.js
 delete mode 100644 web-ui/app/js/search/results_highlighter.js
 delete mode 100644 web-ui/app/js/search/search_trigger.js
 delete mode 100644 web-ui/app/js/services/delete_service.js
 delete mode 100644 web-ui/app/js/services/mail_service.js
 delete mode 100644 web-ui/app/js/services/model/mail.js
 delete mode 100644 web-ui/app/js/services/recover_service.js
 delete mode 100644 web-ui/app/js/style_guide/main.js
 delete mode 100644 web-ui/app/js/tags/data/tags.js
 delete mode 100644 web-ui/app/js/tags/ui/tag.js
 delete mode 100644 web-ui/app/js/tags/ui/tag_base.js
 delete mode 100644 web-ui/app/js/tags/ui/tag_list.js
 delete mode 100644 web-ui/app/js/user_alerts/ui/user_alerts.js
 delete mode 100644 web-ui/app/js/user_settings/data/user_settings.js
 delete mode 100644 web-ui/app/js/user_settings/ui/user_settings_box.js
 delete mode 100644 web-ui/app/js/user_settings/ui/user_settings_icon.js
 delete mode 100644 web-ui/app/js/views/i18n.js
 delete mode 100644 web-ui/app/js/views/recipientListFormatter.js
 delete mode 100644 web-ui/app/js/views/templates.js

(limited to 'web-ui/app/js')

diff --git a/web-ui/app/js/dispatchers/left_pane_dispatcher.js b/web-ui/app/js/dispatchers/left_pane_dispatcher.js
deleted file mode 100644
index 0037a88f..00000000
--- a/web-ui/app/js/dispatchers/left_pane_dispatcher.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'page/router/url_params',
-    'page/events'
-  ],
-
-  function(defineComponent, urlParams, events) {
-    'use strict';
-
-    return defineComponent(leftPaneDispatcher);
-
-    function leftPaneDispatcher() {
-      var initialized = false;
-
-      this.refreshTagList = function (ev, data) {
-        this.trigger(document, events.tags.want, { caller: this.$node, skipMailListRefresh: data.skipMailListRefresh });
-      };
-
-      this.loadTags = function (ev, data) {
-        this.trigger(document, events.ui.tagList.load, data);
-      };
-
-      this.selectTag = function (ev, data) {
-        var tag = (data && data.tag) || urlParams.getTag();
-        this.trigger(document, events.ui.tag.select, { tag: tag, skipMailListRefresh: data.skipMailListRefresh });
-      };
-
-      this.pushUrlState = function (ev, data) {
-        if (initialized) {
-          this.trigger(document, events.router.pushState, data);
-        }
-        initialized = true;
-      };
-
-      this.after('initialize', function () {
-        //this.on(this.$node, events.tags.received, this.loadTags);
-        this.on(document, events.dispatchers.tags.refreshTagList, this.refreshTagList);
-        this.on(document, events.ui.tags.loaded, this.selectTag);
-        this.on(document, events.ui.tag.selected, this.pushUrlState);
-        this.on(document, events.ui.tag.select, this.pushUrlState);
-        this.trigger(document, events.tags.want, { caller: this.$node });
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/dispatchers/middle_pane_dispatcher.js b/web-ui/app/js/dispatchers/middle_pane_dispatcher.js
deleted file mode 100644
index 12222aec..00000000
--- a/web-ui/app/js/dispatchers/middle_pane_dispatcher.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(['flight/lib/component', 'page/events', 'helpers/triggering', 'mail_view/ui/no_mails_available_pane'], function(defineComponent, events, triggering, NoMailsAvailablePane) {
-  'use strict';
-
-  return defineComponent(function() {
-    this.defaultAttrs({
-      middlePane: '#middle-pane',
-      noMailsAvailablePane: 'no-mails-available-pane'
-    });
-
-    this.createChildDiv = function (component_id) {
-      var child_div = $('<div>', {id: component_id});
-      this.select('middlePane').append(child_div);
-      return child_div;
-    };
-
-    this.resetChildDiv = function(component_id) {
-      $('#' + component_id).remove();
-    };
-
-    this.refreshMailList =  function (ev, data) {
-      this.trigger(document, events.ui.mails.fetchByTag, data);
-    };
-
-    this.cleanSelected = function(ev, data) {
-      this.trigger(document, events.ui.mails.cleanSelected);
-    };
-
-    this.resetScroll = function() {
-      this.select('middlePane').scrollTop(0);
-    };
-
-    this.updateMiddlePaneHeight = function() {
-        var vh = $(window).height();
-        var top = $('#main').outerHeight() + $('#top-pane').outerHeight();
-        this.select('middlePane').css({height: (vh - top) + 'px'});
-    };
-
-    this.onMailsChange = function (ev, data) {
-      this.resetChildDiv(this.attr.noMailsAvailablePane);
-      if (data.mails.length > 0) {
-        NoMailsAvailablePane.teardownAll();
-      } else {
-        var child_div = this.createChildDiv(this.attr.noMailsAvailablePane);
-        NoMailsAvailablePane.attachTo(child_div, {tag: data.tag, forSearch: data.forSearch});
-      }
-    };
-
-    this.after('initialize', function () {
-      this.on(document, events.dispatchers.middlePane.refreshMailList, this.refreshMailList);
-      this.on(document, events.dispatchers.middlePane.cleanSelected, this.cleanSelected);
-      this.on(document, events.dispatchers.middlePane.resetScroll, this.resetScroll);
-      this.on(document, events.mails.available, this.onMailsChange);
-
-      this.updateMiddlePaneHeight();
-      $(window).on('resize', this.updateMiddlePaneHeight.bind(this));
-    });
-  });
-});
diff --git a/web-ui/app/js/dispatchers/right_pane_dispatcher.js b/web-ui/app/js/dispatchers/right_pane_dispatcher.js
deleted file mode 100644
index 870bcd92..00000000
--- a/web-ui/app/js/dispatchers/right_pane_dispatcher.js
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-  [
-    'flight/lib/component',
-    'mail_view/ui/compose_box',
-    'mail_view/ui/mail_view',
-    'mail_view/ui/reply_section',
-    'mail_view/ui/draft_box',
-    'mail_view/ui/no_message_selected_pane',
-    'mail_view/ui/feedback_box',
-    'page/events'
-  ],
-
-  function(defineComponent, ComposeBox, MailView, ReplySection, DraftBox, NoMessageSelectedPane, FeedbackBox, events) {
-    'use strict';
-
-    return defineComponent(rightPaneDispatcher);
-
-    function rightPaneDispatcher() {
-      this.defaultAttrs({
-        rightPane: '#right-pane',
-        composeBox: 'compose-box',
-        feedbackBox: 'feedback-box',
-        mailView: 'mail-view',
-        noMessageSelectedPane: 'no-message-selected-pane',
-        replySection: 'reply-section',
-        draftBox: 'draft-box',
-        currentTag: ''
-      });
-
-      this.createAndAttach = function(newContainer) {
-        var stage = $('<div>', { id: newContainer });
-        this.select('rightPane').append(stage);
-        return stage;
-      };
-
-      this.reset = function (newContainer) {
-        this.trigger(document, events.dispatchers.rightPane.clear);
-        this.select('rightPane').empty();
-        var stage = this.createAndAttach(newContainer);
-        return stage;
-      };
-
-      this.openComposeBox = function() {
-        var stage = this.reset(this.attr.composeBox);
-        ComposeBox.attachTo(stage, {currentTag: this.attr.currentTag});
-      };
-
-      this.openFeedbackBox = function() {
-        var stage = this.reset(this.attr.feedbackBox);
-        FeedbackBox.attachTo(stage);
-      };
-
-      this.openMail = function(ev, data) {
-        var stage = this.reset(this.attr.mailView);
-        MailView.attachTo(stage, data);
-
-        var replySectionContainer = this.createAndAttach(this.attr.replySection);
-        ReplySection.attachTo(replySectionContainer, { ident: data.ident });
-      };
-
-      this.initializeNoMessageSelectedPane = function () {
-        var stage = this.reset(this.attr.noMessageSelectedPane);
-        NoMessageSelectedPane.attachTo(stage);
-        this.trigger(document, events.dispatchers.middlePane.cleanSelected);
-      };
-
-      this.openNoMessageSelectedPane = function(ev, data) {
-        this.initializeNoMessageSelectedPane();
-
-        this.trigger(document, events.router.pushState, { tag: this.attr.currentTag, isDisplayNoMessageSelected: true });
-      };
-
-      this.openDraft = function (ev, data) {
-        var stage = this.reset(this.attr.draftBox);
-        DraftBox.attachTo(stage, { mailIdent: data.ident, currentTag: this.attr.currentTag });
-      };
-
-      this.selectTag = function(ev, data) {
-        this.trigger(document, events.ui.tags.loaded, {tag: data.tag});
-      };
-
-      this.saveTag = function(ev, data) {
-        this.attr.currentTag = data.tag;
-      };
-
-      this.after('initialize', function () {
-        this.on(document, events.dispatchers.rightPane.openComposeBox, this.openComposeBox);
-        this.on(document, events.dispatchers.rightPane.openDraft, this.openDraft);
-        this.on(document, events.ui.mail.open, this.openMail);
-        this.on(document, events.dispatchers.rightPane.openFeedbackBox, this.openFeedbackBox);
-        this.on(document, events.dispatchers.rightPane.openNoMessageSelected, this.openNoMessageSelectedPane);
-        this.on(document, events.dispatchers.rightPane.selectTag, this.selectTag);
-        this.on(document, events.ui.tag.selected, this.saveTag);
-        this.on(document, events.ui.tag.select, this.saveTag);
-        this.on(document, events.dispatchers.rightPane.openNoMessageSelectedWithoutPushState, this.initializeNoMessageSelectedPane);
-        this.initializeNoMessageSelectedPane();
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/features/features.js b/web-ui/app/js/features/features.js
deleted file mode 100644
index f71d56ea..00000000
--- a/web-ui/app/js/features/features.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(['helpers/monitored_ajax'], function(monitoredAjax) {
- 'use strict';
-  var cachedDisabledFeatures;
-  var cachedMultiUserFeatures;
-
-  function getDisabledFeatures() {
-    cachedDisabledFeatures = cachedDisabledFeatures || fetchFeatures().disabled_features;
-    return cachedDisabledFeatures;
-  }
-
-  function getMultiUserFeatures() {
-    cachedMultiUserFeatures = cachedMultiUserFeatures || fetchFeatures().multi_user;
-    return cachedMultiUserFeatures;
-  }
-
-  function fetchFeatures() {
-    var features;
-    monitoredAjax(this, '/features', {
-      async: false,
-      success: function (results) {
-        features = results;
-      },
-      error: function () {
-        console.error('Could not load feature toggles');
-      }
-    });
-    return features;
-  }
-
-  return {
-    isEnabled: function (featureName) {
-      return ! _.contains(getDisabledFeatures(), featureName);
-    },
-    isAutoRefreshEnabled: function () {
-      return this.isEnabled('autoRefresh');
-    },
-    isLogoutEnabled: function () {
-      return _.has(getMultiUserFeatures(), 'logout');
-    },
-    getLogoutUrl: function () {
-      return getMultiUserFeatures().logout;
-    }
-  };
-});
diff --git a/web-ui/app/js/feedback/feedback_cache.js b/web-ui/app/js/feedback/feedback_cache.js
deleted file mode 100644
index a5d92266..00000000
--- a/web-ui/app/js/feedback/feedback_cache.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2016 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define([], function() {
-  'use strict';
-
-  return (function() {
-    var feedbackCache = '';
-    return {
-      resetCache: function () {
-        feedbackCache = '';
-      },
-      setCache: function(feedback) {
-        feedbackCache = feedback;
-      },
-      getCache: function() {
-        return feedbackCache;
-      }
-    };
-  })();
-});
diff --git a/web-ui/app/js/feedback/feedback_trigger.js b/web-ui/app/js/feedback/feedback_trigger.js
deleted file mode 100644
index 598f9060..00000000
--- a/web-ui/app/js/feedback/feedback_trigger.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2015 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(['flight/lib/component', 'views/templates', 'page/events', 'features'],
-    function (defineComponent, templates, events, features) {
-  'use strict';
-
-  return defineComponent(function () {
-    this.render = function () {
-      this.$node.html(templates.feedback.feedback());
-    };
-
-    this.onClick = function() {
-      this.trigger(document, events.dispatchers.rightPane.openFeedbackBox);
-    };
-
-    this.after('initialize', function () {
-      if (features.isEnabled('feedback')) {
-          this.render();
-          this.on('click', this.onClick);
-      }
-    });
-
-  });
-});
diff --git a/web-ui/app/js/foundation/initialize_foundation.js b/web-ui/app/js/foundation/initialize_foundation.js
deleted file mode 100644
index 42405dfe..00000000
--- a/web-ui/app/js/foundation/initialize_foundation.js
+++ /dev/null
@@ -1,5 +0,0 @@
-
-(function() {
- 'use strict';
- $(document).foundation();
-})();
diff --git a/web-ui/app/js/foundation/off_canvas.js b/web-ui/app/js/foundation/off_canvas.js
deleted file mode 100644
index 66334470..00000000
--- a/web-ui/app/js/foundation/off_canvas.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(['flight/lib/component', 'page/events'], function (defineComponent, events) {
-  'use strict';
-  return defineComponent(function() {
-
-    this.closeSlider = function (ev){
-      $('.off-canvas-wrap.content').removeClass('move-right');
-      this.toggleTagsVisibility();
-    };
-
-    this.toggleSlideContent = function (ev) {
-      ev.preventDefault();
-  	  $('.left-off-canvas-toggle').click();
-	  this.toggleTagsVisibility();
-    };
-
-    this.toggleTagsVisibility = function () {
-	  if ($('.off-canvas-wrap.content').hasClass('move-right')) {
-	    $('#custom-tag-list').addClass('expanded');
-	  } else {
-	    $('#custom-tag-list').removeClass('expanded');
-	  }
-    };
-
-    this.after('initialize', function () {
-      this.on($('#middle-pane-container'), 'click', this.closeSlider);
-      this.on($('#right-pane'), 'click', this.closeSlider);
-      this.on($('.side-nav-toggle'), 'click', this.toggleSlideContent);
-    });
-  });
-});
diff --git a/web-ui/app/js/helpers/browser.js b/web-ui/app/js/helpers/browser.js
deleted file mode 100644
index dacf2263..00000000
--- a/web-ui/app/js/helpers/browser.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define([], function () {
-
-  'use strict';
-
-  function redirect(url) {
-    window.location.replace(url);
-  }
-
-  function getCookie(name) {
-    var value = '; ' + document.cookie;
-    var parts = value.split('; ' + name + '=');
-    if (parts.length === 2) { return parts.pop().split(';').shift(); }
-  }
-
-  return {
-    redirect: redirect,
-    getCookie: getCookie
-  };
-});
diff --git a/web-ui/app/js/helpers/contenttype.js b/web-ui/app/js/helpers/contenttype.js
deleted file mode 100644
index a1e5361a..00000000
--- a/web-ui/app/js/helpers/contenttype.js
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* jshint curly: false */
-define([], function () {
-  'use strict';
-  var exports = {};
-
-  // Licence: PUBLIC DOMAIN <http://unlicense.org/>
-  // Author: Austin Wright <http://github.com/Acubed>
-
-  function MediaType(s, p){
-	this.type = '';
-	this.params = {};
-    var c, i, n;
-	if(typeof s==='string'){
-	  c = splitQuotedString(s);
-	  this.type = c.shift();
-	  for(i=0; i<c.length; i++){
-		this.parseParameter(c[i]);
-	  }
-	}else if(s instanceof MediaType){
-	  this.type = s.type;
-	  this.q = s.q;
-	  for(n in s.params) this.params[n]=s.params[n];
-	}
-	if(typeof p==='string'){
-	  c = splitQuotedString(p);
-	  for(i=0; i<c.length; i++){
-		this.parseParameter(c[i]);
-	  }
-	}else if(typeof p==='object'){
-	  for(n in p) this.params[n]=p[n];
-	}
-  }
-  MediaType.prototype.parseParameter = function parseParameter(s){
-	var param = s.split('=',1);
-	var name = param[0].trim();
-	var value = s.substr(param[0].length+1).trim();
-	if(!value || !name) return;
-	if(name==='q' && this.q===undefined){
-	  this.q=parseFloat(value);
-	}else{
-	  if(value[0]==='"' && value[value.length-1]==='"'){
-		value = value.substr(1, value.length-2);
-		value = value.replace(/\\(.)/g, function(a,b){return b;});
-	  }
-	  this.params[name]=value;
-	}
-  };
-  MediaType.prototype.toString = function toString(){
-	var str = this.type + ';q='+this.q;
-	for(var n in this.params){
-	  str += ';'+n+'=';
-	  if(this.params[n].match(/["=;<>\[\]\(\) ,\-]/)){
-		str += '"' + this.params[n].replace(/["\\]/g, function(a){return '\\'+a;}) + '"';
-	  }else{
-		str += this.params[n];
-	  }
-	}
-	return str;
-  };
-  exports.MediaType = MediaType;
-
-  // Split a string by character, but ignore quoted parts and backslash-escaped characters
-  function splitQuotedString(str, delim, quote){
-	delim = delim || ';';
-	quote = quote || '"';
-	var res = [];
-	var start = 0;
-	var offset = 0;
-	function findNextChar(v, c, i, a){
-	  var p = str.indexOf(c, offset+1);
-	  return (p<0)?v:Math.min(p,v);
-	}
-	while(offset>=0){
-	  offset = [delim,quote].reduce(findNextChar, 1/0);
-	  if(offset===1/0) break;
-	  switch(str[offset]){
-	  case quote:
-		// Skip to end of quoted string
-		while(1){
-		  offset=str.indexOf(quote, offset+1);
-		  if(offset<0) break;
-		  if(str[offset-1]==='\\') continue;
-		  break;
-		}
-		continue;
-	  case delim:
-		res.push(str.substr(start, offset-start).trim());
-		start = ++offset;
-		break;
-	  }
-	}
-	res.push(str.substr(start).trim());
-	return res;
-  }
-  exports.splitQuotedString = splitQuotedString;
-
-  // Split a list of content types found in an Accept header
-  // Maybe use it like: splitContentTypes(request.headers.accept).map(parseMedia)
-  function splitContentTypes(str){
-	return splitQuotedString(str, ',');
-  }
-  exports.splitContentTypes = splitContentTypes;
-
-  function parseMedia(str){
-	var o = new MediaType(str);
-	if(o.q===undefined) o.q=1;
-	return o;
-  }
-  exports.parseMedia = parseMedia;
-
-  // Pick an ideal representation to send given a list of representations to choose from and the client-preferred list
-  function select(reps, accept){
-	var cr = {q:0};
-	var ca = {q:0};
-	var cq = 0;
-	for(var i=0; i<reps.length; i++){
-	  var r = reps[i];
-	  var rq = r.q || 1;
-	  for(var j=0; j<accept.length; j++){
-		var a=accept[j];
-		var aq = a.q || 1;
-		var cmp = mediaCmp(a, r);
-		if(cmp!==null && cmp>=0){
-		  if(aq*rq>cq){
-			ca = a;
-			cr = r;
-			cq = ca.q*cr.q;
-			if(cq===1 && cr.type) return cr;
-		  }
-		}
-	  }
-	}
-	return cr.type&&cr;
-  }
-  exports.select = select;
-
-  // Determine if one media type is a subset of another
-  // If a is a superset of b (b is smaller than a), return 1
-  // If b is a superset of a, return -1
-  // If they are the exact same, return 0
-  // If they are disjoint, return null
-  function mediaCmp(a, b){
-	if(a.type==='*/*' && b.type!=='*/*') return 1;
-	else if(a.type!=='*/*' && b.type==='*/*') return -1;
-	var ac = (a.type||'').split('/');
-	var bc = (b.type||'').split('/');
-	if(ac[0]==='*' && bc[0]!=='*') return 1;
-	if(ac[0]!=='*' && bc[0]==='*') return -1;
-	if(a.type!==b.type) return null;
-	var ap = a.params || {};
-	var bp = b.params || {};
-	var ak = Object.keys(ap);
-	var bk = Object.keys(bp);
-	if(ak.length < bk.length) return 1;
-	if(ak.length > bk.length) return -1;
-	var k = ak.concat(bk).sort();
-	var dir = 0;
-	for(var n in ap){
-	  if(ap[n] && !bp[n]){ if(dir<0) return null; else dir=1; }
-	  if(!ap[n] && bp[n]){ if(dir>0) return null; else dir=-1; }
-	}
-	return dir;
-  }
-  exports.mediaCmp = mediaCmp;
-
-  return exports;
-});
diff --git a/web-ui/app/js/helpers/iterator.js b/web-ui/app/js/helpers/iterator.js
deleted file mode 100644
index 236c7a40..00000000
--- a/web-ui/app/js/helpers/iterator.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(function () {
-  'use strict';
-
-  return Iterator;
-
-  function Iterator(elems, startingIndex) {
-
-    this.index = startingIndex || 0;
-    this.elems = elems;
-
-    this.hasPrevious = function () {
-      return this.index !== 0;
-    };
-
-    this.hasNext = function () {
-      return this.index < this.elems.length - 1;
-    };
-
-    this.previous = function () {
-      return this.elems[--this.index];
-    };
-
-    this.next = function () {
-      return this.elems[++this.index];
-    };
-
-    this.current = function () {
-      return this.elems[this.index];
-    };
-
-    this.hasElements = function () {
-      return this.elems.length > 0;
-    };
-
-    this.removeCurrent = function () {
-      var removed = this.current(),
-        toRemove = this.index;
-
-      if(!this.hasNext()) { this.index--; }
-      this.elems.remove(toRemove);
-      return removed;
-    };
-  }
-});
diff --git a/web-ui/app/js/helpers/monitored_ajax.js b/web-ui/app/js/helpers/monitored_ajax.js
deleted file mode 100644
index bbf85c45..00000000
--- a/web-ui/app/js/helpers/monitored_ajax.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(['page/events', 'views/i18n', 'helpers/browser'], function (events, i18n, browser) {
-
-  'use strict';
-
-  var messages = {
-    timeout: 'error.timeout',
-    error: 'error.general',
-    parseerror: 'error.parse'
-  };
-
-  function monitoredAjax(on, url, config) {
-    config = config || {};
-    config.timeout = 60 * 1000;
-
-    var originalBeforeSend = config.beforeSend;
-    config.beforeSend = function () {
-      if (originalBeforeSend) {
-        originalBeforeSend();
-      }
-    };
-
-    config.headers = {'X-XSRF-TOKEN': browser.getCookie('XSRF-TOKEN')};
-
-    var originalComplete = config.complete;
-    config.complete = function () {
-      if (originalComplete) {
-        originalComplete();
-      }
-    };
-
-    return $.ajax(url, config).fail(function (xmlhttprequest, textstatus, message) {
-      if (!config.skipErrorMessage) {
-        var msg = (xmlhttprequest.responseJSON && xmlhttprequest.responseJSON.message) ||
-          messages[textstatus] || messages.error;
-        on.trigger(document, events.ui.userAlerts.displayMessage, {message: i18n.t(msg), class: 'error'});
-      }
-
-      if (xmlhttprequest.status === 302) {
-        var redirectUrl = xmlhttprequest.getResponseHeader('Location');
-        browser.redirect(redirectUrl);
-      } else if (xmlhttprequest.status === 401) {
-        browser.redirect('/');
-      }
-
-    }.bind(this));
-  }
-
-  return monitoredAjax;
-
-});
diff --git a/web-ui/app/js/helpers/sanitizer.js b/web-ui/app/js/helpers/sanitizer.js
deleted file mode 100644
index 443e8602..00000000
--- a/web-ui/app/js/helpers/sanitizer.js
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2016 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(['DOMPurify', 'he'], function (DOMPurify, he) {
-  'use strict';
-
-  /**
-   * Sanitizes a mail body to safe-to-display HTML
-   */
-  var sanitizer = {};
-
-  sanitizer.whitelist = [{
-    // highlight tag open
-    pre: '&#x3C;&#x65;&#x6D;&#x20;&#x63;&#x6C;&#x61;&#x73;&#x73;&#x3D;&#x22;&#x73;&#x65;&#x61;&#x72;&#x63;&#x68;&#x2D;&#x68;&#x69;&#x67;&#x68;&#x6C;&#x69;&#x67;&#x68;&#x74;&#x22;&#x3E;',
-    post: '<em class="search-highlight">'
-  }, {
-    // highlight tag close
-    pre: '&#x3C;&#x2F;&#x65;&#x6D;&#x3E;',
-    post: '</em>'
-  }];
-
-  /**
-   * Adds html line breaks to a plaintext with line breaks (incl carriage return)
-   *
-   * @param {string} textPlainBody Plaintext input
-   * @returns {string} Plaintext with HTML line breals (<br/>)
-   */
-  sanitizer.addLineBreaks = function (textPlainBody) {
-    return textPlainBody.replace(/(\r)?\n/g, '<br/>').replace(/(&#xD;)?&#xA;/g, '<br/>');
-  };
-
-  /**
-   * Runs a given dirty body through DOMPurify, thereby removing
-   * potentially hazardous XSS attacks. Please be advised that this
-   * will not act as a privacy leak prevention. Contained contents
-   * will still point to remote sources.
-   *
-   * For future reference: Running DOMPurify with these parameters
-   * can help mitigate some of the most widely used privacy leaks.
-   * FORBID_TAGS: ['style', 'svg', 'audio', 'video', 'math'],
-   * FORBID_ATTR: ['src']
-   *
-   * @param  {string} dirtyBody The unsanitized string
-   * @return {string} Safe-to-display HTML string
-   */
-  sanitizer.purifyHtml = function (dirtyBody) {
-    return DOMPurify.sanitize(dirtyBody, {
-      SAFE_FOR_JQUERY: true,
-      SAFE_FOR_TEMPLATES: true
-    });
-  };
-
-  /**
-   * Runs a given dirty body through he, thereby encoding everything
-   * as HTML entities.
-   *
-   * @param  {string} dirtyBody The unsanitized string
-   * @return {string} Safe-to-display HTML string
-   */
-  sanitizer.purifyText = function (dirtyBody) {
-    var escapedBody = he.encode(dirtyBody, {
-      encodeEverything: true
-    });
-
-    this.whitelist.forEach(function(entry) {
-      while (escapedBody.indexOf(entry.pre) > -1) {
-        escapedBody = escapedBody.replace(entry.pre, entry.post);
-      }
-    });
-
-    return escapedBody;
-  };
-
-  /**
-   * Calls #purify and #addLineBreaks to turn untrusted mail body content
-   * into safe-to-display HTML.
-   *
-   * NB: HTML content is preferred to plaintext content.
-   *
-   * @param  {object} mail Pixelated Mail Object
-   * @return {string} Safe-to-display HTML string
-   */
-  sanitizer.sanitize = function (mail) {
-    var body;
-
-    if (mail.htmlBody) {
-      body = this.purifyHtml(mail.htmlBody);
-    } else {
-      body = this.purifyText(mail.textPlainBody);
-      body = this.addLineBreaks(body);
-    }
-
-    return body;
-  };
-
-  /**
-   * Add hooks to DOMPurify for opening links in new windows
-   */
-  DOMPurify.addHook('afterSanitizeAttributes', function (node) {
-    // set all elements owning target to target=_blank
-    if ('target' in node) {
-      node.setAttribute('target', '_blank');
-    }
-
-    // set non-HTML/MathML links to xlink:show=new
-    if (!node.hasAttribute('target') && (node.hasAttribute('xlink:href') || node.hasAttribute('href'))) {
-      node.setAttribute('xlink:show', 'new');
-    }
-  });
-
-  return sanitizer;
-});
diff --git a/web-ui/app/js/helpers/triggering.js b/web-ui/app/js/helpers/triggering.js
deleted file mode 100644
index d26d9fc6..00000000
--- a/web-ui/app/js/helpers/triggering.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define([], function() {
-  'use strict';
-
-  return function(that, event, data, on) {
-    return function() {
-      if(on) {
-        that.trigger(on, event, data || {});
-      } else {
-        that.trigger(event, data || {});
-      }
-    };
-  };
-});
diff --git a/web-ui/app/js/helpers/view_helper.js b/web-ui/app/js/helpers/view_helper.js
deleted file mode 100644
index ed9e0559..00000000
--- a/web-ui/app/js/helpers/view_helper.js
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'helpers/contenttype',
-    'views/i18n',
-    'quoted-printable/quoted-printable',
-    'utf8/utf8',
-    'helpers/sanitizer'
-  ],
-  function(contentType, i18n, quotedPrintable, utf8, sanitizer) {
-  'use strict';
-
-  function formatStatusClasses(ss) {
-    return _.map(ss, function(s) {
-      return 'status-' + s;
-    }).join(' ');
-  }
-
-  function formatMailBody(mail) {
-    return sanitizer.sanitize(mail);
-  }
-
-  function moveCaretToEnd(el) {
-    if (typeof el.selectionStart === 'number') {
-      el.selectionStart = el.selectionEnd = el.value.length;
-    } else if (typeof el.createTextRange !== 'undefined') {
-      el.focus();
-      var range = el.createTextRange();
-      range.collapse(false);
-      range.select();
-    }
-  }
-
-  function fixedSizeNumber(num, size) {
-    var res = num.toString();
-    while(res.length < size) {
-      res = '0' + res;
-    }
-    return res;
-  }
-
-  function createTodayDate() {
-    var today = new Date();
-    today.setHours(0);
-    today.setMinutes(0);
-    today.setSeconds(0);
-    return today;
-  }
-
-  function moveCaretToEndOfText() {
-    var self = this;
-
-    moveCaretToEnd(self);
-    window.setTimeout(function() {
-      moveCaretToEnd(self);
-    }, 1);
-  }
-
-  function prependFrom(mail) {
-    return i18n.t(
-      'reply-author-line', {'date': new Date(mail.header.date).toString(), 'from': mail.header.from}
-    );
-  }
-
-  function quoteMail(mail) {
-    return '\n\n' + prependFrom(mail) + mail.textPlainBody.replace(/^/mg, '> ');
-  }
-
-  function formatDate(dateString) {
-    var date = new Date(dateString);
-    var today = createTodayDate();
-    if (date.getTime() > today.getTime()) {
-      return fixedSizeNumber(date.getHours(), 2) + ':' + fixedSizeNumber(date.getMinutes(), 2);
-    } else {
-      return '' + date.getFullYear() + '-' + fixedSizeNumber(date.getMonth() + 1, 2) + '-' + fixedSizeNumber(date.getDate(), 2);
-    }
-  }
-
-  function formatSize(bytes) {
-    var e = Math.floor(Math.log(bytes) / Math.log(1024));
-    return (bytes / Math.pow(1024, e)).toFixed(2) + ' ' + ' KMGTP'.charAt(e) + 'b';
-  }
-
-
-  function formatFingerPrint(fingerprint) {
-    fingerprint = fingerprint || '';
-    return fingerprint.replace(/(.{4})/g, '$1 ').trim();
-  }
-
-  function getSinceDate(sinceDate){
-    var commitDate = new Date(sinceDate);
-    var number = Date.now();
-    var millisecondsSince = number - commitDate;
-
-    var SECONDS = 1000,
-        MIN = 60 * SECONDS,
-        HOUR = MIN * 60,
-        DAY = HOUR * 24,
-        WEEK = DAY * 7,
-        MONTH = WEEK * 4,
-        YEAR = DAY * 365;
-
-    var years = Math.floor(millisecondsSince / YEAR);
-    if (years >= 1){
-      return years + ' year(s)';
-    }
-
-    var months = Math.floor(millisecondsSince / MONTH);
-    if (months >= 1) {
-      return months + ' month(s)';
-    }
-
-    var weeks = Math.floor(millisecondsSince / WEEK);
-    if (weeks >= 1) {
-      return weeks + ' week(s)';
-    }
-
-    var days = Math.floor(millisecondsSince / DAY);
-    if (days >= 1) {
-      return days + ' day(s)';
-    }
-
-    var hours = Math.floor(millisecondsSince / HOUR);
-    if (hours >= 1) {
-      return hours + ' hour(s)';
-    }
-
-    var minutes = Math.floor(millisecondsSince / MIN);
-    return minutes + ' minute(s)';
-  }
-
-  Handlebars.registerHelper('formatDate', formatDate);
-  Handlebars.registerHelper('formatSize', formatSize);
-  Handlebars.registerHelper('formatStatusClasses', formatStatusClasses);
-  Handlebars.registerHelper('formatFingerPrint', formatFingerPrint);
-  Handlebars.registerHelper('sinceDate', getSinceDate);
-
-  return {
-    formatStatusClasses: formatStatusClasses,
-    formatSize: formatSize,
-    formatMailBody: formatMailBody,
-    formatFingerPrint: formatFingerPrint,
-    moveCaretToEndOfText: moveCaretToEndOfText,
-    quoteMail: quoteMail,
-    sinceDate: getSinceDate,
-    i18n: i18n
-  };
-});
diff --git a/web-ui/app/js/lib/highlightRegex.js b/web-ui/app/js/lib/highlightRegex.js
deleted file mode 100644
index 17caaa23..00000000
--- a/web-ui/app/js/lib/highlightRegex.js
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * jQuery Highlight Regex Plugin v0.1.2
- *
- * Based on highlight v3 by Johann Burkard
- * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
- *
- * (c) 2009-13 Jacob Rothstein
- * MIT license
- */
-
-;(function( $ ) {
-
-
-
-  var normalize = function( node ) {
-    if ( ! ( node && node.childNodes )) return
-
-    var children     = $.makeArray( node.childNodes )
-    ,   prevTextNode = null
-
-    $.each( children, function( i, child ) {
-      if ( child.nodeType === 3 ) {
-        if ( child.nodeValue === "" ) {
-
-          node.removeChild( child )
-
-        } else if ( prevTextNode !== null ) {
-
-          prevTextNode.nodeValue += child.nodeValue;
-          node.removeChild( child )
-
-        } else {
-
-          prevTextNode = child
-
-        }
-      } else {
-        prevTextNode = null
-
-        if ( child.childNodes ) {
-          normalize( child )
-        }
-      }
-    })
-  }
-
-
-
-
-  $.fn.highlightRegex = function( regex, options ) {
-
-    if ( typeof regex === 'object' && !(regex.constructor.name == 'RegExp' || regex instanceof RegExp ) ) {
-      options = regex
-      regex = undefined
-    }
-
-    if ( typeof options === 'undefined' ) options = {}
-
-    options.className = options.className || 'highlight'
-    options.tagType   = options.tagType   || 'span'
-    options.attrs     = options.attrs     || {}
-
-    if ( typeof regex === 'undefined' || regex.source === '' ) {
-
-      $( this ).find( options.tagType + '.' + options.className ).each( function() {
-
-        $( this ).replaceWith( $( this ).text() )
-
-        normalize( $( this ).parent().get( 0 ))
-
-      })
-
-    } else {
-
-      $( this ).each( function() {
-
-        var elt = $( this ).get( 0 )
-
-        normalize( elt )
-
-        $.each( $.makeArray( elt.childNodes ), function( i, searchnode ) {
-
-          var spannode, middlebit, middleclone, pos, match, parent
-
-          normalize( searchnode )
-
-          if ( searchnode.nodeType == 3 ) {
-            
-            // don't re-highlight the same node over and over
-            if ( $(searchnode).parent(options.tagType + '.' + options.className).length ) {
-                return;
-            }
-
-            while ( searchnode.data &&
-                    ( pos = searchnode.data.search( regex )) >= 0 ) {
-
-              match = searchnode.data.slice( pos ).match( regex )[ 0 ]
-
-              if ( match.length > 0 ) {
-
-                spannode = document.createElement( options.tagType )
-                spannode.className = options.className
-                $(spannode).attr(options.attrs)
-
-                parent      = searchnode.parentNode
-                middlebit   = searchnode.splitText( pos )
-                searchnode  = middlebit.splitText( match.length )
-                middleclone = middlebit.cloneNode( true )
-
-                spannode.appendChild( middleclone )
-                parent.replaceChild( spannode, middlebit )
-
-              } else break
-            }
-
-          } else {
-
-            $( searchnode ).highlightRegex( regex, options )
-
-          }
-        })
-      })
-    }
-
-    return $( this )
-  }
-})( jQuery );
diff --git a/web-ui/app/js/lib/html4-defs.js b/web-ui/app/js/lib/html4-defs.js
deleted file mode 100644
index 1ec575da..00000000
--- a/web-ui/app/js/lib/html4-defs.js
+++ /dev/null
@@ -1,640 +0,0 @@
-// Copyright Google Inc.
-// Licensed under the Apache Licence Version 2.0
-// Autogenerated at Mon Jul 14 18:51:33 BRT 2014
-// @overrides window
-// @provides html4
-define([], function() {
-var html4 = {};
-html4.atype = {
-  'NONE': 0,
-  'URI': 1,
-  'URI_FRAGMENT': 11,
-  'SCRIPT': 2,
-  'STYLE': 3,
-  'HTML': 12,
-  'ID': 4,
-  'IDREF': 5,
-  'IDREFS': 6,
-  'GLOBAL_NAME': 7,
-  'LOCAL_NAME': 8,
-  'CLASSES': 9,
-  'FRAME_TARGET': 10,
-  'MEDIA_QUERY': 13
-};
-html4[ 'atype' ] = html4.atype;
-html4.ATTRIBS = {
-  '*::class': 9,
-  '*::dir': 0,
-  '*::draggable': 0,
-  '*::hidden': 0,
-  '*::id': 4,
-  '*::inert': 0,
-  '*::itemprop': 0,
-  '*::itemref': 6,
-  '*::itemscope': 0,
-  '*::lang': 0,
-  '*::onblur': 2,
-  '*::onchange': 2,
-  '*::onclick': 2,
-  '*::ondblclick': 2,
-  '*::onerror': 2,
-  '*::onfocus': 2,
-  '*::onkeydown': 2,
-  '*::onkeypress': 2,
-  '*::onkeyup': 2,
-  '*::onload': 2,
-  '*::onmousedown': 2,
-  '*::onmousemove': 2,
-  '*::onmouseout': 2,
-  '*::onmouseover': 2,
-  '*::onmouseup': 2,
-  '*::onreset': 2,
-  '*::onscroll': 2,
-  '*::onselect': 2,
-  '*::onsubmit': 2,
-  '*::ontouchcancel': 2,
-  '*::ontouchend': 2,
-  '*::ontouchenter': 2,
-  '*::ontouchleave': 2,
-  '*::ontouchmove': 2,
-  '*::ontouchstart': 2,
-  '*::onunload': 2,
-  '*::spellcheck': 0,
-  '*::style': 3,
-  '*::tabindex': 0,
-  '*::title': 0,
-  '*::translate': 0,
-  'a::accesskey': 0,
-  'a::coords': 0,
-  'a::href': 1,
-  'a::hreflang': 0,
-  'a::name': 7,
-  'a::onblur': 2,
-  'a::onfocus': 2,
-  'a::shape': 0,
-  'a::target': 10,
-  'a::type': 0,
-  'area::accesskey': 0,
-  'area::alt': 0,
-  'area::coords': 0,
-  'area::href': 1,
-  'area::nohref': 0,
-  'area::onblur': 2,
-  'area::onfocus': 2,
-  'area::shape': 0,
-  'area::target': 10,
-  'audio::controls': 0,
-  'audio::loop': 0,
-  'audio::mediagroup': 5,
-  'audio::muted': 0,
-  'audio::preload': 0,
-  'audio::src': 1,
-  'bdo::dir': 0,
-  'blockquote::cite': 1,
-  'br::clear': 0,
-  'button::accesskey': 0,
-  'button::disabled': 0,
-  'button::name': 8,
-  'button::onblur': 2,
-  'button::onfocus': 2,
-  'button::type': 0,
-  'button::value': 0,
-  'canvas::height': 0,
-  'canvas::width': 0,
-  'caption::align': 0,
-  'col::align': 0,
-  'col::char': 0,
-  'col::charoff': 0,
-  'col::span': 0,
-  'col::valign': 0,
-  'col::width': 0,
-  'colgroup::align': 0,
-  'colgroup::char': 0,
-  'colgroup::charoff': 0,
-  'colgroup::span': 0,
-  'colgroup::valign': 0,
-  'colgroup::width': 0,
-  'command::checked': 0,
-  'command::command': 5,
-  'command::disabled': 0,
-  'command::icon': 1,
-  'command::label': 0,
-  'command::radiogroup': 0,
-  'command::type': 0,
-  'data::value': 0,
-  'del::cite': 1,
-  'del::datetime': 0,
-  'details::open': 0,
-  'dir::compact': 0,
-  'div::align': 0,
-  'dl::compact': 0,
-  'fieldset::disabled': 0,
-  'font::color': 0,
-  'font::face': 0,
-  'font::size': 0,
-  'form::accept': 0,
-  'form::action': 1,
-  'form::autocomplete': 0,
-  'form::enctype': 0,
-  'form::method': 0,
-  'form::name': 7,
-  'form::novalidate': 0,
-  'form::onreset': 2,
-  'form::onsubmit': 2,
-  'form::target': 10,
-  'h1::align': 0,
-  'h2::align': 0,
-  'h3::align': 0,
-  'h4::align': 0,
-  'h5::align': 0,
-  'h6::align': 0,
-  'hr::align': 0,
-  'hr::noshade': 0,
-  'hr::size': 0,
-  'hr::width': 0,
-  'iframe::align': 0,
-  'iframe::frameborder': 0,
-  'iframe::height': 0,
-  'iframe::marginheight': 0,
-  'iframe::marginwidth': 0,
-  'iframe::width': 0,
-  'img::align': 0,
-  'img::alt': 0,
-  'img::border': 0,
-  'img::height': 0,
-  'img::hspace': 0,
-  'img::ismap': 0,
-  'img::name': 7,
-  'img::src': 1,
-  'img::usemap': 11,
-  'img::vspace': 0,
-  'img::width': 0,
-  'input::accept': 0,
-  'input::accesskey': 0,
-  'input::align': 0,
-  'input::alt': 0,
-  'input::autocomplete': 0,
-  'input::checked': 0,
-  'input::disabled': 0,
-  'input::inputmode': 0,
-  'input::ismap': 0,
-  'input::list': 5,
-  'input::max': 0,
-  'input::maxlength': 0,
-  'input::min': 0,
-  'input::multiple': 0,
-  'input::name': 8,
-  'input::onblur': 2,
-  'input::onchange': 2,
-  'input::onfocus': 2,
-  'input::onselect': 2,
-  'input::pattern': 0,
-  'input::placeholder': 0,
-  'input::readonly': 0,
-  'input::required': 0,
-  'input::size': 0,
-  'input::src': 1,
-  'input::step': 0,
-  'input::type': 0,
-  'input::usemap': 11,
-  'input::value': 0,
-  'ins::cite': 1,
-  'ins::datetime': 0,
-  'label::accesskey': 0,
-  'label::for': 5,
-  'label::onblur': 2,
-  'label::onfocus': 2,
-  'legend::accesskey': 0,
-  'legend::align': 0,
-  'li::type': 0,
-  'li::value': 0,
-  'map::name': 7,
-  'menu::compact': 0,
-  'menu::label': 0,
-  'menu::type': 0,
-  'meter::high': 0,
-  'meter::low': 0,
-  'meter::max': 0,
-  'meter::min': 0,
-  'meter::value': 0,
-  'ol::compact': 0,
-  'ol::reversed': 0,
-  'ol::start': 0,
-  'ol::type': 0,
-  'optgroup::disabled': 0,
-  'optgroup::label': 0,
-  'option::disabled': 0,
-  'option::label': 0,
-  'option::selected': 0,
-  'option::value': 0,
-  'output::for': 6,
-  'output::name': 8,
-  'p::align': 0,
-  'pre::width': 0,
-  'progress::max': 0,
-  'progress::min': 0,
-  'progress::value': 0,
-  'q::cite': 1,
-  'select::autocomplete': 0,
-  'select::disabled': 0,
-  'select::multiple': 0,
-  'select::name': 8,
-  'select::onblur': 2,
-  'select::onchange': 2,
-  'select::onfocus': 2,
-  'select::required': 0,
-  'select::size': 0,
-  'source::type': 0,
-  'table::align': 0,
-  'table::bgcolor': 0,
-  'table::border': 0,
-  'table::cellpadding': 0,
-  'table::cellspacing': 0,
-  'table::frame': 0,
-  'table::rules': 0,
-  'table::summary': 0,
-  'table::width': 0,
-  'tbody::align': 0,
-  'tbody::char': 0,
-  'tbody::charoff': 0,
-  'tbody::valign': 0,
-  'td::abbr': 0,
-  'td::align': 0,
-  'td::axis': 0,
-  'td::bgcolor': 0,
-  'td::char': 0,
-  'td::charoff': 0,
-  'td::colspan': 0,
-  'td::headers': 6,
-  'td::height': 0,
-  'td::nowrap': 0,
-  'td::rowspan': 0,
-  'td::scope': 0,
-  'td::valign': 0,
-  'td::width': 0,
-  'textarea::accesskey': 0,
-  'textarea::autocomplete': 0,
-  'textarea::cols': 0,
-  'textarea::disabled': 0,
-  'textarea::inputmode': 0,
-  'textarea::name': 8,
-  'textarea::onblur': 2,
-  'textarea::onchange': 2,
-  'textarea::onfocus': 2,
-  'textarea::onselect': 2,
-  'textarea::placeholder': 0,
-  'textarea::readonly': 0,
-  'textarea::required': 0,
-  'textarea::rows': 0,
-  'textarea::wrap': 0,
-  'tfoot::align': 0,
-  'tfoot::char': 0,
-  'tfoot::charoff': 0,
-  'tfoot::valign': 0,
-  'th::abbr': 0,
-  'th::align': 0,
-  'th::axis': 0,
-  'th::bgcolor': 0,
-  'th::char': 0,
-  'th::charoff': 0,
-  'th::colspan': 0,
-  'th::headers': 6,
-  'th::height': 0,
-  'th::nowrap': 0,
-  'th::rowspan': 0,
-  'th::scope': 0,
-  'th::valign': 0,
-  'th::width': 0,
-  'thead::align': 0,
-  'thead::char': 0,
-  'thead::charoff': 0,
-  'thead::valign': 0,
-  'tr::align': 0,
-  'tr::bgcolor': 0,
-  'tr::char': 0,
-  'tr::charoff': 0,
-  'tr::valign': 0,
-  'track::default': 0,
-  'track::kind': 0,
-  'track::label': 0,
-  'track::srclang': 0,
-  'ul::compact': 0,
-  'ul::type': 0,
-  'video::controls': 0,
-  'video::height': 0,
-  'video::loop': 0,
-  'video::mediagroup': 5,
-  'video::muted': 0,
-  'video::poster': 1,
-  'video::preload': 0,
-  'video::src': 1,
-  'video::width': 0
-};
-html4[ 'ATTRIBS' ] = html4.ATTRIBS;
-html4.eflags = {
-  'OPTIONAL_ENDTAG': 1,
-  'EMPTY': 2,
-  'CDATA': 4,
-  'RCDATA': 8,
-  'UNSAFE': 16,
-  'FOLDABLE': 32,
-  'SCRIPT': 64,
-  'STYLE': 128,
-  'VIRTUALIZED': 256
-};
-html4[ 'eflags' ] = html4.eflags;
-html4.ELEMENTS = {
-  'a': 0,
-  'abbr': 0,
-  'acronym': 0,
-  'address': 0,
-  'applet': 272,
-  'area': 2,
-  'article': 0,
-  'aside': 0,
-  'audio': 0,
-  'b': 0,
-  'base': 274,
-  'basefont': 274,
-  'bdi': 0,
-  'bdo': 0,
-  'big': 0,
-  'blockquote': 0,
-  'body': 305,
-  'br': 2,
-  'button': 0,
-  'canvas': 0,
-  'caption': 0,
-  'center': 0,
-  'cite': 0,
-  'code': 0,
-  'col': 2,
-  'colgroup': 1,
-  'command': 2,
-  'data': 0,
-  'datalist': 0,
-  'dd': 1,
-  'del': 0,
-  'details': 0,
-  'dfn': 0,
-  'dialog': 272,
-  'dir': 0,
-  'div': 0,
-  'dl': 0,
-  'dt': 1,
-  'em': 0,
-  'fieldset': 0,
-  'figcaption': 0,
-  'figure': 0,
-  'font': 0,
-  'footer': 0,
-  'form': 0,
-  'frame': 274,
-  'frameset': 272,
-  'h1': 0,
-  'h2': 0,
-  'h3': 0,
-  'h4': 0,
-  'h5': 0,
-  'h6': 0,
-  'head': 305,
-  'header': 0,
-  'hgroup': 0,
-  'hr': 2,
-  'html': 305,
-  'i': 0,
-  'iframe': 4,
-  'img': 2,
-  'input': 2,
-  'ins': 0,
-  'isindex': 274,
-  'kbd': 0,
-  'keygen': 274,
-  'label': 0,
-  'legend': 0,
-  'li': 1,
-  'link': 274,
-  'map': 0,
-  'mark': 0,
-  'menu': 0,
-  'meta': 274,
-  'meter': 0,
-  'nav': 0,
-  'nobr': 0,
-  'noembed': 276,
-  'noframes': 276,
-  'noscript': 276,
-  'object': 272,
-  'ol': 0,
-  'optgroup': 0,
-  'option': 1,
-  'output': 0,
-  'p': 1,
-  'param': 274,
-  'pre': 0,
-  'progress': 0,
-  'q': 0,
-  's': 0,
-  'samp': 0,
-  'script': 84,
-  'section': 0,
-  'select': 0,
-  'small': 0,
-  'source': 2,
-  'span': 0,
-  'strike': 0,
-  'strong': 0,
-  'style': 148,
-  'sub': 0,
-  'summary': 0,
-  'sup': 0,
-  'table': 0,
-  'tbody': 1,
-  'td': 1,
-  'textarea': 8,
-  'tfoot': 1,
-  'th': 1,
-  'thead': 1,
-  'time': 0,
-  'title': 280,
-  'tr': 1,
-  'track': 2,
-  'tt': 0,
-  'u': 0,
-  'ul': 0,
-  'var': 0,
-  'video': 0,
-  'wbr': 2
-};
-html4[ 'ELEMENTS' ] = html4.ELEMENTS;
-html4.ELEMENT_DOM_INTERFACES = {
-  'a': 'HTMLAnchorElement',
-  'abbr': 'HTMLElement',
-  'acronym': 'HTMLElement',
-  'address': 'HTMLElement',
-  'applet': 'HTMLAppletElement',
-  'area': 'HTMLAreaElement',
-  'article': 'HTMLElement',
-  'aside': 'HTMLElement',
-  'audio': 'HTMLAudioElement',
-  'b': 'HTMLElement',
-  'base': 'HTMLBaseElement',
-  'basefont': 'HTMLBaseFontElement',
-  'bdi': 'HTMLElement',
-  'bdo': 'HTMLElement',
-  'big': 'HTMLElement',
-  'blockquote': 'HTMLQuoteElement',
-  'body': 'HTMLBodyElement',
-  'br': 'HTMLBRElement',
-  'button': 'HTMLButtonElement',
-  'canvas': 'HTMLCanvasElement',
-  'caption': 'HTMLTableCaptionElement',
-  'center': 'HTMLElement',
-  'cite': 'HTMLElement',
-  'code': 'HTMLElement',
-  'col': 'HTMLTableColElement',
-  'colgroup': 'HTMLTableColElement',
-  'command': 'HTMLCommandElement',
-  'data': 'HTMLElement',
-  'datalist': 'HTMLDataListElement',
-  'dd': 'HTMLElement',
-  'del': 'HTMLModElement',
-  'details': 'HTMLDetailsElement',
-  'dfn': 'HTMLElement',
-  'dialog': 'HTMLDialogElement',
-  'dir': 'HTMLDirectoryElement',
-  'div': 'HTMLDivElement',
-  'dl': 'HTMLDListElement',
-  'dt': 'HTMLElement',
-  'em': 'HTMLElement',
-  'fieldset': 'HTMLFieldSetElement',
-  'figcaption': 'HTMLElement',
-  'figure': 'HTMLElement',
-  'font': 'HTMLFontElement',
-  'footer': 'HTMLElement',
-  'form': 'HTMLFormElement',
-  'frame': 'HTMLFrameElement',
-  'frameset': 'HTMLFrameSetElement',
-  'h1': 'HTMLHeadingElement',
-  'h2': 'HTMLHeadingElement',
-  'h3': 'HTMLHeadingElement',
-  'h4': 'HTMLHeadingElement',
-  'h5': 'HTMLHeadingElement',
-  'h6': 'HTMLHeadingElement',
-  'head': 'HTMLHeadElement',
-  'header': 'HTMLElement',
-  'hgroup': 'HTMLElement',
-  'hr': 'HTMLHRElement',
-  'html': 'HTMLHtmlElement',
-  'i': 'HTMLElement',
-  'iframe': 'HTMLIFrameElement',
-  'img': 'HTMLImageElement',
-  'input': 'HTMLInputElement',
-  'ins': 'HTMLModElement',
-  'isindex': 'HTMLUnknownElement',
-  'kbd': 'HTMLElement',
-  'keygen': 'HTMLKeygenElement',
-  'label': 'HTMLLabelElement',
-  'legend': 'HTMLLegendElement',
-  'li': 'HTMLLIElement',
-  'link': 'HTMLLinkElement',
-  'map': 'HTMLMapElement',
-  'mark': 'HTMLElement',
-  'menu': 'HTMLMenuElement',
-  'meta': 'HTMLMetaElement',
-  'meter': 'HTMLMeterElement',
-  'nav': 'HTMLElement',
-  'nobr': 'HTMLElement',
-  'noembed': 'HTMLElement',
-  'noframes': 'HTMLElement',
-  'noscript': 'HTMLElement',
-  'object': 'HTMLObjectElement',
-  'ol': 'HTMLOListElement',
-  'optgroup': 'HTMLOptGroupElement',
-  'option': 'HTMLOptionElement',
-  'output': 'HTMLOutputElement',
-  'p': 'HTMLParagraphElement',
-  'param': 'HTMLParamElement',
-  'pre': 'HTMLPreElement',
-  'progress': 'HTMLProgressElement',
-  'q': 'HTMLQuoteElement',
-  's': 'HTMLElement',
-  'samp': 'HTMLElement',
-  'script': 'HTMLScriptElement',
-  'section': 'HTMLElement',
-  'select': 'HTMLSelectElement',
-  'small': 'HTMLElement',
-  'source': 'HTMLSourceElement',
-  'span': 'HTMLSpanElement',
-  'strike': 'HTMLElement',
-  'strong': 'HTMLElement',
-  'style': 'HTMLStyleElement',
-  'sub': 'HTMLElement',
-  'summary': 'HTMLElement',
-  'sup': 'HTMLElement',
-  'table': 'HTMLTableElement',
-  'tbody': 'HTMLTableSectionElement',
-  'td': 'HTMLTableDataCellElement',
-  'textarea': 'HTMLTextAreaElement',
-  'tfoot': 'HTMLTableSectionElement',
-  'th': 'HTMLTableHeaderCellElement',
-  'thead': 'HTMLTableSectionElement',
-  'time': 'HTMLTimeElement',
-  'title': 'HTMLTitleElement',
-  'tr': 'HTMLTableRowElement',
-  'track': 'HTMLTrackElement',
-  'tt': 'HTMLElement',
-  'u': 'HTMLElement',
-  'ul': 'HTMLUListElement',
-  'var': 'HTMLElement',
-  'video': 'HTMLVideoElement',
-  'wbr': 'HTMLElement'
-};
-html4[ 'ELEMENT_DOM_INTERFACES' ] = html4.ELEMENT_DOM_INTERFACES;
-html4.ueffects = {
-  'NOT_LOADED': 0,
-  'SAME_DOCUMENT': 1,
-  'NEW_DOCUMENT': 2
-};
-html4[ 'ueffects' ] = html4.ueffects;
-html4.URIEFFECTS = {
-  'a::href': 2,
-  'area::href': 2,
-  'audio::src': 1,
-  'blockquote::cite': 0,
-  'command::icon': 1,
-  'del::cite': 0,
-  'form::action': 2,
-  'img::src': 1,
-  'input::src': 1,
-  'ins::cite': 0,
-  'q::cite': 0,
-  'video::poster': 1,
-  'video::src': 1
-};
-html4[ 'URIEFFECTS' ] = html4.URIEFFECTS;
-html4.ltypes = {
-  'UNSANDBOXED': 2,
-  'SANDBOXED': 1,
-  'DATA': 0
-};
-html4[ 'ltypes' ] = html4.ltypes;
-html4.LOADERTYPES = {
-  'a::href': 2,
-  'area::href': 2,
-  'audio::src': 2,
-  'blockquote::cite': 2,
-  'command::icon': 1,
-  'del::cite': 2,
-  'form::action': 2,
-  'img::src': 1,
-  'input::src': 1,
-  'ins::cite': 2,
-  'q::cite': 2,
-  'video::poster': 1,
-  'video::src': 2
-};
-html4[ 'LOADERTYPES' ] = html4.LOADERTYPES;
-
-return html4
-});
diff --git a/web-ui/app/js/mail_list/domain/refresher.js b/web-ui/app/js/mail_list/domain/refresher.js
deleted file mode 100644
index 38c9cde5..00000000
--- a/web-ui/app/js/mail_list/domain/refresher.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(['flight/lib/component', 'page/events', 'features'], function(defineComponent, events, features) {
-    'use strict';
-
-    return defineComponent(refresher);
-
-    function refresher() {
-      this.defaultAttrs({
-        interval: 20000
-      });
-
-      this.setupRefresher = function() {
-        setTimeout(this.doRefresh.bind(this), this.attr.interval);
-      };
-
-      this.doRefresh = function() {
-        this.trigger(document, events.ui.mails.refresh);
-        this.setupRefresher();
-      };
-
-      this.after('initialize', function () {
-        if (features.isAutoRefreshEnabled()) {
-          this.setupRefresher();
-        }
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_list/ui/mail_item_factory.js b/web-ui/app/js/mail_list/ui/mail_item_factory.js
deleted file mode 100644
index 7205d35c..00000000
--- a/web-ui/app/js/mail_list/ui/mail_item_factory.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-  [
-    'mail_list/ui/mail_items/generic_mail_item',
-    'mail_list/ui/mail_items/draft_item',
-    'mail_list/ui/mail_items/sent_item'
-  ],
-  function (GenericMailItem, DraftItem, SentItem) {
-    'use strict';
-
-    var MAIL_ITEM_TYPE = {
-      'drafts': DraftItem,
-      'sent': SentItem,
-      'trash': GenericMailItem
-    };
-
-    var TEMPLATE_TYPE = {
-      'drafts': 'draft',
-      'sent': 'sent',
-      'trash': 'trash'
-    };
-
-    var createAndAttach = function (nodeToAttachTo, mail, currentMailIdent, currentTag, isChecked) {
-      var mailItemContainer = $('<li>', { id: 'mail-' + mail.ident});
-      nodeToAttachTo.append(mailItemContainer);
-
-      mail.currentTag = currentTag;
-      var mailToCreate = MAIL_ITEM_TYPE[mail.mailbox] || GenericMailItem;
-      mailToCreate.attachTo(mailItemContainer, {
-        mail: mail,
-        selected: mail.ident === currentMailIdent,
-        tag: currentTag,
-        isChecked: isChecked,
-        templateType: TEMPLATE_TYPE[mail.mailbox] || 'single'
-      });
-
-    };
-
-    return {
-      createAndAttach: createAndAttach
-    };
-  }
-);
diff --git a/web-ui/app/js/mail_list/ui/mail_items/draft_item.js b/web-ui/app/js/mail_list/ui/mail_items/draft_item.js
deleted file mode 100644
index 57fbafd5..00000000
--- a/web-ui/app/js/mail_list/ui/mail_items/draft_item.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-  [
-    'flight/lib/component',
-    'helpers/view_helper',
-    'mail_list/ui/mail_items/mail_item',
-    'page/events'
-  ],
-
-  function (defineComponent, viewHelpers, mailItem, events) {
-    'use strict';
-
-    return defineComponent(draftItem, mailItem);
-
-    function draftItem() {
-      this.triggerOpenMail = function (ev) {
-        if (this.isOpeningOnANewTab(ev)) {
-          return;
-        }
-        this.trigger(document, events.dispatchers.rightPane.openDraft, { ident: this.attr.mail.ident });
-        this.trigger(document, events.ui.mail.updateSelected, { ident: this.attr.mail.ident });
-        this.trigger(document, events.router.pushState, { mailIdent: this.attr.mail.ident });
-        ev.preventDefault(); // don't let the hashchange trigger a popstate
-      };
-
-      this.after('initialize', function () {
-        this.render();
-
-        if (this.attr.isChecked) {
-          this.checkCheckbox();
-        }
-
-        this.on(document, events.ui.composeBox.newMessage, this.doUnselect);
-        this.on(document, events.ui.mail.updateSelected, this.updateSelected);
-        this.on(document, events.mails.teardown, this.teardown);
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_list/ui/mail_items/generic_mail_item.js b/web-ui/app/js/mail_list/ui/mail_items/generic_mail_item.js
deleted file mode 100644
index 939f7e1b..00000000
--- a/web-ui/app/js/mail_list/ui/mail_items/generic_mail_item.js
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-  [
-    'flight/lib/component',
-    'helpers/view_helper',
-    'mail_list/ui/mail_items/mail_item',
-    'page/events'
-  ],
-
-  function (defineComponent, viewHelpers, mailItem, events) {
-    'use strict';
-
-    return defineComponent(genericMailItem, mailItem);
-
-    function genericMailItem() {
-      this.status = {
-        READ: 'read'
-      };
-
-      this.triggerOpenMail = function (ev) {
-        if (this.isOpeningOnANewTab(ev)) {
-          updateMailStatusToRead.call(this);
-          return;
-        }
-        this.trigger(document, events.ui.mail.open, { ident: this.attr.mail.ident });
-        this.trigger(document, events.router.pushState, { mailIdent: this.attr.mail.ident });
-        ev.preventDefault(); // don't let the hashchange trigger a popstate
-      };
-
-      function updateMailStatusToRead() {
-        if (!_.contains(this.attr.mail.status, this.status.READ)) {
-          var mail_read_data = { ident: this.attr.mail.ident, tags: this.attr.mail.tags, mailbox: this.attr.mail.mailbox };
-          this.trigger(document, events.mail.read, mail_read_data);
-          this.attr.mail.status.push(this.status.READ);
-          this.$node.addClass(viewHelpers.formatStatusClasses(this.attr.mail.status));
-        }
-      }
-
-      this.openMail = function (ev, data) {
-        if (data.ident !== this.attr.mail.ident) {
-          return;
-        }
-        updateMailStatusToRead.call(this);
-
-        this.trigger(document, events.ui.mail.updateSelected, { ident: this.attr.mail.ident });
-      };
-
-      this.updateTags = function(ev, data) {
-        if(data.ident === this.attr.mail.ident){
-          this.attr.tags = data.tags;
-          if(!_.contains(this.attr.tags, this.attr.tag)) {
-            this.teardown();
-          } else {
-            this.render();
-          }
-        }
-      };
-
-      this.deleteMail = function(ev, data) {
-        if(data.mail.ident === this.attr.mail.ident){
-          this.teardown();
-        }
-      };
-
-      this.after('initialize', function () {
-        this.render();
-
-        if (this.attr.isChecked) {
-          this.checkCheckbox();
-        }
-
-        this.on(document, events.ui.composeBox.newMessage, this.doUnselect);
-        this.on(document, events.ui.mail.open, this.openMail);
-        this.on(document, events.ui.mail.updateSelected, this.updateSelected);
-        this.on(document, events.mails.teardown, this.teardown);
-        this.on(document, events.mail.tags.update, this.updateTags);
-        this.on(document, events.mail.delete, this.deleteMail);
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_list/ui/mail_items/mail_item.js b/web-ui/app/js/mail_list/ui/mail_items/mail_item.js
deleted file mode 100644
index be664289..00000000
--- a/web-ui/app/js/mail_list/ui/mail_items/mail_item.js
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-  [
-    'helpers/view_helper',
-    'views/templates',
-    'page/events'
-  ],
-  function (viewHelper, templates, events) {
-
-  'use strict';
-  function mailItem() {
-    this.updateSelected = function (ev, data) {
-      if (data.ident === this.attr.mail.ident) { this.doSelect(); }
-      else { this.doUnselect(); }
-    };
-
-    this.isOpeningOnANewTab = function (ev) {
-      return ev.metaKey || ev.ctrlKey || ev.which === 2;
-    };
-
-    this.doSelect = function () {
-      this.$node.addClass('selected');
-    };
-
-    this.doUnselect = function () {
-      this.$node.removeClass('selected');
-    };
-
-    this.doMailChecked = function (ev) {
-      if (ev.target.checked) {
-        this.checkCheckbox();
-      } else {
-        this.uncheckCheckbox();
-      }
-    };
-
-    this.checkboxElement = function () {
-      return this.$node.find('input[type=checkbox]');
-    };
-
-    this.checkCheckbox = function () {
-      this.checkboxElement().prop('checked', true);
-      this.trigger(document, events.ui.mail.checked, { mail: this.attr.mail});
-    };
-
-    this.uncheckCheckbox = function () {
-      this.checkboxElement().prop('checked', false);
-      this.trigger(document, events.ui.mail.unchecked, { mail: this.attr.mail});
-    };
-
-    this.render = function () {
-      this.attr.mail.tagsForListView = _.without(this.attr.mail.tags, this.attr.tag);
-      var mailItemHtml = templates.mails[this.attr.templateType](this.attr.mail);
-      this.$node.html(mailItemHtml);
-      this.$node.addClass("mail-list-entry");
-      this.$node.addClass(viewHelper.formatStatusClasses(this.attr.mail.status));
-      if (this.attr.selected) { this.doSelect(); }
-      this.on(this.$node.find('a'), 'click', this.triggerOpenMail);
-    };
-
-    this.after('initialize', function () {
-      this.on(this.$node.find('input[type=checkbox]'), 'change', this.doMailChecked);
-      this.on(document, events.ui.mails.cleanSelected, this.doUnselect);
-      this.on(document, events.ui.tag.select, this.doUnselect);
-      this.on(document, events.ui.tag.select, this.uncheckCheckbox);
-      this.on(document, events.ui.mails.uncheckAll, this.uncheckCheckbox);
-      this.on(document, events.ui.mails.checkAll, this.checkCheckbox);
-    });
-  }
-
-  return mailItem;
-});
diff --git a/web-ui/app/js/mail_list/ui/mail_items/sent_item.js b/web-ui/app/js/mail_list/ui/mail_items/sent_item.js
deleted file mode 100644
index 9e511068..00000000
--- a/web-ui/app/js/mail_list/ui/mail_items/sent_item.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-  [
-    'flight/lib/component',
-    'mail_list/ui/mail_items/mail_item',
-    'page/events'
-  ],
-
-  function (defineComponent, mailItem, events) {
-    'use strict';
-
-    return defineComponent(sentItem, mailItem);
-
-    function sentItem() {
-      this.triggerOpenMail = function (ev) {
-        if (this.isOpeningOnANewTab(ev)) {
-          return;
-        }
-        this.trigger(document, events.ui.mail.open, { ident: this.attr.mail.ident });
-        this.trigger(document, events.router.pushState, { mailIdent: this.attr.mail.ident });
-        ev.preventDefault(); // don't let the hashchange trigger a popstate
-      };
-
-      this.openMail = function (ev, data) {
-        if (data.ident !== this.attr.mail.ident) {
-          return;
-        }
-        this.trigger(document, events.ui.mail.updateSelected, { ident: this.attr.mail.ident });
-      };
-
-      this.after('initialize', function () {
-        this.render();
-
-        if (this.attr.isChecked) {
-          this.checkCheckbox();
-        }
-
-        this.on(document, events.ui.composeBox.newMessage, this.doUnselect);
-        this.on(document, events.ui.mail.open, this.openMail);
-        this.on(document, events.ui.mail.updateSelected, this.updateSelected);
-        this.on(document, events.mails.teardown, this.teardown);
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_list/ui/mail_list.js b/web-ui/app/js/mail_list/ui/mail_list.js
deleted file mode 100644
index af4821a8..00000000
--- a/web-ui/app/js/mail_list/ui/mail_list.js
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-  [
-    'flight/lib/component',
-    'flight/lib/utils',
-    'mail_list/ui/mail_item_factory',
-    'page/router/url_params',
-    'page/events'
-  ],
-
-  function (defineComponent, utils, MailItemFactory, urlParams, events) {
-    'use strict';
-
-    return defineComponent(mailList);
-
-    function mailList () {
-      var openMailEventFor = function (tag) {
-        return tag === 'drafts' ? events.dispatchers.rightPane.openDraft : events.ui.mail.open;
-      };
-
-      this.defaultAttrs({
-        mail: '.mail',
-        currentMailIdent: '',
-        urlParams: urlParams,
-        initialized: false,
-        checkedMails: {}
-      });
-
-      this.appendMail = function (mail) {
-        var isChecked = mail.ident in this.attr.checkedMails;
-        MailItemFactory.createAndAttach(this.$node, mail, this.attr.currentMailIdent, this.attr.currentTag, isChecked);
-      };
-
-      this.resetMailList = function () {
-        this.trigger(document, events.mails.teardown);
-        this.$node.empty();
-      };
-
-      this.triggerMailOpenForPopState = function (data) {
-        if (data.mailIdent) {
-          this.trigger(document, openMailEventFor(data.tag), { ident: data.mailIdent });
-        }
-      };
-
-      this.shouldSelectEmailFromUrlMailIdent = function () {
-        return this.attr.urlParams.hasMailIdent();
-      };
-
-      this.selectMailBasedOnUrlMailIdent = function () {
-        var mailIdent = this.attr.urlParams.getMailIdent();
-        this.trigger(document, openMailEventFor(this.attr.currentTag), { ident: mailIdent });
-        this.trigger(document, events.router.pushState, { tag: this.attr.currentTag, mailIdent: mailIdent });
-      };
-
-      this.updateCurrentTagAndMail = function (data) {
-        if (data.ident) {
-          this.attr.currentMailIdent = data.ident;
-        }
-
-        this.attr.currentTag = data.tag || this.attr.currentTag;
-
-        this.updateCheckAllCheckbox();
-      };
-
-      this.renderMails = function (mails) {
-        _.each(mails, this.appendMail, this);
-        this.trigger(document, events.search.highlightResults, {where: '#mail-list'});
-        this.trigger(document, events.search.highlightResults, {where: '.mail-read-view__header'});
-      };
-
-      this.triggerScrollReset = function () {
-        this.trigger(document, events.dispatchers.middlePane.resetScroll);
-      };
-
-      this.showMails = function (event, data) {
-        this.updateCurrentTagAndMail(data);
-        this.refreshMailList(null, data);
-        this.triggerMailOpenForPopState(data);
-        this.openMailFromUrl();
-      };
-
-      this.refreshMailList = function (ev, data) {
-        if (ev) { // triggered by the event, so we need to refresh the tag list
-          this.trigger(document, events.dispatchers.tags.refreshTagList, { skipMailListRefresh: true });
-        }
-        this.resetMailList();
-        this.renderMails(data.mails);
-      };
-
-      this.updateSelected = function (ev, data) {
-        if (data.ident !== this.attr.currentMailIdent) {
-          this.attr.currentMailIdent = data.ident;
-        }
-      };
-
-      this.cleanSelected = function () {
-        this.attr.currentMailIdent = '';
-        this.triggerScrollReset();
-      };
-
-      this.respondWithCheckedMails = function (ev, caller) {
-        this.trigger(caller, events.ui.mail.hereChecked, {checkedMails: this.attr.checkedMails});
-      };
-
-      this.updateCheckAllCheckbox = function () {
-        this.trigger(document, events.ui.mails.hasMailsChecked, _.keys(this.attr.checkedMails).length > 0);
-      };
-
-      this.addToCheckedMails = function (ev, data) {
-        this.attr.checkedMails[data.mail.ident] = data.mail;
-        this.updateCheckAllCheckbox();
-      };
-
-      this.removeFromCheckedMails = function (ev, data) {
-        if (data.mails) {
-          _.each(data.mails, function (mail) {
-            delete this.attr.checkedMails[mail.ident];
-          }, this);
-        } else {
-          delete this.attr.checkedMails[data.mail.ident];
-        }
-        this.updateCheckAllCheckbox();
-      };
-
-      this.refreshWithScroll = function () {
-        this.trigger(document, events.ui.mails.refresh);
-        this.triggerScrollReset();
-      };
-
-      this.refreshAfterSaveDraft = function () {
-        if (this.attr.currentTag === 'drafts') {
-          this.refreshWithScroll();
-        }
-      };
-
-      this.refreshAfterMailSent = function () {
-        if (this.attr.currentTag === 'drafts' || this.attr.currentTag === 'sent') {
-          this.refreshWithScroll();
-        }
-      };
-
-      this.after('initialize', function () {
-        this.on(document, events.ui.mails.cleanSelected, this.cleanSelected);
-        this.on(document, events.ui.tag.select, this.cleanSelected);
-
-        this.on(document, events.mails.available, this.showMails);
-        this.on(document, events.mails.availableForRefresh, this.refreshMailList);
-
-        this.on(document, events.mail.draftSaved, this.refreshAfterSaveDraft);
-        this.on(document, events.mail.sent, this.refreshAfterMailSent);
-
-        this.on(document, events.ui.mail.updateSelected, this.updateSelected);
-        this.on(document, events.ui.mail.wantChecked, this.respondWithCheckedMails);
-        this.on(document, events.ui.mail.checked, this.addToCheckedMails);
-        this.on(document, events.ui.mail.unchecked, this.removeFromCheckedMails);
-
-        this.openMailFromUrl = utils.once(function () {
-          if (this.shouldSelectEmailFromUrlMailIdent()) {
-            this.selectMailBasedOnUrlMailIdent();
-          }
-        });
-
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_list_actions/ui/archive_many_trigger.js b/web-ui/app/js/mail_list_actions/ui/archive_many_trigger.js
deleted file mode 100644
index b148cdce..00000000
--- a/web-ui/app/js/mail_list_actions/ui/archive_many_trigger.js
+++ /dev/null
@@ -1,29 +0,0 @@
-define(
-  [
-    'flight/lib/component',
-    'views/templates',
-    'mixins/with_enable_disable_on_event',
-    'page/events'
-  ],
-
-  function(definecomponent, templates, withEnableDisableOnEvent, events) {
-    'use strict';
-
-    return definecomponent(archiveManyTrigger, withEnableDisableOnEvent(events.ui.mails.hasMailsChecked));
-    function archiveManyTrigger() {
-
-      this.getMailsToArchive = function() {
-        this.trigger(document, events.ui.mail.wantChecked, this.$node);
-      };
-
-      this.archiveManyEmails = function(event, data) {
-        this.trigger(document, events.mail.archiveMany, data);
-      };
-
-      this.after('initialize', function () {
-        this.on('click', this.getMailsToArchive);
-        this.on(events.ui.mail.hereChecked, this.archiveManyEmails);
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_list_actions/ui/compose_trigger.js b/web-ui/app/js/mail_list_actions/ui/compose_trigger.js
deleted file mode 100644
index ec79cb26..00000000
--- a/web-ui/app/js/mail_list_actions/ui/compose_trigger.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'views/templates',
-    'page/events'
-  ],
-
-  function(defineComponent, templates, events) {
-    'use strict';
-
-    return defineComponent(composeTrigger);
-
-    function composeTrigger() {
-
-      this.defaultAttrs({});
-
-      this.render = function() {
-        this.$node.html(templates.mailActions.composeTrigger);
-      };
-
-      this.enableComposing = function(event, data) {
-        this.trigger(document, events.dispatchers.rightPane.openComposeBox);
-      };
-
-      this.showEmailSuccess = function () {
-        this.trigger(document, events.ui.userAlerts.displayMessage, {message: 'Your message was sent!', class: 'success'});
-      };
-
-      this.showEmailError = function (ev, data) {
-        this.trigger(document, events.ui.userAlerts.displayMessage, {message: 'Error,  message not sent: ' + data.responseJSON.message, class: 'error'});
-      };
-
-      this.after('initialize', function () {
-        this.render();
-        this.on('click', this.enableComposing);
-        this.on(document, events.mail.sent, this.showEmailSuccess);
-        this.on(document, events.mail.send_failed, this.showEmailError);
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_list_actions/ui/delete_many_trigger.js b/web-ui/app/js/mail_list_actions/ui/delete_many_trigger.js
deleted file mode 100644
index dd2f67a5..00000000
--- a/web-ui/app/js/mail_list_actions/ui/delete_many_trigger.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'views/templates',
-    'mixins/with_enable_disable_on_event',
-    'page/events'
-  ],
-
-  function(defineComponent, templates, withEnableDisableOnEvent, events) {
-    'use strict';
-
-    return defineComponent(deleteManyTrigger, withEnableDisableOnEvent(events.ui.mails.hasMailsChecked));
-
-    function deleteManyTrigger() {
-      this.defaultAttrs({});
-
-      this.getMailsToDelete = function(event) {
-        this.trigger(document, events.ui.mail.wantChecked, this.$node);
-      };
-
-      this.deleteManyEmails = function (event, data) {
-        this.trigger(document, events.ui.mail.deleteMany, data);
-      };
-
-      this.after('initialize', function () {
-        this.on('click', this.getMailsToDelete);
-        this.on(events.ui.mail.hereChecked, this.deleteManyEmails);
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_list_actions/ui/mail_list_actions.js b/web-ui/app/js/mail_list_actions/ui/mail_list_actions.js
deleted file mode 100644
index 69e5fde4..00000000
--- a/web-ui/app/js/mail_list_actions/ui/mail_list_actions.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-  [
-    'flight/lib/component',
-    'views/templates',
-    'page/events',
-    'page/router/url_params',
-    'mail_list_actions/ui/compose_trigger',
-    'mail_list_actions/ui/refresh_trigger',
-    'mail_list/domain/refresher',
-    'mail_list_actions/ui/toggle_check_all_trigger',
-    'mail_list_actions/ui/pagination_trigger',
-    'mail_list_actions/ui/delete_many_trigger',
-    'mail_list_actions/ui/recover_many_trigger',
-    'mail_list_actions/ui/archive_many_trigger',
-    'mail_list_actions/ui/mark_many_as_read_trigger',
-    'mail_list_actions/ui/mark_as_unread_trigger'
-  ],
-
-  function (
-    defineComponent,
-    templates,
-    events,
-    urlParams,
-    composeTrigger,
-    refreshTrigger,
-    refresher,
-    toggleCheckAllMailTrigger,
-    paginationTrigger,
-    deleteManyTrigger,
-    recoverManyTrigger,
-    archiveManyTrigger,
-    markManyAsReadTrigger,
-    markAsUnreadTrigger
-  ) {
-    'use strict';
-    return defineComponent(mailsActions);
-
-    function mailsActions() {
-      this.render = function() {
-        this.$node.html(this.getActionsBoxTemplate());
-        refreshTrigger.attachTo('#refresh-trigger');
-        composeTrigger.attachTo('#compose-trigger');
-        toggleCheckAllMailTrigger.attachTo('#toggle-check-all-emails');
-        paginationTrigger.attachTo('#pagination-trigger');
-        deleteManyTrigger.attachTo('#delete-selected');
-        recoverManyTrigger.attachTo('#recover-selected');
-        archiveManyTrigger.attachTo('#archive-selected');
-        markManyAsReadTrigger.attachTo('#mark-selected-as-read');
-        markAsUnreadTrigger.attachTo('#mark-selected-as-unread');
-        refresher.attachTo(document);
-      };
-
-      this.getCurrentTag = function () {
-        return this.attr.currentTag || urlParams.getTag();
-      };
-
-      this.updateCurrentTag = function (ev, data) {
-        this.attr.currentTag = data.tag;
-        this.render();
-      };
-
-      this.getActionsBoxTemplate = function () {
-        if(this.getCurrentTag() === 'trash') {
-          return templates.mailActions.trashActionsBox();
-        } else {
-          return templates.mailActions.actionsBox();
-        }
-      };
-
-      this.after('initialize', function () {
-        this.on(document, events.ui.tag.select, this.updateCurrentTag);
-        this.render();
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_list_actions/ui/mark_as_unread_trigger.js b/web-ui/app/js/mail_list_actions/ui/mark_as_unread_trigger.js
deleted file mode 100644
index 2584e453..00000000
--- a/web-ui/app/js/mail_list_actions/ui/mark_as_unread_trigger.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'views/templates',
-    'mixins/with_enable_disable_on_event',
-    'page/events'
-  ],
-
-  function(defineComponent, templates, withEnableDisableOnEvent, events) {
-    'use strict';
-
-    return defineComponent(markAsUnreadTrigger, withEnableDisableOnEvent(events.ui.mails.hasMailsChecked));
-
-    function markAsUnreadTrigger() {
-      this.defaultAttrs({});
-
-      this.getMailsToMarkAsUnread = function(event) {
-        this.trigger(document, events.ui.mail.wantChecked, this.$node);
-      };
-
-      this.markManyEmailsAsUnread = function (event, data) {
-        this.trigger(document, events.mail.unread, data);
-      };
-
-      this.after('initialize', function () {
-        this.on('click', this.getMailsToMarkAsUnread);
-        this.on(events.ui.mail.hereChecked, this.markManyEmailsAsUnread);
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_list_actions/ui/mark_many_as_read_trigger.js b/web-ui/app/js/mail_list_actions/ui/mark_many_as_read_trigger.js
deleted file mode 100644
index c16a2229..00000000
--- a/web-ui/app/js/mail_list_actions/ui/mark_many_as_read_trigger.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'views/templates',
-    'mixins/with_enable_disable_on_event',
-    'page/events'
-  ],
-
-  function(defineComponent, templates, withEnableDisableOnEvent, events) {
-    'use strict';
-
-    return defineComponent(markManyAsReadTrigger, withEnableDisableOnEvent(events.ui.mails.hasMailsChecked));
-
-    function markManyAsReadTrigger() {
-      this.defaultAttrs({});
-
-      this.getMailsToMarkAsRead = function(event) {
-        this.trigger(document, events.ui.mail.wantChecked, this.$node);
-      };
-
-      this.markManyEmailsAsRead = function (event, data) {
-        this.trigger(document, events.mail.read, data);
-      };
-
-      this.after('initialize', function () {
-        this.on('click', this.getMailsToMarkAsRead);
-        this.on(events.ui.mail.hereChecked, this.markManyEmailsAsRead);
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_list_actions/ui/pagination_trigger.js b/web-ui/app/js/mail_list_actions/ui/pagination_trigger.js
deleted file mode 100644
index 3bc13d40..00000000
--- a/web-ui/app/js/mail_list_actions/ui/pagination_trigger.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'views/templates',
-    'page/events'
-  ],
-
-  function(defineComponent, templates, events) {
-    'use strict';
-
-    return defineComponent(paginationTrigger);
-
-    function paginationTrigger() {
-      this.defaultAttrs({
-        previous: '#left-arrow',
-        next: '#right-arrow',
-        currentPage: '#current-page'
-      });
-
-      this.renderWithPageNumber = function(pageNumber) {
-        this.$node.html(templates.mailActions.paginationTrigger({
-          currentPage: pageNumber
-        }));
-        this.on(this.attr.previous, 'click', this.previousPage);
-        this.on(this.attr.next, 'click', this.nextPage);
-      };
-
-      this.render = function() {
-        this.renderWithPageNumber(1);
-      };
-
-      this.updatePageDisplay = function(event, data) {
-        this.renderWithPageNumber(data.currentPage);
-      };
-
-      this.previousPage = function(event) {
-        this.trigger(document, events.ui.page.previous);
-      };
-
-      this.nextPage = function(event) {
-        this.trigger(document, events.ui.page.next);
-      };
-
-      this.after('initialize', function () {
-        this.render();
-        this.on(document, events.ui.page.changed, this.updatePageDisplay);
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_list_actions/ui/recover_many_trigger.js b/web-ui/app/js/mail_list_actions/ui/recover_many_trigger.js
deleted file mode 100644
index e0a32094..00000000
--- a/web-ui/app/js/mail_list_actions/ui/recover_many_trigger.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'views/templates',
-    'mixins/with_enable_disable_on_event',
-    'page/events'
-  ],
-
-  function(defineComponent, templates, withEnableDisableOnEvent, events) {
-    'use strict';
-
-    return defineComponent(recoverManyTrigger, withEnableDisableOnEvent(events.ui.mails.hasMailsChecked));
-
-    function recoverManyTrigger() {
-      this.defaultAttrs({});
-
-      this.getMailsToRecover = function(event) {
-        this.trigger(document, events.ui.mail.wantChecked, this.$node);
-      };
-
-      this.recoverManyEmails = function (event, data) {
-        this.trigger(document, events.ui.mail.recoverMany, data);
-      };
-
-      this.after('initialize', function () {
-        this.on('click', this.getMailsToRecover);
-        this.on(events.ui.mail.hereChecked, this.recoverManyEmails);
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_list_actions/ui/refresh_trigger.js b/web-ui/app/js/mail_list_actions/ui/refresh_trigger.js
deleted file mode 100644
index a16270d2..00000000
--- a/web-ui/app/js/mail_list_actions/ui/refresh_trigger.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'views/templates',
-    'page/events'
-  ],
-
-  function(defineComponent, templates, events) {
-    'use strict';
-
-    return defineComponent(refreshTrigger);
-
-    function refreshTrigger() {
-      this.render = function() {
-        this.$node.html(templates.mailActions.refreshTrigger);
-      };
-
-      this.refresh = function(event) {
-        this.trigger(document, events.ui.mails.refresh);
-      };
-
-      this.after('initialize', function () {
-        this.render();
-        this.on('click', this.refresh);
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_list_actions/ui/toggle_check_all_trigger.js b/web-ui/app/js/mail_list_actions/ui/toggle_check_all_trigger.js
deleted file mode 100644
index 71c65346..00000000
--- a/web-ui/app/js/mail_list_actions/ui/toggle_check_all_trigger.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'page/events'
-  ],
-
-  function(defineComponent, events) {
-    'use strict';
-
-    return defineComponent(toggleCheckAllEmailsTrigger);
-
-    function toggleCheckAllEmailsTrigger() {
-      this.defaultAttrs({ });
-
-      this.toggleCheckAll = function(event) {
-        if (this.$node.prop('checked')) {
-          this.trigger(document, events.ui.mails.checkAll);
-        } else {
-          this.trigger(document, events.ui.mails.uncheckAll);
-        }
-      };
-
-      this.setCheckbox = function (event, state) {
-        this.$node.prop('checked', state);
-      };
-
-      this.after('initialize', function () {
-        this.on('click', this.toggleCheckAll);
-        this.on(document, events.ui.mails.hasMailsChecked, this.setCheckbox);
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_view/data/feedback_sender.js b/web-ui/app/js/mail_view/data/feedback_sender.js
deleted file mode 100644
index 2232dbe4..00000000
--- a/web-ui/app/js/mail_view/data/feedback_sender.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2015 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'helpers/monitored_ajax',
-    'page/events'
-  ],
-  function (defineComponent, monitoredAjax, events) {
-    'use strict';
-
-  return defineComponent(function () {
-    this.defaultAttrs({
-      feedbackResource: '/feedback'
-    });
-
-    this.successSubmittingFeedback = function() {
-      this.trigger(document, events.feedback.submitted);
-    };
-
-    this.submitFeedback = function(event, data) {
-      monitoredAjax.call(_, this, this.attr.feedbackResource, {
-        type: 'POST',
-        dataType: 'json',
-        contentType: 'application/json; charset=utf-8',
-        data: JSON.stringify(data)
-      }).done(this.successSubmittingFeedback());
-    };
-
-    this.after('initialize', function () {
-      this.on(document, events.feedback.submit, this.submitFeedback);
-    });
-
-  });
-});
diff --git a/web-ui/app/js/mail_view/data/mail_builder.js b/web-ui/app/js/mail_view/data/mail_builder.js
deleted file mode 100644
index 7a478dd8..00000000
--- a/web-ui/app/js/mail_view/data/mail_builder.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(['services/model/mail'], function (mailModel) {
-    'use strict';
-
-    var mail;
-
-    function recipients(mail, place, v) {
-        if (v !== '' && !_.isUndefined(v)) {
-            if (_.isArray(v)) {
-                mail[place] = v;
-            } else {
-                mail[place] = v.split(' ');
-            }
-        } else {
-            mail[place] = [];
-        }
-    }
-
-    return {
-        newMail: function (ident) {
-            ident = _.isUndefined(ident) ? '' : ident;
-
-            mail = {
-                header: {
-                    to: [],
-                    cc: [],
-                    bcc: [],
-                    from: undefined,
-                    subject: ''
-                },
-                tags: [],
-                body: '',
-                attachments: [],
-                ident: ident
-            };
-            return this;
-        },
-
-        subject: function (subject) {
-            mail.header.subject = subject;
-            return this;
-        },
-
-        body: function (body) {
-            mail.body = body;
-            return this;
-        },
-
-        to: function (to) {
-            recipients(mail.header, 'to', to);
-            return this;
-        },
-
-        cc: function (cc) {
-            recipients(mail.header, 'cc', cc);
-            return this;
-        },
-
-        bcc: function (bcc) {
-            recipients(mail.header, 'bcc', bcc);
-            return this;
-        },
-
-        header: function (name, value) {
-            mail.header[name] = value;
-            return this;
-        },
-
-        tag: function (tag) {
-            if (_.isUndefined(tag)) {
-                tag = 'drafts';
-            }
-            mail.tags.push(tag);
-            return this;
-        },
-
-        attachment: function (attachmentList) {
-            mail.attachments = attachmentList;
-            return this;
-        },
-
-        build: function () {
-            return mailModel.create(mail);
-        }
-    };
-});
diff --git a/web-ui/app/js/mail_view/data/mail_sender.js b/web-ui/app/js/mail_view/data/mail_sender.js
deleted file mode 100644
index 8bb01f70..00000000
--- a/web-ui/app/js/mail_view/data/mail_sender.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'mail_view/data/mail_builder',
-    'page/events',
-    'helpers/monitored_ajax',
-    'features'
-  ],
-  function (defineComponent, mailBuilder, events, monitoredAjax, features) {
-    'use strict';
-
-    return defineComponent(mailSender);
-
-    function mailSender() {
-      function successSendingMail(on){
-        return function(result) {
-          on.trigger(document, events.mail.sent, result);
-        };
-      }
-
-      function failureSendingMail(on) {
-        return function(result) {
-          on.trigger(document, events.mail.send_failed, result);
-        };
-      }
-
-      function successSaveDraft(on){
-        return function(result){
-          on.trigger(document, events.mail.draftSaved, result);
-        };
-      }
-
-      this.defaultAttrs({
-        mailsResource: '/mails'
-      });
-
-      this.sendMail = function(event, data) {
-        this.trigger(events.dispatchers.rightPane.openNoMessageSelected);
-        monitoredAjax.call(_, this, this.attr.mailsResource, {
-          type: 'POST',
-          dataType: 'json',
-          contentType: 'application/json; charset=utf-8',
-          data: JSON.stringify(data)
-        }).done(successSendingMail(this)).fail(failureSendingMail(this));
-
-      };
-
-      this.saveMail = function(mail) {
-        return monitoredAjax.call(_, this, this.attr.mailsResource, {
-          type: 'PUT',
-          dataType: 'json',
-          contentType: 'application/json; charset=utf-8',
-          data: JSON.stringify(mail),
-          skipErrorMessage: true
-        });
-      };
-
-      this.saveDraft = function(event, data) {
-        this.saveMail(data)
-          .done(successSaveDraft(this));
-      };
-
-      this.saveMailWithCallback = function(event, data) {
-        this.saveMail(data.mail)
-          .done(function(result) { return data.callback(result); })
-          .fail(function(result) { return data.callback(result); });
-      };
-
-      this.after('initialize', function () {
-        this.on(events.mail.send, this.sendMail);
-        if(features.isEnabled('saveDraft')) {
-          this.on(events.mail.saveDraft, this.saveDraft);
-        }
-        this.on(document, events.mail.save, this.saveMailWithCallback);
-      });
-    }
-  });
diff --git a/web-ui/app/js/mail_view/ui/attachment_icon.js b/web-ui/app/js/mail_view/ui/attachment_icon.js
deleted file mode 100644
index e04fc02a..00000000
--- a/web-ui/app/js/mail_view/ui/attachment_icon.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2015 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-    [
-        'flight/lib/component',
-        'page/events',
-        'features'
-    ],
-
-    function (defineComponent, events, features) {
-        'use strict';
-
-        return defineComponent(function () {
-            this.render = function () {
-                this.$node.html('<i class="fa fa-paperclip"></i>');
-            };
-
-            this.triggerUploadAttachment = function () {
-                this.trigger(document, events.mail.startUploadAttachment);
-            };
-
-            this.uploadInProgress = function (ev, data) {
-                this.attr.busy = true;
-                this.$node.addClass('busy');
-            };
-
-            this.uploadFinished = function (ev, data) {
-                this.attr.busy = false;
-                this.$node.removeClass('busy');
-            };
-
-            this.after('initialize', function () {
-                if (features.isEnabled('attachment')) {
-                    this.render();
-                    this.on(document, events.mail.uploadingAttachment, this.uploadInProgress);
-                    this.on(document, events.mail.uploadedAttachment, this.uploadFinished);
-                    this.on(document, events.mail.failedUploadAttachment, this.uploadFinished);
-                }
-                this.on(this.$node, 'click', function() {
-                    if (!this.attr.busy) {
-                        this.triggerUploadAttachment();
-                    }
-                });
-            });
-        });
-    });
diff --git a/web-ui/app/js/mail_view/ui/attachment_list.js b/web-ui/app/js/mail_view/ui/attachment_list.js
deleted file mode 100644
index 4ef64960..00000000
--- a/web-ui/app/js/mail_view/ui/attachment_list.js
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (c) 2015 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-    [
-        'views/templates',
-        'page/events',
-        'helpers/view_helper',
-        'helpers/monitored_ajax'
-    ],
-
-    function (templates, events, viewHelper, monitoredAjax) {
-        'use strict';
-
-        function attachmentList() {
-            this.defaultAttrs({
-                inputFileUpload: '#fileupload',
-                attachmentListItem: '#attachment-list-item',
-                attachmentUploadItem: '#attachment-upload-item',
-                attachmentUploadItemProgress: '#attachment-upload-item-progress',
-                attachmentUploadItemAbort: '#attachment-upload-item-abort',
-                attachmentBaseUrl: '/attachment',
-                attachments: [],
-                closeIcon: '#upload-error-close',
-                uploadError: '#upload-error',
-                dismissButton: '#dismiss-button',
-                uploadFileButton: '#upload-file-button'
-            });
-
-            var ONE_MEGABYTE = 1024*1024;
-            var ATTACHMENT_SIZE_LIMIT = 5*ONE_MEGABYTE;
-
-            this.showAttachment = function (ev, data) {
-                this.trigger(document, events.mail.appendAttachment, data);
-                this.renderAttachmentListView(data);
-            };
-
-            this.addAttachment = function (event, data) {
-                this.attr.attachments.push(data);
-            };
-
-            this.renderAttachmentListView = function (data) {
-                var currentHtml = this.select('attachmentListItem').html();
-                var item = this.buildAttachmentListItem(data);
-                this.select('attachmentListItem').append(item);
-            };
-
-            this.buildAttachmentListItem = function (attachment) {
-                var attachmentData = {ident: attachment.ident,
-                                      encoding: attachment.encoding,
-                                      name: attachment.name,
-                                      size: attachment.size,
-                                      removable: true};
-
-                var element = $(templates.compose.attachmentItem(attachmentData));
-                var self = this;
-                element.find('i.remove-icon').bind('click', function(event) {
-                    var element = $(this);
-                    var ident = element.closest('li').attr('data-ident');
-                    self.trigger(document, events.mail.removeAttachment, {ident: ident, element: element});
-                    event.preventDefault();
-                });
-                return element;
-            };
-
-            this.performPreUploadCheck = function(e, data) {
-                if (data.originalFiles[0].size > ATTACHMENT_SIZE_LIMIT) {
-                    return false;
-                }
-
-                return true;
-            };
-
-            this.removeUploadError = function() {
-                var uploadError = this.select('uploadError');
-                if (uploadError) {
-                    uploadError.remove();
-                }
-            };
-
-            this.showUploadError = function () {
-                var self = this;
-
-                var html = $(templates.compose.uploadAttachmentFailed());
-                html.insertAfter(self.select('attachmentListItem'));
-
-                self.on(self.select('closeIcon'), 'click', dismissUploadFailed);
-                self.on(self.select('dismissButton'), 'click', dismissUploadFailed);
-                self.on(self.select('uploadFileButton'), 'click', uploadAnotherFile);
-
-                function dismissUploadFailed(event) {
-                    event.preventDefault();
-                    self.select('uploadError').remove();
-                }
-
-                function uploadAnotherFile(event) {
-                    event.preventDefault();
-                    self.trigger(document, events.mail.startUploadAttachment);
-                }
-            };
-
-            this.showUploadProgressBar = function(e, data) {
-                var element = $(templates.compose.attachmentUploadItem({
-                    name: data.originalFiles[0].name,
-                    size: data.originalFiles[0].size
-                }));
-                this.select('attachmentUploadItem').append(element);
-                this.select('attachmentUploadItem').show();
-            };
-
-            this.hideUploadProgressBar = function() {
-                this.select('attachmentUploadItem').hide();
-                this.select('attachmentUploadItem').empty();
-            };
-
-            this.attachUploadAbort = function(e, data) {
-                this.on(this.select('attachmentUploadItemAbort'), 'click', function(e) {
-                    data.abort();
-                    e.preventDefault();
-                });
-            };
-
-            this.detachUploadAbort = function() {
-                this.off(this.select('attachmentUploadItemAbort'), 'click');
-            };
-
-            this.addJqueryFileUploadConfig = function() {
-                var self = this;
-
-                self.removeUploadError();
-
-                this.select('inputFileUpload').fileupload({
-                    add: function(e, data) {
-                        if (self.performPreUploadCheck(e, data)) {
-                            self.showUploadProgressBar(e, data);
-                            self.attachUploadAbort(e, data);
-                            data.submit();
-                        } else {
-                            self.showUploadError();
-                        }
-                    },
-                    url: self.attr.attachmentBaseUrl,
-                    dataType: 'json',
-                    done: function (e, response) {
-                        self.detachUploadAbort();
-                        self.hideUploadProgressBar();
-                        self.trigger(document, events.mail.uploadedAttachment, response.result);
-                    },
-                    fail: function(e, data){
-                        self.detachUploadAbort();
-                        self.hideUploadProgressBar();
-                        self.trigger(document, events.mail.failedUploadAttachment);
-                    },
-                    progressall: function (e, data) {
-                        var progressRate = parseInt(data.loaded / data.total * 100, 10);
-                        self.select('attachmentUploadItemProgress').css('width', progressRate + '%');
-                    }
-                }).bind('fileuploadstart', function (e) {
-                    self.trigger(document, events.mail.uploadingAttachment);
-                });
-            };
-
-            this.startUpload = function () {
-                this.addJqueryFileUploadConfig();
-                this.select('inputFileUpload').click();
-            };
-
-            this.removeAttachmentFromList = function(ident) {
-              for (var i = 0; i < this.attr.attachments.length; i++) {
-                if (this.attr.attachments[i].ident === ident) {
-                  this.attr.attachments.remove(i);
-                  break;
-                }
-              }
-            };
-
-            this.destroyAttachmentElement = function(element) {
-              element.closest('li').remove();
-            };
-
-            this.removeAttachments = function(event, data) {
-              this.removeAttachmentFromList(data.ident);
-              this.destroyAttachmentElement(data.element);
-            };
-
-            this.after('initialize', function () {
-                this.addJqueryFileUploadConfig();
-                this.on(document, events.mail.uploadedAttachment, this.showAttachment);
-                this.on(document, events.mail.startUploadAttachment, this.startUpload);
-                this.on(document, events.mail.appendAttachment, this.addAttachment);
-                this.on(document, events.mail.removeAttachment, this.removeAttachments);
-            });
-        }
-
-        return attachmentList;
-    });
diff --git a/web-ui/app/js/mail_view/ui/compose_box.js b/web-ui/app/js/mail_view/ui/compose_box.js
deleted file mode 100644
index 101dc939..00000000
--- a/web-ui/app/js/mail_view/ui/compose_box.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'views/templates',
-    'mixins/with_mail_edit_base',
-    'page/events',
-    'mail_view/data/mail_builder'
-  ],
-
-  function (defineComponent, templates, withMailEditBase, events, mailBuilder) {
-    'use strict';
-
-    return defineComponent(composeBox, withMailEditBase);
-
-    function composeBox() {
-
-      this.defaultAttrs({
-        'closeButton': '.close-mail-button'
-      });
-
-      this.showNoMessageSelected = function() {
-        this.trigger(events.dispatchers.rightPane.openNoMessageSelected);
-      };
-
-      this.buildMail = function(tag) {
-        return this.builtMail(tag).build();
-      };
-
-      this.builtMail = function(tag) {
-        return mailBuilder.newMail(this.attr.ident)
-          .subject(this.select('subjectBox').val())
-          .to(this.attr.recipientValues.to)
-          .cc(this.attr.recipientValues.cc)
-          .bcc(this.attr.recipientValues.bcc)
-          .body(this.select('bodyBox').val())
-          .attachment(this.attr.attachments)
-          .tag(tag);
-      };
-
-      this.renderComposeBox = function() {
-        this.render(templates.compose.box, {});
-        this.enableFloatlabel('input.floatlabel');
-        this.enableFloatlabel('textarea.floatlabel');
-        this.select('recipientsFields').show();
-        this.on(this.select('closeButton'), 'click', this.showNoMessageSelected);
-        this.enableAutoSave();
-      };
-
-      this.mailDeleted = function(event, data) {
-        if (_.contains(_.pluck(data.mails, 'ident'),  this.attr.ident)) {
-          this.trigger(events.dispatchers.rightPane.openNoMessageSelected);
-        }
-      };
-
-      this.discardDraft = function () {
-        this.trigger(events.dispatchers.rightPane.openNoMessageSelected);
-      };
-
-      this.after('initialize', function () {
-        this.renderComposeBox();
-
-        this.select('toBox').focus();
-        this.on(document, events.mail.deleted, this.mailDeleted);
-        this.on(document, events.mail.sent, this.showNoMessageSelected);
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_view/ui/draft_box.js b/web-ui/app/js/mail_view/ui/draft_box.js
deleted file mode 100644
index afe31914..00000000
--- a/web-ui/app/js/mail_view/ui/draft_box.js
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'views/templates',
-    'mixins/with_mail_edit_base',
-    'page/events',
-    'mail_view/data/mail_builder'
-  ],
-
-  function (defineComponent, templates, withMailEditBase, events, mailBuilder) {
-    'use strict';
-
-    return defineComponent(draftBox, withMailEditBase);
-
-    function draftBox() {
-      this.defaultAttrs({
-        closeMailButton: '.close-mail-button'
-      });
-
-      this.showNoMessageSelected = function() {
-        this.trigger(events.dispatchers.rightPane.openNoMessageSelected);
-      };
-
-      this.buildMail = function(tag) {
-        return this.builtMail(tag).build();
-      };
-
-      this.builtMail = function(tag) {
-        return mailBuilder.newMail(this.attr.ident)
-          .subject(this.select('subjectBox').val())
-          .to(this.attr.recipientValues.to)
-          .cc(this.attr.recipientValues.cc)
-          .bcc(this.attr.recipientValues.bcc)
-          .body(this.select('bodyBox').val())
-          .attachment(this.attr.attachments)
-          .tag(tag);
-      };
-
-      this.renderDraftBox = function(ev, data) {
-        var mail = data.mail;
-        var body = mail.textPlainBody;
-        this.attr.ident = mail.ident;
-        this.render(templates.compose.box, {
-          recipients: {
-            to: mail.header.to,
-            cc: mail.header.cc,
-            bcc: mail.header.bcc
-          },
-          subject: mail.header.subject,
-          body: body,
-          attachments: this.convertToRemovableAttachments(mail.attachments)
-        });
-
-        var self = this;
-        this.$node.find('i.remove-icon').bind('click', function(event) {
-          var element = $(this);
-          var ident = element.closest('li').attr('data-ident');
-          self.trigger(document, events.mail.removeAttachment, {ident: ident, element: element});
-          event.preventDefault();
-        });
-
-        this.enableFloatlabel('input.floatlabel');
-        this.enableFloatlabel('textarea.floatlabel');
-        this.select('recipientsFields').show();
-        this.select('bodyBox').focus();
-        this.select('tipMsg').hide();
-        this.enableAutoSave();
-        this.bindCollapse();
-        this.on(this.select('closeMailButton'), 'click', this.showNoMessageSelected);
-      };
-
-      this.convertToRemovableAttachments = function(attachments) {
-        return attachments.map(function(attachment) {
-          attachment.removable = true;
-          return attachment;
-        });
-      };
-
-      this.mailDeleted = function(event, data) {
-        if (_.contains(_.pluck(data.mails, 'ident'),  this.attr.ident)) {
-          this.trigger(events.dispatchers.rightPane.openNoMessageSelected);
-        }
-      };
-
-      this.after('initialize', function () {
-        this.on(this, events.mail.here, this.renderDraftBox);
-        this.on(document, events.mail.sent, this.showNoMessageSelected);
-        this.on(document, events.mail.deleted, this.mailDeleted);
-        this.trigger(document, events.mail.want, { mail: this.attr.mailIdent, caller: this });
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_view/ui/draft_save_status.js b/web-ui/app/js/mail_view/ui/draft_save_status.js
deleted file mode 100644
index 47751d91..00000000
--- a/web-ui/app/js/mail_view/ui/draft_save_status.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'page/events',
-    'views/i18n'
-  ],
-
-  function (defineComponent, events, i18n) {
-    'use strict';
-
-    return defineComponent(draftSaveStatus);
-
-    function draftSaveStatus() {
-      this.setMessage = function(msg) {
-        var node = this.$node;
-        return function () { node.text(msg); };
-      };
-
-      this.after('initialize', function () {
-        this.on(document, events.mail.saveDraft, this.setMessage(i18n.t('draft-saving')));
-        this.on(document, events.mail.draftSaved, this.setMessage(i18n.t('draft-saved')));
-        this.on(document, events.ui.mail.changedSinceLastSave, this.setMessage(''));
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_view/ui/feedback_box.js b/web-ui/app/js/mail_view/ui/feedback_box.js
deleted file mode 100644
index 4e00ece8..00000000
--- a/web-ui/app/js/mail_view/ui/feedback_box.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2015 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(['flight/lib/component', 'views/templates', 'page/events', 'features', 'feedback/feedback_cache'],
-  function (defineComponent, templates, events, features, feedbackCache) {
-    'use strict';
-
-    return defineComponent(function () {
-      this.defaultAttrs({
-        'closeButton': '.close-mail-button',
-        'submitButton': '#send-button',
-        'textBox': '#text-box',
-      });
-
-      this.render = function () {
-        this.$node.html(templates.compose.feedback());
-      };
-
-      this.startCachingData = function () {
-        this.select('textBox').val(feedbackCache.getCache());
-        this.select('textBox').on('change', this.cacheFeedbackData.bind(this));
-      };
-
-
-      this.cacheFeedbackData = function () {
-        feedbackCache.setCache(this.select('textBox').val());
-      };
-
-      this.showNoMessageSelected = function () {
-        this.trigger(document, events.dispatchers.rightPane.openNoMessageSelected);
-      };
-
-      this.submitFeedback = function () {
-        var feedback = this.select('textBox').val();
-        this.trigger(document, events.feedback.submit, {feedback: feedback});
-        feedbackCache.resetCache();
-      };
-
-      this.showSuccessMessage = function () {
-        this.trigger(document, events.ui.userAlerts.displayMessage, {message: 'Thanks for your feedback!'});
-      };
-
-      this.after('initialize', function () {
-        if (features.isEnabled('feedback')) {
-          this.render();
-          this.startCachingData();
-          this.on(document, events.feedback.submitted, this.showNoMessageSelected);
-          this.on(document, events.feedback.submitted, this.showSuccessMessage);
-          this.on(this.select('closeButton'), 'click', this.showNoMessageSelected);
-          this.on(this.select('submitButton'), 'click', this.submitFeedback);
-        }
-      });
-
-    });
-  });
diff --git a/web-ui/app/js/mail_view/ui/forward_box.js b/web-ui/app/js/mail_view/ui/forward_box.js
deleted file mode 100644
index a34bd55d..00000000
--- a/web-ui/app/js/mail_view/ui/forward_box.js
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-  [
-    'flight/lib/component',
-    'helpers/view_helper',
-    'mixins/with_hide_and_show',
-    'mixins/with_compose_inline',
-    'page/events',
-    'views/i18n'
-  ],
-
-  function (defineComponent, viewHelper, withHideAndShow, withComposeInline, events, i18n) {
-    'use strict';
-
-    return defineComponent(forwardBox, withHideAndShow, withComposeInline);
-
-    function forwardBox() {
-      var fwd = function(v) { return i18n.t('fwd') + ': ' + v; };
-
-      this.fetchTargetMail = function (ev) {
-        this.trigger(document, events.mail.want, { mail: this.attr.ident, caller: this });
-      };
-
-      this.setupForwardBox = function() {
-        var mail = this.attr.mail;
-        this.attr.subject = fwd(mail.header.subject);
-        this.attr.attachments = mail.attachments;
-
-        this.renderInlineCompose('forward-box', {
-          subject: this.attr.subject,
-          recipients: { to: [], cc: []},
-          body: viewHelper.quoteMail(mail),
-          attachments: this.convertToRemovableAttachments(mail.attachments)
-        });
-
-        var self = this;
-        this.$node.find('i.remove-icon').bind('click', function(event) {
-          var element = $(this);
-          var ident = element.closest('li').attr('data-ident');
-          self.trigger(document, events.mail.removeAttachment, {ident: ident});
-          event.preventDefault();
-        });
-
-        this.on(this.select('subjectDisplay'), 'click', this.showSubjectInput);
-        this.select('recipientsDisplay').hide();
-        this.select('recipientsFields').show();
-      };
-
-      this.convertToRemovableAttachments = function(attachments) {
-        return attachments.map(function(attachment) {
-          attachment.removable = true;
-          return attachment;
-        });
-      };
-
-      this.showSubjectInput = function() {
-        this.select('subjectDisplay').hide();
-        this.select('subjectInput').show();
-        this.select('subjectInput').focus();
-      };
-
-      this.buildMail = function(tag) {
-        var builder = this.builtMail(tag).subject(this.select('subjectInput').val());
-
-        var headersToFwd = ['bcc', 'cc', 'date', 'from', 'message_id', 'reply_to', 'sender', 'to'];
-        var header = this.attr.mail.header;
-        _.each(headersToFwd, function (h) {
-          if (!_.isUndefined(header[h])) {
-            builder.header('resent_' + h, header[h]);
-          }
-        });
-
-        return builder.build();
-      };
-
-      this.after('initialize', function () {
-        this.setupForwardBox();
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_view/ui/mail_actions.js b/web-ui/app/js/mail_view/ui/mail_actions.js
deleted file mode 100644
index 65cd0aaa..00000000
--- a/web-ui/app/js/mail_view/ui/mail_actions.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-  [
-    'flight/lib/component',
-    'views/templates',
-    'page/events'
-  ],
-
-  function (defineComponent, templates, events) {
-    'use strict';
-
-    return defineComponent(mailActions);
-
-    function mailActions() {
-
-      this.defaultAttrs({
-        replyButtonTop: '#reply-button-top',
-        viewMoreActions: '#view-more-actions',
-        replyAllButtonTop: '#reply-all-button-top',
-        deleteButtonTop: '#delete-button-top',
-        moreActions: '#more-actions'
-      });
-
-
-      this.displayMailActions = function () {
-
-        this.$node.html(templates.mails.mailActions());
-
-        this.select('moreActions').hide();
-
-        this.on(this.select('replyButtonTop'), 'click', function () {
-          this.trigger(document, events.ui.replyBox.showReply);
-        }.bind(this));
-
-        this.on(this.select('replyAllButtonTop'), 'click', function () {
-          this.trigger(document, events.ui.replyBox.showReplyAll);
-          this.select('moreActions').hide();
-        }.bind(this));
-
-        this.on(this.select('deleteButtonTop'), 'click', function () {
-          this.trigger(document, events.ui.mail.delete, {mail: this.attr.mail});
-          this.select('moreActions').hide();
-        }.bind(this));
-
-        this.on(this.select('viewMoreActions'), 'click', function () {
-          this.select('moreActions').toggle();
-        }.bind(this));
-
-        this.on(this.select('viewMoreActions'), 'blur', function (event) {
-          var replyButtonTopHover = this.select('replyAllButtonTop').is(':hover');
-          var deleteButtonTopHover = this.select('deleteButtonTop').is(':hover');
-
-          if (replyButtonTopHover || deleteButtonTopHover) {
-            event.preventDefault();
-          } else {
-            this.select('moreActions').hide();
-          }
-        }.bind(this));
-
-      };
-
-      this.after('initialize', function () {
-        this.on(document, events.dispatchers.rightPane.clear, this.teardown);
-        this.displayMailActions();
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_view/ui/mail_view.js b/web-ui/app/js/mail_view/ui/mail_view.js
deleted file mode 100644
index 3408c8af..00000000
--- a/web-ui/app/js/mail_view/ui/mail_view.js
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-  [
-    'flight/lib/component',
-    'views/templates',
-    'mail_view/ui/mail_actions',
-    'helpers/view_helper',
-    'mixins/with_hide_and_show',
-    'mixins/with_mail_tagging',
-    'mixins/with_mail_sandbox',
-    'page/events',
-    'views/i18n'
-  ],
-
-  function (defineComponent, templates, mailActions, viewHelpers, withHideAndShow, withMailTagging, withMailSandbox, events, i18n) {
-  'use strict';
-
-    return defineComponent(mailView, mailActions, withHideAndShow, withMailTagging, withMailSandbox);
-
-    function mailView() {
-      this.defaultAttrs({
-        tags: '.mail-read-view__header-tags-tag',
-        newTagInput: '#new-tag-input',
-        newTagButton: '#new-tag-button',
-        addNew: '.mail-read-view__header-tags-new-button',
-        trashButton: '#trash-button',
-        archiveButton: '#archive-button',
-        closeMailButton: '.close-mail-button'
-      });
-
-      this.displayMail = function (event, data) {
-        this.attr.mail = data.mail;
-
-        var signed, encrypted, attachments;
-
-        data.mail.security_casing = data.mail.security_casing || {};
-        signed = this.checkSigned(data.mail);
-        encrypted = this.checkEncrypted(data.mail);
-        attachments = data.mail.attachments.map(function (attachment) {
-            attachment.received = true;
-            return attachment;
-        });
-
-        if(data.mail.mailbox === 'sent') {
-          encrypted = undefined;
-          signed = undefined;
-        }
-
-        this.$node.html(templates.mails.fullView({
-          header: data.mail.header,
-          body: [],
-          statuses: viewHelpers.formatStatusClasses(data.mail.status),
-          ident: data.mail.ident,
-          tags: data.mail.tags,
-          encryptionStatus: encrypted,
-          signatureStatus: signed,
-          attachments: attachments
-        }));
-
-        this.showMailOnSandbox(this.attr.mail);
-
-        this.attachTagCompletion(this.attr.mail);
-
-        this.select('tags').on('click', function (event) {
-          this.removeTag($(event.target).text());
-        }.bind(this));
-
-        this.addTagLoseFocus();
-        this.on(this.select('newTagButton'), 'click', this.showNewTagInput);
-        this.on(this.select('newTagInput'), 'keydown', this.handleKeyDown);
-        this.on(this.select('newTagInput'), 'blur', this.addTagLoseFocus);
-        this.on(this.select('trashButton'), 'click', this.moveToTrash);
-        this.on(this.select('closeMailButton'), 'click', this.openNoMessageSelectedPane);
-
-        mailActions.attachTo('#mail-actions', data);
-        this.resetScroll();
-      };
-
-      this.resetScroll = function(){
-        $('#right-pane').scrollTop(0);
-      };
-
-      this.checkEncrypted = function(mail) {
-        if(_.isEmpty(mail.security_casing.locks)) {
-          return {
-            cssClass: 'security-status__label--not-encrypted',
-            label: 'not-encrypted'
-          };
-        }
-
-        var statusClass = ['security-status__label--encrypted'];
-        var statusLabel;
-
-        var hasAnyEncryptionInfo = _.any(mail.security_casing.locks, function (lock) {
-          return lock.state === 'valid';
-        });
-
-        if(hasAnyEncryptionInfo) {
-          statusLabel = 'encrypted';
-        } else {
-          statusClass.push('--with-error');
-          statusLabel = 'encryption-error';
-        }
-
-        return {
-          cssClass: statusClass.join(''),
-          label: statusLabel
-        };
-      };
-
-      this.checkSigned = function(mail) {
-        var statusNotSigned = {
-          cssClass: 'security-status__label--not-signed',
-          label: 'not-signed'
-        };
-
-        if(_.isEmpty(mail.security_casing.imprints)) {
-          return statusNotSigned;
-        }
-
-        var hasNoSignatureInformation = _.any(mail.security_casing.imprints, function (imprint) {
-          return imprint.state === 'no_signature_information';
-        });
-
-        if(hasNoSignatureInformation) {
-          return statusNotSigned;
-        }
-
-        var statusClass = ['security-status__label--signed'];
-        var statusLabel = ['signed'];
-
-        if(_.any(mail.security_casing.imprints, function(imprint) { return imprint.state === 'from_revoked'; })) {
-          statusClass.push('--revoked');
-          statusLabel.push('signature-revoked');
-        }
-
-        if(_.any(mail.security_casing.imprints, function(imprint) { return imprint.state === 'from_expired'; })) {
-          statusClass.push('--expired');
-          statusLabel.push('signature-expired');
-        }
-
-        if(this.isNotTrusted(mail)) {
-          statusClass.push('--not-trusted');
-          statusLabel.push('signature-not-trusted');
-        }
-
-        return {
-          cssClass: statusClass.join(''),
-          label: statusLabel.join(' ')
-        };
-      };
-
-      this.isNotTrusted = function(mail){
-        return _.any(mail.security_casing.imprints, function(imprint) {
-          if(_.isNull(imprint.seal)){
-            return true;
-          }
-          var currentTrust = _.isUndefined(imprint.seal.trust) ? imprint.seal.validity : imprint.seal.trust;
-          return currentTrust === 'no_trust';
-        });
-      };
-
-      this.openNoMessageSelectedPane = function(ev, data) {
-        this.trigger(document, events.dispatchers.rightPane.openNoMessageSelected);
-      };
-
-      this.handleKeyDown = function(event) {
-        var ENTER_KEY = 13;
-        var ESC_KEY = 27;
-
-        if (event.which === ENTER_KEY){
-          event.preventDefault();
-          if (this.select('newTagInput').val().trim() !== '') {
-            this.createNewTag();
-          }
-        } else if (event.which === ESC_KEY) {
-          event.preventDefault();
-          this.addTagLoseFocus();
-        }
-      };
-
-      this.addTagLoseFocus = function () {
-        this.select('newTagInput').hide();
-        this.select('newTagInput').typeahead('val', '');
-        this.select('addNew').show();
-      };
-
-      this.showNewTagInput = function () {
-        this.select('newTagInput').show();
-        this.select('newTagInput').focus();
-        this.select('addNew').hide();
-      };
-
-      this.removeTag = function (tag) {
-        tag = tag.toString();
-        var filteredTags = _.without(this.attr.mail.tags, tag);
-        this.updateTags(this.attr.mail, filteredTags);
-        this.trigger(document, events.dispatchers.tags.refreshTagList);
-      };
-
-      this.moveToTrash = function(){
-        this.trigger(document, events.ui.mail.delete, { mail: this.attr.mail });
-      };
-
-      this.tagsUpdated = function(ev, data) {
-        data = data || {};
-        this.attr.mail.tags = data.tags;
-        this.displayMail({}, { mail: this.attr.mail });
-      };
-
-      this.mailDeleted = function(ev, data) {
-        if (_.contains(_.pluck(data.mails, 'ident'),  this.attr.mail.ident)) {
-          this.openNoMessageSelectedPane();
-        }
-      };
-
-      this.fetchMailToShow = function () {
-        this.trigger(events.mail.want, {mail: this.attr.ident, caller: this});
-      };
-
-      this.highlightMailContent = function (event, data) {
-        // we can't directly manipulate the iFrame to highlight the content
-        // so we need to take an indirection where we directly manipulate
-        // the mail content to accomodate the highlighting
-        this.trigger(document, events.mail.highlightMailContent, data);
-      };
-
-      this.after('initialize', function () {
-        this.on(this, events.mail.notFound, this.openNoMessageSelectedPane);
-        this.on(this, events.mail.here, this.highlightMailContent);
-        this.on(document, events.mail.display, this.displayMail);
-        this.on(document, events.dispatchers.rightPane.clear, this.teardown);
-        this.on(document, events.mail.tags.updated, this.tagsUpdated);
-        this.on(document, events.mail.deleted, this.mailDeleted);
-        this.fetchMailToShow();
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_view/ui/no_mails_available_pane.js b/web-ui/app/js/mail_view/ui/no_mails_available_pane.js
deleted file mode 100644
index c62c6b30..00000000
--- a/web-ui/app/js/mail_view/ui/no_mails_available_pane.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'views/templates',
-    'mixins/with_hide_and_show',
-    'page/events'
-  ],
-
-  function(defineComponent, templates, withHideAndShow, events) {
-    'use strict';
-
-    //return defineComponent(noMailsAvailablePane, withHideAndShow);
-    return defineComponent(noMailsAvailablePane);
-
-    function noMailsAvailablePane() {
-      this.defaultAttrs({
-        tag: null,
-        forSearch: ''
-      });
-
-      var mailsQueryMatch = /-?in:"?[\w]+"?|tag:"[\w]+"/g;
-
-      this.render = function() {
-        this.attr.tag = 'tags.' + this.attr.tag;
-        this.attr.forSearch = this.attr.forSearch.replace(mailsQueryMatch, '').trim();
-        this.$node.html(templates.noMailsAvailable(this.attr));
-      };
-
-      this.after('initialize', function () {
-        this.render();
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_view/ui/no_message_selected_pane.js b/web-ui/app/js/mail_view/ui/no_message_selected_pane.js
deleted file mode 100644
index a5fc2393..00000000
--- a/web-ui/app/js/mail_view/ui/no_message_selected_pane.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'views/templates',
-    'mixins/with_hide_and_show',
-    'page/events'
-  ],
-
-  function(defineComponent, templates, withHideAndShow, events) {
-    'use strict';
-
-    return defineComponent(noMessageSelectedPane, withHideAndShow);
-
-    function noMessageSelectedPane() {
-      this.render = function() {
-        this.$node.html(templates.noMessageSelected());
-      };
-
-      this.after('initialize', function () {
-        this.render();
-        this.on(document, events.dispatchers.rightPane.clear, this.teardown);
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_view/ui/recipients/recipient.js b/web-ui/app/js/mail_view/ui/recipients/recipient.js
deleted file mode 100644
index c13a52b1..00000000
--- a/web-ui/app/js/mail_view/ui/recipients/recipient.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-  [
-    'flight/lib/component',
-    'views/templates',
-    'page/events'
-  ],
-
-  function (defineComponent, templates, events) {
-  'use strict';
-
-    return defineComponent(recipient);
-
-    function recipient() {
-      this.renderAndPrepend = function (nodeToPrependTo, recipient) {
-        var html = $(templates.compose.fixedRecipient(recipient));
-        html.insertBefore(nodeToPrependTo.children().last());
-        var component = new this.constructor();
-        component.initialize(html, recipient);
-        component.attr.recipient = recipient;
-        return component;
-      };
-
-      this.recipientDelActions = function () {
-        this.on(this.$node.find('.recipient-del'), 'click', function (event) {
-          this.doSelect();
-          this.trigger(events.ui.recipients.deleteRecipient, this);
-          event.preventDefault();
-        });
-
-        this.on(this.$node.find('.recipient-del'), 'mouseover', function () {
-          this.$node.find('.recipient-value').addClass('deleting');
-          this.$node.find('.recipient-del').addClass('deleteTooltip');
-        });
-
-        this.on(this.$node.find('.recipient-del'), 'mouseout', function () {
-          this.$node.find('.recipient-value').removeClass('deleting');
-          this.$node.find('.recipient-del').removeClass('deleteTooltip');
-        });
-      };
-
-      this.destroy = function () {
-        this.$node.remove();
-        this.teardown();
-      };
-
-      this.doSelect = function () {
-        this.$node.find('.recipient-value').addClass('selected');
-      };
-
-      this.doUnselect = function () {
-        this.$node.find('.recipient-value').removeClass('selected');
-      };
-
-      this.isSelected = function () {
-        return this.$node.find('.recipient-value').hasClass('selected');
-      };
-
-      this.sinalizeInvalid = function () {
-        this.$node.find('.recipient-value>span').addClass('invalid-format');
-      };
-
-      this.discoverEncryption = function () {
-        this.$node.addClass('discover-encryption');
-        var p = $.getJSON('/keys?search=' + this.attr.address).promise();
-        p.done(function () {
-          this.$node.find('.recipient-value').addClass('encrypted');
-          this.$node.removeClass('discover-encryption');
-        }.bind(this));
-          p.fail(function () {
-            this.$node.find('.recipient-value').addClass('not-encrypted');
-            this.$node.removeClass('discover-encryption');
-        }.bind(this));
-      };
-
-      this.getMailAddress = function() {
-        return this.$node.find('input[type=hidden]').val();
-      };
-
-      this.triggerEditRecipient = function(event, element) {
-        this.trigger(this.$node.closest('.recipients-area'), events.ui.recipients.clickToEdit, this);
-      };
-
-      this.after('initialize', function () {
-        this.recipientDelActions();
-        this.on('click', this.triggerEditRecipient);
-        
-        if (this.attr.invalidAddress){
-            this.sinalizeInvalid();
-        } else {
-            this.discoverEncryption();
-        }
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_view/ui/recipients/recipients.js b/web-ui/app/js/mail_view/ui/recipients/recipients.js
deleted file mode 100644
index 2caa8d14..00000000
--- a/web-ui/app/js/mail_view/ui/recipients/recipients.js
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-  [
-    'flight/lib/component',
-    'views/templates',
-    'page/events',
-    'helpers/iterator',
-    'mail_view/ui/recipients/recipients_input',
-    'mail_view/ui/recipients/recipient',
-    'mail_view/ui/recipients/recipients_iterator'
-  ],
-  function (defineComponent, templates, events, Iterator, RecipientsInput, Recipient, RecipientsIterator) {
-    'use strict';
-
-    return defineComponent(recipients);
-
-    function recipients() {
-      this.defaultAttrs({
-        navigationHandler: '.recipients-navigation-handler',
-        recipientsList: '.recipients-list'
-      });
-
-      function getAddresses(recipients) {
-        return _.flatten(_.map(recipients, function (e) { return e.attr.address;}));
-      }
-
-      function moveLeft() { this.attr.iterator.moveLeft(); }
-      function moveRight() { this.attr.iterator.moveRight(); }
-      function deleteCurrentRecipient() {
-        this.attr.iterator.deleteCurrent();
-        this.addressesUpdated();
-      }
-
-      function editCurrentRecipient(event, recipient) {
-        var mailAddr = this.attr.iterator.current().getMailAddress();
-        this.attr.iterator.deleteCurrent();
-        this.attr.input.$node.val(mailAddr).focus();
-        this.unselectAllRecipients();
-        this.addressesUpdated();
-      }
-
-      this.clickToEditRecipient = function(event, recipient) {
-        this.attr.iterator = null;
-        var mailAddr = recipient.getMailAddress();
-
-        var position = this.getRecipientPosition(recipient);
-        this.attr.recipients.splice(position, 1);
-        recipient.destroy();
-
-        this.addressesUpdated();
-        this.unselectAllRecipients();
-        this.attr.input.$node.val(mailAddr).focus();
-      };
-
-      this.getRecipientPosition = function(recipient) {
-        return recipient.$node.closest('.recipients-area').find('.fixed-recipient').index(recipient.$node);
-      };
-
-      this.unselectAllRecipients = function() {
-        this.$node.find('.recipient-value.selected').removeClass('selected');
-      };
-
-      var SPECIAL_KEYS_ACTIONS = {
-        8: deleteCurrentRecipient,
-        46: deleteCurrentRecipient,
-        32: editCurrentRecipient,
-        13: editCurrentRecipient,
-        37: moveLeft,
-        39: moveRight
-      };
-
-      this.addRecipient = function(recipient) {
-        var newRecipient = Recipient.prototype.renderAndPrepend(this.$node.find(this.attr.recipientsList), recipient);
-        this.attr.recipients.push(newRecipient);
-      };
-
-      this.recipientEntered = function (event, recipient) {
-        this.addRecipient(recipient);
-        this.addressesUpdated();
-      };
-
-      this.invalidRecipientEntered = function(event, recipient) {
-        recipient.invalidAddress = true;
-        this.addRecipient(recipient);
-      };
-
-      this.deleteRecipient = function (event, recipient) {
-        this.attr.iterator = null;
-        var position = this.getRecipientPosition(recipient);
-
-        this.attr.recipients.splice(position, 1);
-        recipient.destroy();
-
-        this.addressesUpdated();
-      };
-
-      this.deleteLastRecipient = function () {
-        this.attr.recipients.pop().destroy();
-        this.addressesUpdated();
-      };
-
-      this.enterNavigationMode = function () {
-        this.attr.iterator = new RecipientsIterator({
-          elements: this.attr.recipients,
-          exitInput: this.attr.input.$node
-        });
-
-        this.attr.iterator.current().doSelect();
-        this.attr.input.$node.blur();
-        this.select('navigationHandler').focus();
-      };
-
-      this.leaveNavigationMode = function () {
-        if(this.attr.iterator) { this.attr.iterator.current().unselect(); }
-        this.attr.iterator = null;
-      };
-
-      this.selectLastRecipient = function () {
-        if (this.attr.recipients.length === 0) { return; }
-        this.enterNavigationMode();
-      };
-
-      this.attachInput = function () {
-        this.attr.input = RecipientsInput.prototype.attachAndReturn(this.$node.find('input[type=text]'), this.attr.name);
-      };
-
-      this.processSpecialKey = function (event) {
-        if(SPECIAL_KEYS_ACTIONS.hasOwnProperty(event.which)) { SPECIAL_KEYS_ACTIONS[event.which].apply(this); }
-      };
-
-      this.initializeAddresses = function () {
-        _.each(_.flatten(this.attr.addresses), function (address) {
-          this.addRecipient({ address: address, name: this.attr.name });
-        }.bind(this));
-      };
-
-      this.addressesUpdated = function() {
-        this.trigger(document, events.ui.recipients.updated, {recipientsName: this.attr.name, newRecipients: getAddresses(this.attr.recipients)});
-      };
-
-      this.doCompleteRecipients = function () {
-        var address = this.attr.input.$node.val();
-        if (!_.isEmpty(address)) {
-          var recipient = Recipient.prototype.renderAndPrepend(this.$node, { name: this.attr.name, address: address });
-          this.attr.recipients.push(recipient);
-          this.attr.input.$node.val('');
-        }
-
-        this.trigger(document, events.ui.recipients.updated, {
-          recipientsName: this.attr.name,
-          newRecipients: getAddresses(this.attr.recipients),
-          skipSaveDraft: true
-        });
-
-      };
-
-      this.after('initialize', function () {
-        this.attr.recipients = [];
-        this.attachInput();
-        this.initializeAddresses();
-
-        this.on(events.ui.recipients.deleteRecipient, this.deleteRecipient);
-        this.on(events.ui.recipients.deleteLast, this.deleteLastRecipient);
-        this.on(events.ui.recipients.selectLast, this.selectLastRecipient);
-        this.on(events.ui.recipients.entered, this.recipientEntered);
-        this.on(events.ui.recipients.enteredInvalid, this.invalidRecipientEntered);
-        this.on(events.ui.recipients.clickToEdit, this.clickToEditRecipient);
-
-        this.on(document, events.ui.recipients.doCompleteInput, this.doCompleteRecipients);
-
-        this.on(this.attr.input.$node, 'focus', this.leaveNavigationMode);
-        this.on(this.select('navigationHandler'), 'keydown', this.processSpecialKey);
-
-        this.on(document, events.dispatchers.rightPane.clear, this.teardown);
-      });
-    }
-  });
diff --git a/web-ui/app/js/mail_view/ui/recipients/recipients_input.js b/web-ui/app/js/mail_view/ui/recipients/recipients_input.js
deleted file mode 100644
index 8a9c4eaf..00000000
--- a/web-ui/app/js/mail_view/ui/recipients/recipients_input.js
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define([
-    'flight/lib/component',
-    'page/events',
-    'features'
-  ],
-  function (defineComponent, events, features) {
-    'use strict';
-
-    function recipientsInput() {
-      var EXIT_KEY_CODE_MAP = {
-          8: 'backspace',
-          37: 'left'
-        },
-        ENTER_ADDRESS_KEY_CODE_MAP = {
-          9: 'tab',
-          186: 'semicolon',
-          188: 'comma',
-          13: 'enter',
-          27: 'esc'
-        },
-        EVENT_FOR = {
-          8: events.ui.recipients.deleteLast,
-          37: events.ui.recipients.selectLast
-        },
-        self;
-
-      var simpleAddressMatch = /[^<\w,;]?([^\s<;,]+@[\w-]+\.[^\s>;,]+)/;
-      var canonicalAddressMatch = /([^,;\s][^,;@]+<[^\s;,]+@[\w-]+\.[^\s;,]+>)/;
-      var emailAddressMatch = new RegExp([simpleAddressMatch.source, '|', canonicalAddressMatch.source].join(''), 'g');
-
-      var extractContactNames = function (response) {
-          return _.map(response, function(a) { return { value: a }; });
-      };
-
-      function createEmailCompleter() {
-        var emailCompleter = new Bloodhound({
-          datumTokenizer: function (d) {
-            return [d.value];
-          },
-          queryTokenizer: function (q) {
-            return [q.trim()];
-          },
-          remote: {
-            url: '/contacts?q=%QUERY',
-            filter: extractContactNames
-          }
-        });
-        emailCompleter.initialize();
-        return emailCompleter;
-      }
-
-      function reset(node) {
-        node.typeahead('val', '');
-      }
-
-      function caretIsInTheBeginningOfInput(input) {
-        return input.selectionStart === 0;
-      }
-
-      function isExitKey(keyPressed) {
-        return EXIT_KEY_CODE_MAP.hasOwnProperty(keyPressed);
-      }
-
-      function isEnterAddressKey(keyPressed) {
-        return ENTER_ADDRESS_KEY_CODE_MAP.hasOwnProperty(keyPressed);
-      }
-
-      this.processSpecialKey = function (event) {
-        var keyPressed = event.which;
-
-        if (isExitKey(keyPressed) && caretIsInTheBeginningOfInput(this.$node[0])) {
-          this.trigger(EVENT_FOR[keyPressed]);
-          return;
-        }
-
-        if (!event.shiftKey && isEnterAddressKey(keyPressed)) {
-          this.tokenizeRecipient(event);
-
-          if ((keyPressed !== 9 /* tab */)) {
-            event.preventDefault();
-          }
-        }
-
-      };
-
-      this.tokenizeRecipient = function (event) {
-        if (_.isEmpty(this.$node.val().trim())) {
-          return;
-        }
-
-        this.recipientSelected(null, {value: this.$node.val() });
-        event.preventDefault();
-      };
-
-      this.recipientSelected = function (event, data) {
-        var value = (data && data.value) || this.$node.val();
-
-        var validAddresses = this.extractValidAddresses(value);
-        var invalidAddresses = this.extractInvalidAddresses(value);
-
-        this.triggerEventForEach(validAddresses, events.ui.recipients.entered);
-        this.triggerEventForEach(invalidAddresses, events.ui.recipients.enteredInvalid);
-
-        reset(this.$node);
-      };
-
-     this.triggerEventForEach = function (addresses, event) {
-       var that = this;
-       _.each(addresses, function(address) {
-         if (!_.isEmpty(address.trim())) {
-           that.trigger(that.$node, event, { name: that.attr.name, address: address.trim() });
-         }
-       });
-     };
-
-     this.extractValidAddresses = function(rawAddresses) {
-        return rawAddresses.match(emailAddressMatch);
-      };
-
-      this.extractInvalidAddresses = function(rawAddresses) {
-        return rawAddresses.replace(emailAddressMatch, '').split(/[,;]/);
-      };
-
-      this.init = function () {
-        this.$node.typeahead({
-          hint: true,
-          highlight: true,
-          minLength: 1
-        }, {
-          source: createEmailCompleter().ttAdapter(),
-          templates: {
-              suggestion: function (o) { return _.escape(o.value); }
-          }
-        });
-      };
-
-      this.attachAndReturn = function (node, name) {
-        var input = new this.constructor();
-        input.initialize(node, { name: name});
-        return input;
-      };
-
-      this.warnSendButtonOfInputState = function () {
-        var toTrigger = _.isEmpty(this.$node.val()) ? events.ui.recipients.inputFieldIsEmpty : events.ui.recipients.inputFieldHasCharacters;
-        this.trigger(document, toTrigger, { name: this.attr.name });
-      };
-
-      this.after('initialize', function () {
-        self = this;
-        this.init();
-        this.on('typeahead:selected typeahead:autocompleted', this.recipientSelected);
-        this.on(this.$node, 'focusout', this.tokenizeRecipient);
-        this.on(this.$node, 'keydown', this.processSpecialKey);
-        this.on(this.$node, 'keyup', this.warnSendButtonOfInputState);
-
-        this.on(document, events.dispatchers.rightPane.clear, this.teardown);
-      });
-    }
-
-    return defineComponent(recipientsInput);
-
-  }
-);
diff --git a/web-ui/app/js/mail_view/ui/recipients/recipients_iterator.js b/web-ui/app/js/mail_view/ui/recipients/recipients_iterator.js
deleted file mode 100644
index 624ac4f5..00000000
--- a/web-ui/app/js/mail_view/ui/recipients/recipients_iterator.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(['helpers/iterator'], function (Iterator) {
-  'use strict';
-
-  return RecipientsIterator;
-
-  function RecipientsIterator(options) {
-
-    this.iterator = new Iterator(options.elements, options.elements.length - 1);
-    this.input = options.exitInput;
-
-    this.current = function () {
-      return this.iterator.current();
-    };
-
-    this.moveLeft = function () {
-      if (this.iterator.hasPrevious()) {
-        this.iterator.current().doUnselect();
-        this.iterator.previous().doSelect();
-      }
-    };
-
-    this.moveRight = function () {
-      this.iterator.current().doUnselect();
-      if (this.iterator.hasNext()) {
-        this.iterator.next().doSelect();
-      } else {
-        this.input.focus();
-      }
-    };
-
-    this.deleteCurrent = function () {
-      this.iterator.removeCurrent().destroy();
-
-      if (this.iterator.hasElements()) {
-        this.iterator.current().doSelect();
-      } else {
-        this.input.focus();
-      }
-    };
-  }
-
-});
diff --git a/web-ui/app/js/mail_view/ui/reply_box.js b/web-ui/app/js/mail_view/ui/reply_box.js
deleted file mode 100644
index a174d185..00000000
--- a/web-ui/app/js/mail_view/ui/reply_box.js
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-  [
-    'flight/lib/component',
-    'helpers/view_helper',
-    'mixins/with_hide_and_show',
-    'mixins/with_compose_inline',
-    'page/events',
-    'views/i18n'
-  ],
-
-  function (defineComponent, viewHelper, withHideAndShow, withComposeInline, events, i18n) {
-    'use strict';
-
-    return defineComponent(replyBox, withHideAndShow, withComposeInline);
-
-    function replyBox() {
-      this.defaultAttrs({
-        replyType: 'reply',
-        draftReply: false,
-        mail: null,
-        mailBeingRepliedIdent: undefined
-      });
-
-      this.getRecipients = function() {
-        if (this.attr.replyType === 'replyall') {
-          return this.attr.mail.replyToAllAddress();
-        } else {
-          return this.attr.mail.replyToAddress();
-        }
-      };
-
-      var re = function(v) { return i18n.t('re') + ': ' + v; };
-
-      this.setupReplyBox = function() {
-        var recipients, body;
-
-        if (this.attr.draftReply){
-          this.attr.ident = this.attr.mail.ident;
-          this.attr.mailBeingRepliedIdent = this.attr.mail.draft_reply_for;
-
-          recipients = this.attr.mail.recipients();
-          body = this.attr.mail.body;
-          this.attr.subject = this.attr.mail.header.subject;
-        } else {
-          this.attr.mailBeingRepliedIdent = this.attr.mail.ident;
-          recipients = this.getRecipients();
-          body = viewHelper.quoteMail(this.attr.mail);
-          this.attr.subject = re(this.attr.mail.header.subject);
-        }
-
-        this.attr.recipientValues.to = recipients.to;
-        this.attr.recipientValues.cc = recipients.cc;
-
-        this.renderInlineCompose('reply-box', {
-          recipients: recipients,
-          subject: this.attr.subject,
-          body: body
-        });
-
-        this.on(this.select('recipientsDisplay'), 'click keydown', this.showRecipientFields);
-        this.on(this.select('subjectDisplay'), 'click', this.showSubjectInput);
-      };
-
-      this.showRecipientFields = function(ev, data) {
-        if(!ev.keyCode || ev.keyCode === 13){
-          this.select('recipientsDisplay').hide();
-          this.select('recipientsFields').show();
-          $('#recipients-to-area .tt-input').focus();
-        }
-      };
-
-      this.showSubjectInput = function() {
-        this.select('subjectDisplay').hide();
-        this.select('subjectInput').show();
-        this.select('subjectInput').focus();
-      };
-
-      this.buildMail = function(tag) {
-        var builder = this.builtMail(tag).subject(this.select('subjectInput').val());
-        if(!_.isUndefined(this.attr.mail.header.message_id)) {
-          builder.header('in_reply_to', this.attr.mail.header.message_id);
-        }
-
-        if(!_.isUndefined(this.attr.mail.header.list_id)) {
-          builder.header('list_id', this.attr.mail.header.list_id);
-        }
-
-        var mail = builder.build();
-        mail.setDraftReplyFor(this.attr.mailBeingRepliedIdent);
-
-        return mail;
-      };
-
-      this.after('initialize', function () {
-        this.setupReplyBox();
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_view/ui/reply_section.js b/web-ui/app/js/mail_view/ui/reply_section.js
deleted file mode 100644
index cbe64205..00000000
--- a/web-ui/app/js/mail_view/ui/reply_section.js
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'views/templates',
-    'mail_view/ui/reply_box',
-    'mail_view/ui/forward_box',
-    'mixins/with_hide_and_show',
-    'mixins/with_feature_toggle',
-    'page/events'
-  ],
-
-  function (defineComponent, templates, ReplyBox, ForwardBox, withHideAndShow, withFeatureToggle, events) {
-    'use strict';
-
-    return defineComponent(replySection, withHideAndShow, withFeatureToggle('replySection'));
-
-    function replySection() {
-      this.defaultAttrs({
-        replyButton: '#reply-button',
-        replyAllButton: '#reply-all-button',
-        forwardButton: '#forward-button',
-        replyBox: '#reply-box',
-        replyType: 'reply',
-        replyContainer: '.reply-container'
-      });
-
-      this.showReply = function() {
-        this.attr.replyType = 'reply';
-        this.fetchEmailToReplyTo();
-      };
-
-      this.showReplyAll = function() {
-        this.attr.replyType = 'replyall';
-        this.fetchEmailToReplyTo();
-      };
-
-      this.showForward = function() {
-        this.attr.replyType = 'forward';
-        this.fetchEmailToReplyTo();
-      };
-
-      this.render = function () {
-        this.$node.html(templates.compose.replySection);
-
-        this.on(this.select('replyButton'), 'click', this.showReply);
-        this.on(this.select('replyAllButton'), 'click', this.showReplyAll);
-        this.on(this.select('forwardButton'), 'click', this.showForward);
-      };
-
-      this.checkForDraftReply = function() {
-        this.render();
-        this.hideContainer();
-
-        this.trigger(document, events.mail.draftReply.want, {ident: this.attr.ident});
-      };
-
-      this.fetchEmailToReplyTo = function (ev) {
-        this.trigger(document, events.mail.want, { mail: this.attr.ident, caller: this });
-      };
-
-      this.showDraftReply = function(ev, data) {
-        this.showContainer();
-        this.hideButtons();
-        ReplyBox.attachTo(this.select('replyBox'), { mail: data.mail, draftReply: true });
-      };
-
-      this.showReplyComposeBox = function (ev, data) {
-        this.showContainer();
-        this.hideButtons();
-        if(this.attr.replyType === 'forward') {
-          ForwardBox.attachTo(this.select('replyBox'), { mail: data.mail });
-        } else {
-          ReplyBox.attachTo(this.select('replyBox'), { mail: data.mail, replyType: this.attr.replyType });
-        }
-      };
-
-      this.hideContainer = function() {
-        this.select('replyContainer').hide();
-      };
-
-      this.showContainer = function() {
-        this.select('replyContainer').show();
-      };
-
-      this.hideButtons = function() {
-        this.select('replyButton').hide();
-        this.select('replyAllButton').hide();
-        this.select('forwardButton').hide();
-      };
-
-      this.showButtons = function () {
-        this.showContainer();
-        this.select('replyBox').empty();
-        this.select('replyButton').show();
-        this.select('replyAllButton').show();
-        this.select('forwardButton').show();
-      };
-
-      this.after('initialize', function () {
-        this.on(document, events.ui.replyBox.showReply, this.showReply);
-        this.on(document, events.ui.replyBox.showReplyAll, this.showReplyAll);
-        this.on(document, events.ui.composeBox.trashReply, this.showButtons);
-        this.on(this, events.mail.here, this.showReplyComposeBox);
-        this.on(document, events.dispatchers.rightPane.clear, this.teardown);
-
-        this.on(document, events.ui.replyBox.showReplyContainer, this.showContainer);
-        this.on(document, events.mail.draftReply.here, this.showDraftReply);
-
-        this.checkForDraftReply();
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/mail_view/ui/send_button.js b/web-ui/app/js/mail_view/ui/send_button.js
deleted file mode 100644
index 66fe1233..00000000
--- a/web-ui/app/js/mail_view/ui/send_button.js
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define([
-    'flight/lib/component',
-    'flight/lib/utils',
-    'page/events',
-    'helpers/view_helper'
-  ],
-  function (defineComponent, utils, events, viewHelper) {
-    'use strict';
-
-    return defineComponent(sendButton);
-
-    function sendButton() {
-      var RECIPIENTS_BOXES_COUNT = 3;
-
-      this.enableButton = function () {
-        this.$node.prop('disabled', false);
-      };
-
-      this.disableButton = function () {
-        this.$node.prop('disabled', true);
-      };
-
-      this.atLeastOneInputFieldHasRecipients = function () {
-        return _.any(_.values(this.attr.recipients), function (e) { return !_.isEmpty(e); });
-      };
-
-      this.atLeastOneInputFieldHasCharacters = function () {
-        return _.any(_.values(this.attr.inputFieldHasCharacters), function (e) { return e === true; });
-      };
-
-      this.updateButton = function () {
-        if (this.attr.sendingInProgress === false) {
-          if (this.attr.uploading === false && (this.atLeastOneInputFieldHasCharacters() || this.atLeastOneInputFieldHasRecipients())) {
-            this.enableButton();
-          } else {
-            this.disableButton();
-          }
-        }
-      };
-
-      this.inputFieldIsEmpty = function (ev, data) {
-        this.attr.inputFieldHasCharacters[data.name] = false;
-        this.updateButton();
-      };
-
-      this.inputFieldHasCharacters = function (ev, data) {
-        this.attr.inputFieldHasCharacters[data.name] = true;
-        this.updateButton();
-      };
-
-      this.uploadInProgress = function (ev, data) {
-        this.attr.uploading = true;
-        this.updateButton();
-      };
-
-      this.uploadFinished = function (ev, data) {
-        this.attr.uploading = false;
-        this.updateButton();
-      };
-
-      this.updateRecipientsForField = function (ev, data) {
-        this.attr.recipients[data.recipientsName] = data.newRecipients;
-        this.attr.inputFieldHasCharacters[data.recipientsName] = false;
-
-        this.updateButton();
-      };
-
-      this.updateRecipientsAndSendMail = function () {
-
-        this.on(document, events.ui.mail.recipientsUpdated, utils.countThen(RECIPIENTS_BOXES_COUNT, function () {
-          this.trigger(document, events.ui.mail.send);
-          this.off(document, events.ui.mail.recipientsUpdated);
-        }.bind(this)));
-
-        this.disableButton();
-        this.$node.text(viewHelper.i18n.t('sending-mail'));
-
-        this.attr.sendingInProgress = true;
-
-        this.trigger(document, events.ui.recipients.doCompleteInput);
-      };
-
-      this.resetButton = function () {
-        this.attr.sendingInProgress = false;
-        this.attr.uploading = false;
-        this.$node.html(viewHelper.i18n.t('send'));
-        this.enableButton();
-      };
-
-      this.after('initialize', function () {
-        this.attr.recipients = {};
-        this.attr.inputFieldHasCharacters = {};
-        this.resetButton();
-
-        this.on(document, events.ui.recipients.inputFieldHasCharacters, this.inputFieldHasCharacters);
-        this.on(document, events.ui.recipients.inputFieldIsEmpty, this.inputFieldIsEmpty);
-        this.on(document, events.ui.recipients.updated, this.updateRecipientsForField);
-
-        this.on(this.$node, 'click', this.updateRecipientsAndSendMail);
-
-        this.on(document, events.mail.uploadingAttachment, this.uploadInProgress);
-        this.on(document, events.mail.uploadedAttachment, this.uploadFinished);
-        this.on(document, events.mail.failedUploadAttachment, this.uploadFinished);
-
-        this.on(document, events.dispatchers.rightPane.clear, this.teardown);
-        this.on(document, events.ui.sendbutton.enable, this.resetButton);
-        this.on(document, events.mail.send_failed, this.resetButton);
-
-        this.disableButton();
-      });
-    }
-
-  }
-);
diff --git a/web-ui/app/js/main.js b/web-ui/app/js/main.js
deleted file mode 100644
index b8836a6b..00000000
--- a/web-ui/app/js/main.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-requirejs.config({
-  baseUrl: '../assets/',
-  paths: {
-    'mail_list': 'js/mail_list',
-    'page': 'js/page',
-    'feedback': 'js/feedback',
-    'flight': 'bower_components/flight',
-    'DOMPurify': 'bower_components/DOMPurify/dist/purify.min',
-    'he': 'bower_components/he/he',
-    'hbs': 'js/generated/hbs',
-    'helpers': 'js/helpers',
-    'lib': 'js/lib',
-    'views': 'js/views',
-    'tags': 'js/tags',
-    'mail_list_actions': 'js/mail_list_actions',
-    'user_alerts': 'js/user_alerts',
-    'mail_view': 'js/mail_view',
-    'dispatchers': 'js/dispatchers',
-    'services': 'js/services',
-    'mixins': 'js/mixins',
-    'search': 'js/search',
-    'foundation': 'js/foundation',
-    'features': 'js/features/features',
-    'i18next': 'bower_components/i18next/i18next',
-    'i18nextXHRBackend': 'bower_components/i18next-xhr-backend/i18nextXHRBackend',
-    'i18nextBrowserLanguageDetector': 'bower_components/i18next-browser-languagedetector/i18nextBrowserLanguageDetector',
-    'quoted-printable': 'bower_components/quoted-printable',
-    'utf8': 'bower_components/utf8',
-    'user_settings': 'js/user_settings'
-  }
-});
-
-require([
-  'flight/lib/compose',
-  'flight/lib/debug'
-], function(compose, debug){
-  'use strict';
-  debug.enable(true);
-  debug.events.logAll();
-});
-
-require(
-  [
-    'flight/lib/compose',
-    'flight/lib/registry',
-    'flight/lib/advice',
-    'flight/lib/logger',
-    'flight/lib/debug',
-    'page/events',
-    'page/default',
-    'js/monkey_patching/all'
-  ],
-
-  function(compose, registry, advice, withLogging, debug, events, initializeDefault, _monkeyPatched) {
-    'use strict';
-
-    window.Pixelated = window.Pixelated || {};
-    window.Pixelated.events = events;
-
-    compose.mixin(registry, [advice.withAdvice, withLogging]);
-
-    debug.enable(true);
-    debug.events.logAll();
-
-    initializeDefault('');
-  }
-);
diff --git a/web-ui/app/js/mixins/with_auto_refresh.js b/web-ui/app/js/mixins/with_auto_refresh.js
deleted file mode 100644
index c75fda45..00000000
--- a/web-ui/app/js/mixins/with_auto_refresh.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(['features'],
-  function (features) {
-    'use strict';
-
-    function withAutoRefresh(refreshMethod) {
-      return function () {
-        this.defaultAttrs({
-          refreshInterval: 15000
-        });
-
-        this.setupRefresher = function () {
-          clearTimeout(this.attr.refreshTimer);
-          this.attr.refreshTimer = setTimeout(function () {
-            this[refreshMethod]();
-            this.setupRefresher();
-          }.bind(this), this.attr.refreshInterval);
-        };
-
-        this.after('initialize', function () {
-          if (features.isAutoRefreshEnabled()) {
-            this.setupRefresher();
-          }
-        });
-      };
-    }
-
-    return withAutoRefresh;
-  }
-);
-
diff --git a/web-ui/app/js/mixins/with_compose_inline.js b/web-ui/app/js/mixins/with_compose_inline.js
deleted file mode 100644
index b8266f28..00000000
--- a/web-ui/app/js/mixins/with_compose_inline.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-  [
-    'page/events',
-    'views/templates',
-    'mail_view/data/mail_builder',
-    'mixins/with_mail_edit_base'
-  ],
-  function(events, templates, mailBuilder, withMailEditBase) {
-    'use strict';
-
-    function withComposeInline() {
-      this.defaultAttrs({
-        subjectDisplay: '#reply-subject',
-        subjectInput: '#subject-container input',
-        forwardBox: '#forward-box',
-        recipientsDisplay: '#all-recipients'
-      });
-
-      this.openMail = function(ev, data) {
-        this.trigger(document, events.ui.mail.open, {ident: this.attr.mail.ident});
-      };
-
-      this.trashReply = function() {
-        this.trigger(document, events.ui.composeBox.trashReply);
-        this.teardown();
-      };
-
-      this.builtMail = function(tag) {
-        return mailBuilder.newMail(this.attr.ident)
-          .subject(this.select('subjectBox').val())
-          .to(this.attr.recipientValues.to)
-          .cc(this.attr.recipientValues.cc)
-          .bcc(this.attr.recipientValues.bcc)
-          .body(this.select('bodyBox').val())
-          .attachment(this.attr.attachments)
-          .tag(tag);
-      };
-
-      this.renderInlineCompose = function(className, viewData) {
-        this.show();
-        this.render(templates.compose.inlineBox, viewData);
-
-        this.$node.addClass(className);
-        this.select('bodyBox').focus();
-
-        this.enableAutoSave();
-      };
-
-      this.updateIdent = function(ev, data) {
-        this.attr.mail.ident = data.ident;
-      };
-
-      this.discardDraft = function() {
-        this.trashReply();
-      };
-
-      this.after('initialize', function () {
-        this.on(document, events.mail.sent, this.openMail);
-        this.on(document, events.mail.deleted, this.trashReply);
-        this.on(document, events.mail.draftSaved, this.updateIdent);
-      });
-
-      withMailEditBase.call(this);
-    }
-
-    return withComposeInline;
-  });
diff --git a/web-ui/app/js/mixins/with_enable_disable_on_event.js b/web-ui/app/js/mixins/with_enable_disable_on_event.js
deleted file mode 100644
index 5b28a67b..00000000
--- a/web-ui/app/js/mixins/with_enable_disable_on_event.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define([],
-  function () {
-    'use strict';
-
-    function withEnableDisableOnEvent(ev) {
-      return function () {
-        this.disableElement = function () {
-          this.$node.attr('disabled', 'disabled');
-        };
-
-        this.enableElement = function () {
-          this.$node.removeAttr('disabled');
-        };
-
-        this.toggleEnabled = function (ev, enable) {
-          if (enable) {
-            this.enableElement();
-          } else {
-            this.disableElement();
-          }
-        };
-
-        this.after('initialize', function () {
-          this.on(document, ev, this.toggleEnabled);
-        });
-      };
-    }
-
-    return withEnableDisableOnEvent;
-  }
-);
diff --git a/web-ui/app/js/mixins/with_feature_toggle.js b/web-ui/app/js/mixins/with_feature_toggle.js
deleted file mode 100644
index 195b08bc..00000000
--- a/web-ui/app/js/mixins/with_feature_toggle.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(['features'],
-  function(features) {
-  'use strict';
-
-    function withFeatureToggle(componentName, behaviorForFeatureOff) {
-      return function() {
-
-        this.around('initialize', _.bind(function(basicInitialize, node, attrs) {
-          if(features.isEnabled(componentName)) {
-            return basicInitialize(node, attrs);
-          }
-          else if (behaviorForFeatureOff){
-            behaviorForFeatureOff.call(this);
-
-            return this;
-          }
-        }, this));
-      };
-    }
-
-    return withFeatureToggle;
-
-});
diff --git a/web-ui/app/js/mixins/with_hide_and_show.js b/web-ui/app/js/mixins/with_hide_and_show.js
deleted file mode 100644
index c8902f61..00000000
--- a/web-ui/app/js/mixins/with_hide_and_show.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(function(require) {
-  'use strict';
-
-  function withHideAndShow() {
-    this.hide = function () {
-      this.$node.hide();
-    };
-    this.show = function () {
-      this.$node.show();
-    };
-  }
-
-  return withHideAndShow;
-
-});
diff --git a/web-ui/app/js/mixins/with_mail_edit_base.js b/web-ui/app/js/mixins/with_mail_edit_base.js
deleted file mode 100644
index a088080e..00000000
--- a/web-ui/app/js/mixins/with_mail_edit_base.js
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-    [
-        'flight/lib/compose',
-        'helpers/view_helper',
-        'mail_view/ui/recipients/recipients',
-        'mail_view/ui/draft_save_status',
-        'page/events',
-        'views/i18n',
-        'mail_view/ui/send_button',
-        'mail_view/ui/attachment_icon',
-        'mail_view/ui/attachment_list',
-        'flight/lib/utils'
-    ],
-    function (compose, viewHelper, Recipients, DraftSaveStatus, events, i18n, SendButton, AttachmentIcon, attachmentList, utils) {
-        'use strict';
-
-        function withMailEditBase() {
-
-            this.defaultAttrs({
-                bodyBox: '#text-box',
-                sendButton: '#send-button',
-                attachmentButton: '#attachment-button',
-                attachmentList: '#attachment-list',
-                cancelButton: '#cancel-button',
-                trashButton: '#trash-button',
-                toArea: '#recipients-to-area',
-                toBox: '#recipients-to-box',
-                ccArea: '#recipients-cc-area',
-                bccArea: '#recipients-bcc-area',
-                ccsTrigger: '#ccs-trigger',
-                bccsTrigger: '#bccs-trigger',
-                toTrigger: '#to-trigger',
-                subjectBox: '#subject',
-                tipMsg: '.tip-msg',
-                draftSaveStatus: '#draft-save-status',
-                recipientsFields: '#recipients-fields',
-                currentTag: '',
-                recipientValues: {to: [], cc: [], bcc: []},
-                saveDraftInterval: 3000
-            });
-
-            this.attachRecipients = function (context) {
-                Recipients.attachTo(this.select('toArea'), {name: 'to', addresses: context.recipients.to});
-                Recipients.attachTo(this.select('ccArea'), {name: 'cc', addresses: context.recipients.cc || []});
-                Recipients.attachTo(this.select('bccArea'), {name: 'bcc', addresses: context.recipients.bcc || []});
-            };
-
-            function thereAreRecipientsToDisplay() {
-
-                var allRecipients = _.chain(this.attr.recipientValues).
-                values().
-                flatten().
-                remove(undefined).
-                value();
-
-                return !_.isEmpty(allRecipients);
-            }
-
-            this.warnSendButtonOfRecipients = function () {
-                if (thereAreRecipientsToDisplay.call(this)) {
-                    _.forOwn(this.attr.recipientValues, function (recipients, recipientsType) {
-                        if (!_.isUndefined(recipients) && !_.isEmpty(recipients)) {
-                            var recipientsUpdatedData = {
-                                newRecipients: recipients,
-                                recipientsName: recipientsType
-                            };
-                            this.trigger(document, events.ui.recipients.updated, recipientsUpdatedData);
-                        }
-                    }.bind(this));
-                }
-            };
-
-            this.render = function (template, context) {
-                this.$node.html(template(context));
-
-                if (!context || _.isEmpty(context)) {
-                    context.recipients = {to: [], cc: [], bcc: []};
-                }
-                this.attr.recipientValues = context.recipients;
-                this.attr.attachments = context.attachments || [];
-                this.attachRecipients(context);
-
-                this.on(this.select('trashButton'), 'click', this.discardMail);
-                SendButton.attachTo(this.select('sendButton'));
-                AttachmentIcon.attachTo(this.select('attachmentButton'));
-
-                this.warnSendButtonOfRecipients();
-            };
-
-            this.enableAutoSave = function () {
-                this.select('bodyBox').on('input', this.monitorInput.bind(this));
-                this.select('subjectBox').on('input', this.monitorInput.bind(this));
-                this.on(document, events.mail.appendAttachment, this.monitorInput.bind(this));
-                this.on(document, events.mail.removeAttachment, this.monitorInput.bind(this));
-                DraftSaveStatus.attachTo(this.select('draftSaveStatus'));
-            };
-
-            this.monitorInput = function () {
-                this.trigger(events.ui.mail.changedSinceLastSave);
-                this.cancelPostponedSaveDraft();
-                var mail = this.buildMail();
-                this.postponeSaveDraft(mail);
-            };
-
-            this.discardMail = function () {
-                this.cancelPostponedSaveDraft();
-                if (this.attr.ident) {
-                    var mail = this.buildMail();
-                    this.trigger(document, events.ui.mail.delete, {mail: mail});
-                } else {
-                    this.trigger(document, events.ui.mail.discard);
-                }
-            };
-
-            this.trim_recipient = function (recipients) {
-                return recipients.map(function (recipient) {
-                    return recipient.trim();
-                });
-            };
-
-            this.sendMail = function () {
-                this.cancelPostponedSaveDraft();
-                var mail = this.buildMail('sent');
-
-                if (allRecipientsAreEmails(mail)) {
-                    mail.header.to = this.trim_recipient(mail.header.to);
-                    mail.header.cc = this.trim_recipient(mail.header.cc);
-                    mail.header.bcc = this.trim_recipient(mail.header.bcc);
-                    this.trigger(events.mail.send, mail);
-                } else {
-                    this.trigger(
-                        events.ui.userAlerts.displayMessage,
-                        {message: i18n.t('recipients-not-valid')}
-                    );
-                    this.trigger(events.mail.send_failed);
-                }
-            };
-
-            this.buildAndSaveDraft = function () {
-                var mail = this.buildMail();
-                this.saveDraft(mail);
-            };
-
-            this.recipientsUpdated = function (ev, data) {
-                this.attr.recipientValues[data.recipientsName] = data.newRecipients;
-                this.trigger(document, events.ui.mail.recipientsUpdated);
-                if (data.skipSaveDraft) {
-                    return;
-                }
-
-                var mail = this.buildMail();
-                this.postponeSaveDraft(mail);
-            };
-
-            this.saveDraft = function (mail) {
-                this.cancelPostponedSaveDraft();
-                this.trigger(document, events.mail.saveDraft, mail);
-            };
-
-            this.cancelPostponedSaveDraft = function () {
-                clearTimeout(this.attr.timeout);
-            };
-
-            this.postponeSaveDraft = function (mail) {
-                this.cancelPostponedSaveDraft();
-
-                this.attr.timeout = window.setTimeout(_.bind(function () {
-                    this.saveDraft(mail);
-                }, this), this.attr.saveDraftInterval);
-            };
-
-            this.draftSaved = function (event, data) {
-                this.attr.ident = data.ident;
-            };
-
-            this.validateAnyRecipient = function () {
-                return !_.isEmpty(_.flatten(_.values(this.attr.recipientValues)));
-            };
-
-            function allRecipientsAreEmails(mail) {
-                var allRecipients = mail.header.to.concat(mail.header.cc).concat(mail.header.bcc);
-                return _.isEmpty(allRecipients) ? false : _.all(allRecipients, emailFormatChecker);
-            }
-
-            function emailFormatChecker(email) {
-                var emailFormat = /[^\s@]+@[^\s@]+\.[^\s@]+$/;
-                return emailFormat.test(email);
-            }
-
-            this.saveTag = function (ev, data) {
-                this.attr.currentTag = data.tag;
-            };
-
-            this.mailSent = function () {
-                this.trigger(document, events.ui.userAlerts.displayMessage, {message: 'Your message was sent!'});
-            };
-
-            this.enableFloatlabel = function (element) {
-                var showClass = 'showfloatlabel';
-                $(element).bind('keyup', function () {
-                    var label = $(this).prev('label');
-                    if (this.value !== '') {
-                        label.addClass(showClass);
-                        $(this).addClass(showClass);
-                    } else {
-                        label.removeClass(showClass);
-                        $(this).removeClass(showClass);
-                    }
-                });
-            };
-
-            this.toggleRecipientsArrows = function () {
-                $('#cc-bcc-collapse').toggleClass('fa-angle-down');
-                $('#cc-bcc-collapse').toggleClass('fa-angle-up');
-            };
-
-            this.before('initialize', function () {
-                if (!this.discardDraft) {
-                    this.discardDraft = function () {
-                    };
-                }
-            });
-
-            this.bindCollapse = function () {
-                this.on($('#cc-bcc-collapse'), 'click', this.toggleRecipientsArrows);
-            };
-
-            this.after('initialize', function () {
-                this.on(document, events.dispatchers.rightPane.clear, this.teardown);
-                this.on(document, events.ui.recipients.updated, this.recipientsUpdated);
-                this.on(document, events.mail.draftSaved, this.draftSaved);
-                this.on(document, events.mail.sent, this.mailSent);
-
-                this.on(document, events.ui.mail.send, this.sendMail);
-
-                this.on(document, events.ui.mail.discard, this.discardDraft);
-                this.on(document, events.ui.tag.selected, this.saveTag);
-                this.on(document, events.ui.tag.select, this.saveTag);
-                this.bindCollapse();
-            });
-
-            compose.mixin(this, [attachmentList]);
-        }
-
-        return withMailEditBase;
-    });
diff --git a/web-ui/app/js/mixins/with_mail_sandbox.js b/web-ui/app/js/mixins/with_mail_sandbox.js
deleted file mode 100644
index 1a51840d..00000000
--- a/web-ui/app/js/mixins/with_mail_sandbox.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  ['helpers/view_helper', 'page/events'],
-  function(viewHelpers, events) {
-    'use strict';
-
-    function withMailSandbox() {
-      this.showMailOnSandbox = function(mail) {
-        var that = this;
-        var $iframe = $("#read-sandbox");
-        var iframe = $iframe[0];
-        var content = viewHelpers.formatMailBody(mail);
-
-        window.addEventListener('message', function(e) {
-          if (e.origin === 'null' && e.source === iframe.contentWindow) {
-            that.trigger(document, events.ui.replyBox.showReplyContainer);
-            that.trigger(document, events.search.highlightResults, {where: '.mail-read-view__header'});
-          }
-        });
-
-        iframe.onload = function() {
-          if ($iframe.iFrameResize) {
-            // use iframe-resizer to dynamically adapt iframe size to its content
-            var config = {
-              resizedCallback: scaleToFit,
-              checkOrigin: false
-            };
-            $iframe.iFrameResize(config);
-          }
-
-          iframe.contentWindow.postMessage({
-            html: content
-          }, '*');
-
-          // transform scale iframe to fit container width
-          // necessary if iframe is wider than container
-          function scaleToFit() {
-            var parentWidth = $iframe.parent().width();
-            var w = $iframe.width();
-            var scale = 'none';
-
-            // only scale html mails
-            if (mail && mail.htmlBody && (w > parentWidth)) {
-                scale = parentWidth / w;
-                scale = 'scale(' + scale + ',' + scale + ')';
-            }
-
-            $iframe.css({
-                '-webkit-transform-origin': '0 0',
-                '-moz-transform-origin': '0 0',
-                '-ms-transform-origin': '0 0',
-                'transform-origin': '0 0',
-                '-webkit-transform': scale,
-                '-moz-transform': scale,
-                '-ms-transform': scale,
-                'transform': scale
-            });
-          }
-        };
-      };
-    }
-
-    return withMailSandbox;
-  }
-);
diff --git a/web-ui/app/js/mixins/with_mail_tagging.js b/web-ui/app/js/mixins/with_mail_tagging.js
deleted file mode 100644
index 1fc1c3bd..00000000
--- a/web-ui/app/js/mixins/with_mail_tagging.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-  ['page/events', 'features'],
-  function (events, features) {
-  'use strict';
-    function withMailTagging () {
-      this.updateTags = function(mail, tags) {
-        this.trigger(document, events.mail.tags.update, {ident: mail.ident, tags: tags});
-      };
-
-      this.attachTagCompletion = function(mail) {
-        this.tagFilter = function (parsedResult) {
-            var filtered = _.filter(parsedResult, function (tag) {return ! _.contains(mail.tags, tag.name); });
-            return _.map(filtered, function(tag) { return {value: Handlebars.Utils.escapeExpression(tag.name)}; });
-        };
-
-        this.tagCompleter = new Bloodhound({
-          datumTokenizer: function(d) { return [d.value]; },
-          queryTokenizer: function(q) { return [q.trim()]; },
-          remote: {
-            url: '/tags?skipDefaultTags=true&q=%QUERY',
-            filter: this.tagFilter
-          }
-        });
-
-        this.tagCompleter.initialize();
-
-        this.select('newTagInput').typeahead({
-          hint: true,
-          highlight: true,
-          minLength: 1
-        }, {
-          source: this.tagCompleter.ttAdapter()
-        });
-      };
-
-      this.createNewTag = function () {
-        var tagsCopy = this.attr.mail.tags.slice();
-        tagsCopy.push(this.select('newTagInput').val());
-        this.tagCompleter.clear();
-        this.tagCompleter.clearPrefetchCache();
-        this.tagCompleter.clearRemoteCache();
-        this.updateTags(this.attr.mail, _.uniq(tagsCopy));
-      };
-
-      this.after('displayMail', function () {
-        this.on(this.select('newTagInput'), 'typeahead:selected typeahead:autocompleted', this.createNewTag);
-      });
-    }
-
-    return withMailTagging;
-  }
-);
diff --git a/web-ui/app/js/monkey_patching/all.js b/web-ui/app/js/monkey_patching/all.js
deleted file mode 100644
index 2c29c9a1..00000000
--- a/web-ui/app/js/monkey_patching/all.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-require(['js/monkey_patching/array', 'js/monkey_patching/post_message'], function () {});
diff --git a/web-ui/app/js/monkey_patching/array.js b/web-ui/app/js/monkey_patching/array.js
deleted file mode 100644
index d0ccc4b8..00000000
--- a/web-ui/app/js/monkey_patching/array.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-(function () {
-  'use strict';
-
-  // Array Remove - By John Resig (MIT Licensed)
-  Array.prototype.remove = function (from, to) {
-    var rest = this.slice((to || from) + 1 || this.length);
-    this.length = from < 0 ? this.length + from : from;
-    return this.push.apply(this, rest);
-  };
-
-}());
diff --git a/web-ui/app/js/monkey_patching/post_message.js b/web-ui/app/js/monkey_patching/post_message.js
deleted file mode 100644
index 363ce581..00000000
--- a/web-ui/app/js/monkey_patching/post_message.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-/*
- * origin window.postMessage fails with non serializable objects, so we fallback to console.log to do the job
- */
-(function () {
-  'use strict';
-
-  var originalPostMessage = window.postMessage;
-  window.postMessage = function(a, b) {
-    try {
-      originalPostMessage(a, b);
-    } catch (e) {
-      console.log(a, b);
-    }
-  };
-
-}());
diff --git a/web-ui/app/js/page/default.js b/web-ui/app/js/page/default.js
deleted file mode 100644
index ecaedfd8..00000000
--- a/web-ui/app/js/page/default.js
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'mail_view/ui/compose_box',
-    'mail_list_actions/ui/mail_list_actions',
-    'user_alerts/ui/user_alerts',
-    'mail_list/ui/mail_list',
-    'mail_view/ui/no_message_selected_pane',
-    'mail_view/ui/no_mails_available_pane',
-    'mail_view/ui/mail_view',
-    'mail_view/ui/mail_actions',
-    'mail_view/ui/reply_section',
-    'mail_view/data/mail_sender',
-    'services/mail_service',
-    'services/delete_service',
-    'services/recover_service',
-    'tags/ui/tag_list',
-    'tags/data/tags',
-    'page/router',
-    'dispatchers/right_pane_dispatcher',
-    'dispatchers/middle_pane_dispatcher',
-    'dispatchers/left_pane_dispatcher',
-    'search/search_trigger',
-    'search/results_highlighter',
-    'foundation/off_canvas',
-    'page/pane_contract_expand',
-    'views/i18n',
-    'views/recipientListFormatter',
-    'flight/lib/logger',
-    'user_settings/data/user_settings',
-    'user_settings/ui/user_settings_icon',
-    'page/logout',
-    'page/logout_shortcut',
-    'feedback/feedback_trigger',
-    'mail_view/ui/feedback_box',
-    'mail_view/data/feedback_sender',
-    'page/version',
-    'page/unread_count_title',
-    'page/pix_logo',
-    'helpers/browser'
-  ],
-
-  function (
-    composeBox,
-    mailListActions,
-    userAlerts,
-    mailList,
-    noMessageSelectedPane,
-    noMailsAvailablePane,
-    mailView,
-    mailViewActions,
-    replyButton,
-    mailSender,
-    mailService,
-    deleteService,
-    recoverService,
-    tagList,
-    tags,
-    router,
-    rightPaneDispatcher,
-    middlePaneDispatcher,
-    leftPaneDispatcher,
-    searchTrigger,
-    resultsHighlighter,
-    offCanvas,
-    paneContractExpand,
-    viewI18n,
-    recipientListFormatter,
-    withLogging,
-    userSettings,
-    userSettingsIcon,
-    logout,
-    logoutShortcut,
-    feedback,
-    feedbackBox,
-    feedbackSender,
-    version,
-    unreadCountTitle,
-    pixLogo,
-    browser) {
-
-    'use strict';
-    function initialize(path) {
-      viewI18n.init(path + '/assets/');
-      viewI18n.loaded(function() {
-        paneContractExpand.attachTo(document);
-
-        userAlerts.attachTo('#user-alerts');
-
-        mailList.attachTo('#mail-list');
-        mailListActions.attachTo('#list-actions');
-
-        searchTrigger.attachTo('#search-trigger');
-        resultsHighlighter.attachTo(document);
-
-        mailSender.attachTo(document);
-
-        mailService.attachTo(document);
-        deleteService.attachTo(document);
-        recoverService.attachTo(document);
-
-        tags.attachTo(document);
-        tagList.attachTo('#tag-list');
-
-        router.attachTo(document);
-
-        rightPaneDispatcher.attachTo(document);
-        middlePaneDispatcher.attachTo(document);
-        leftPaneDispatcher.attachTo(document);
-
-        offCanvas.attachTo(document);
-        userSettings.attachTo(document);
-        userSettingsIcon.attachTo('#user-settings-icon');
-        logout.attachTo('#logout');
-        logoutShortcut.attachTo('#logout-shortcut');
-        version.attachTo('.version');
-
-        feedback.attachTo('#feedback');
-        feedbackSender.attachTo(document);
-
-        unreadCountTitle.attachTo(document);
-
-        pixLogo.attachTo(document);
-
-        $.ajaxSetup({headers: {'X-XSRF-TOKEN': browser.getCookie('XSRF-TOKEN')}});
-      });
-    }
-
-    return initialize;
-  }
-);
diff --git a/web-ui/app/js/page/events.js b/web-ui/app/js/page/events.js
deleted file mode 100644
index 68a6aad1..00000000
--- a/web-ui/app/js/page/events.js
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(function () {
-  'use strict';
-
-  var events = {
-    router: {
-      pushState: 'router:pushState'
-    },
-    ui: {
-      sendbutton: {
-        enable: 'ui:sendbutton:enable'
-      },
-      middlePane: {
-        expand: 'ui:middlePane:expand',
-        contract: 'ui:middlePane:contract'
-      },
-      userAlerts: {
-        displayMessage: 'ui:userAlerts:displayMessage'
-      },
-      tag: {
-        selected: 'ui:tagSelected',
-        select: 'ui:tagSelect',
-      },
-      tags: {
-        loaded: 'ui:tagsLoaded'
-      },
-      tagList: {
-        load: 'ui:tagList:load'
-      },
-      mails: {
-        refresh: 'ui:mails:refresh',
-        fetchByTag: 'ui:mails:fetchByTag',
-        cleanSelected: 'ui:mails:cleanSelected',
-        checkAll: 'ui:mails:checkAll',
-        uncheckAll: 'ui:mails:uncheckAll',
-        hasMailsChecked: 'ui:mails:hasMailsChecked'
-      },
-      mail: {
-        open: 'ui:mail:open',
-        updateSelected: 'ui:mail:updateSelected',
-        delete: 'ui:mail:delete',
-        deleteMany: 'ui:mail:deleteMany',
-        recoverMany: 'ui:mail:recoverMany',
-        archiveMany: 'ui:mail:archiveMany',
-        wantChecked: 'ui:mail:wantChecked',
-        hereChecked: 'ui:mail:hereChecked',
-        checked: 'ui:mail:checked',
-        discard: 'ui:mail:discard',
-        unchecked: 'ui:mail:unchecked',
-        changedSinceLastSave: 'ui:mail:changedSinceLastSave',
-        send: 'ui:mail:send',
-        recipientsUpdated: 'ui:mail:recipientsUpdated'
-      },
-      page: {
-        previous: 'ui:page:previous',
-        next: 'ui:page:next',
-        changed: 'ui:page:changed',
-        spinLogo: 'ui:page:spinLogo',
-        stopSpinningLogo: 'ui:page:stopSpinningLogo'
-      },
-      composeBox: {
-        newMessage: 'ui:composeBox:newMessage',
-        newReply: 'ui:composeBox:newReply',
-        trashReply: 'ui:composeBox:trashReply',
-        requestCancelReply: 'ui:composeBox:requestCancelReply'
-      },
-      replyBox: {
-        showReply: 'ui:replyBox:showReply',
-        showReplyAll: 'ui:replyBox:showReplyAll',
-        showReplyContainer: 'ui:replyBox:showReplyContainer',
-      },
-      recipients: {
-        entered: 'ui:recipients:entered',
-        enteredInvalid: 'ui:recipients:enteredInvalid',
-        updated: 'ui:recipients:updated',
-        editRecipient: 'ui:recipients:editRecipient',
-        deleteRecipient: 'ui:recipients:deleteRecipient',
-        deleteLast: 'ui:recipients:deleteLast',
-        selectLast: 'ui:recipients:selectLast',
-        unselectAll: 'ui:recipients:unselectAll',
-        addressesExist: 'ui:recipients:addressesExist',
-        inputFieldHasCharacters: 'ui:recipients:inputFieldHasCharacters',
-        inputFieldIsEmpty: 'ui:recipients:inputFieldIsEmpty',
-        doCompleteInput: 'ui:recipients:doCompleteInput',
-        doCompleteRecipients: 'ui:recipients:doCompleteRecipients',
-        clickToEdit: 'ui:recipients:clickToEdit'
-      },
-      userSettingsBox: {
-        toggle: 'ui:userSettingsBox:toggle'
-      }
-    },
-    search: {
-      perform: 'search:perform',
-      results: 'search:results',
-      empty: 'search:empty',
-      highlightResults: 'search:highlightResults',
-      resetHighlight: 'search:resetHighlight'
-    },
-    feedback: {
-      submit: 'feedback:submit',
-      submitted: 'feedback:submitted'
-    },
-    userSettings: {
-      here: 'userSettings:here',
-      getInfo: 'userSettings:getInfo',
-      destroyPopup: 'userSettings:destroyPopup'
-    },
-    mail: {
-      here: 'mail:here',
-      want: 'mail:want',
-      display: 'mail:display',
-      highlightMailContent: 'mail:highlightMailContent',
-      send: 'mail:send',
-      send_failed: 'mail:send_failed',
-      sent: 'mail:sent',
-      read: 'mail:read',
-      unread: 'mail:unread',
-      delete: 'mail:delete',
-      deleteMany: 'mail:deleteMany',
-      archiveMany: 'mail:archiveMany',
-      recoverMany: 'mail:recoverMany',
-      deleted: 'mail:deleted',
-      saveDraft: 'draft:save',
-      draftSaved: 'draft:saved',
-      draftReply: {
-        want: 'mail:draftReply:want',
-        here: 'mail:draftReply:here',
-        notFound: 'mail:draftReply:notFound'
-      },
-      notFound: 'mail:notFound',
-      save: 'mail:saved',
-      tags: {
-        update: 'mail:tags:update',
-        updated: 'mail:tags:updated'
-      },
-      uploadedAttachment: 'mail:uploaded:attachment',
-      uploadingAttachment: 'mail:uploading:attachment',
-      startUploadAttachment: 'mail:start:upload:attachment',
-      failedUploadAttachment: 'mail:failed:upload:attachment',
-      appendAttachment: 'mail:append:attachment',
-      resetAttachments: 'mail:reset:attachments',
-      removeAttachment: 'mail:remove:attachment'
-    },
-    mails: {
-      available: 'mails:available',
-      availableForRefresh: 'mails:available:refresh',
-      teardown: 'mails:teardown'
-    },
-    tags: {
-      want: 'tags:want',
-      received: 'tags:received',
-      teardown: 'tags:teardown',
-      shortcuts: {
-        teardown: 'tags:shortcuts:teardown'
-      }
-    },
-    route: {
-      toUrl: 'route:toUrl'
-    },
-
-    components: {
-      composeBox: {
-        open: 'components:composeBox:open',
-        close: 'components:composeBox:close'
-      },
-      mailPane: {
-        open: 'components:mailPane:open',
-        close: 'components:mailPane:close'
-      },
-      mailView: {
-        show: 'components:mailView:show',
-        close: 'components:mailView:close'
-      },
-      replySection: {
-        initialize: 'components:replySection:initialize',
-        close: 'components:replySection:close'
-      },
-      noMessageSelectedPane: {
-        open: 'components:noMessageSelectedPane:open',
-        close: 'components:noMessageSelectedPane:close'
-      }
-    },
-
-    dispatchers: {
-      rightPane: {
-        openComposeBox: 'dispatchers:rightPane:openComposeBox',
-        openFeedbackBox: 'dispatchers:rightPane:openFeedbackBox',
-        openNoMessageSelected: 'dispatchers:rightPane:openNoMessageSelected',
-        openNoMessageSelectedWithoutPushState: 'dispatchers:rightPane:openNoMessageSelectedWithoutPushState',
-        refreshMailList: 'dispatchers:rightPane:refreshMailList',
-        openDraft: 'dispatchers:rightPane:openDraft',
-        selectTag: 'dispatchers:rightPane:selectTag',
-        clear: 'dispatchers:rightPane:clear'
-      },
-      middlePane: {
-        refreshMailList: 'dispatchers:middlePane:refreshMailList',
-        cleanSelected: 'dispatchers:middlePane:unselect',
-        resetScroll: 'dispatchers:middlePane:resetScroll'
-      },
-      tags: {
-        refreshTagList: 'dispatchers:tag:refresh'
-      }
-    }
-  };
-
-  return events;
-});
diff --git a/web-ui/app/js/page/logout.js b/web-ui/app/js/page/logout.js
deleted file mode 100644
index 81b57db2..00000000
--- a/web-ui/app/js/page/logout.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(['flight/lib/component', 'features', 'views/templates', 'helpers/browser'],
- function (defineComponent, features, templates, browser) {
-  'use strict';
-
-  return defineComponent(function () {
-
-    this.defaultAttrs({form: '#logout-form'});
-
-    this.render = function () {
-      var logoutHTML = templates.page.logout({ logout_url: features.getLogoutUrl(),
-       csrf_token: browser.getCookie('XSRF-TOKEN')});
-      this.$node.html(logoutHTML);
-    };
-
-    this.logout = function(){
-      this.select('form').submit();
-    };
-
-    this.after('initialize', function () {
-      if (features.isLogoutEnabled()) {
-	      this.render();
-	      this.on(this.$node, 'click', this.logout);
-      }
-    });
-
-  });
-});
diff --git a/web-ui/app/js/page/logout_shortcut.js b/web-ui/app/js/page/logout_shortcut.js
deleted file mode 100644
index 10a69c7d..00000000
--- a/web-ui/app/js/page/logout_shortcut.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(['flight/lib/component', 'features', 'views/templates'], function (defineComponent, features, templates) {
-  'use strict';
-
-  return defineComponent(function () {
- 
-    this.render = function () {
-      if (features.isLogoutEnabled()) {
-        var logoutShortcutHTML = templates.page.logoutShortcut();
-        this.$node.html(logoutShortcutHTML);
-      }
-    };
-
-    this.after('initialize', function () {
-	    this.render();
-    });
-  });
-});
diff --git a/web-ui/app/js/page/pane_contract_expand.js b/web-ui/app/js/page/pane_contract_expand.js
deleted file mode 100644
index 9bb435c4..00000000
--- a/web-ui/app/js/page/pane_contract_expand.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(['flight/lib/component', 'page/events'], function (describeComponent, events) {
-  'use strict';
-
-  return describeComponent(paneContractExpand);
-
-  function paneContractExpand() {
-    this.defaultAttrs({
-      RIGHT_PANE_EXPAND_CLASSES: 'small-7 medium-7 large-7 columns',
-      RIGHT_PANE_CONTRACT_CLASSES: 'small-7 medium-4 large-4 columns',
-      MIDDLE_PANE_EXPAND_CLASSES: 'small-5 medium-8 large-8 columns no-padding',
-      MIDDLE_PANE_CONTRACT_CLASSES: 'small-5 medium-5 large-5 columns no-padding'
-    });
-
-    this.expandMiddlePaneContractRightPane = function () {
-      $('#middle-pane-container').attr('class', this.attr.MIDDLE_PANE_EXPAND_CLASSES);
-      $('#right-pane').attr('class', this.attr.RIGHT_PANE_CONTRACT_CLASSES);
-    };
-
-    this.contractMiddlePaneExpandRightPane = function () {
-      $('#middle-pane-container').attr('class', this.attr.MIDDLE_PANE_CONTRACT_CLASSES);
-      $('#right-pane').attr('class', this.attr.RIGHT_PANE_EXPAND_CLASSES);
-    };
-
-    this.after('initialize', function () {
-      this.on(document, events.ui.mail.open, this.contractMiddlePaneExpandRightPane);
-      this.on(document, events.dispatchers.rightPane.openComposeBox, this.contractMiddlePaneExpandRightPane);
-      this.on(document, events.dispatchers.rightPane.openDraft, this.contractMiddlePaneExpandRightPane);
-      this.on(document, events.dispatchers.rightPane.openFeedbackBox, this.contractMiddlePaneExpandRightPane);
-      this.on(document, events.dispatchers.rightPane.openNoMessageSelected, this.expandMiddlePaneContractRightPane);
-      this.expandMiddlePaneContractRightPane();
-    });
-
-  }
-});
diff --git a/web-ui/app/js/page/pix_logo.js b/web-ui/app/js/page/pix_logo.js
deleted file mode 100644
index ad17f3be..00000000
--- a/web-ui/app/js/page/pix_logo.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'page/events'
-  ],
-
-  function(defineComponent, events) {
-    'use strict';
-
-    return defineComponent(pixLogo);
-
-    function pixLogo() {
-      this.turnAnimationOn = function () {
-        $('.logo-part-animation-off').attr('class', 'logo-part-animation-on');
-      };
-
-      this.turnAnimationOff = function () {
-        setTimeout(function(){
-          $('.logo-part-animation-on').attr('class', 'logo-part-animation-off');
-        }, 600);
-      };
-
-      this.triggerSpinLogo = function (ev, data) {
-        this.trigger(document, events.ui.page.spinLogo);
-      };
-
-      this.triggerStopSpinningLogo = function(ev, data) {
-        this.trigger(document, events.ui.page.stopSpinningLogo);
-      };
-
-      this.after('initialize', function () {
-        this.on(document, events.ui.page.spinLogo, this.turnAnimationOn);
-        this.on(document, events.ui.page.stopSpinningLogo, this.turnAnimationOff);
-
-        this.on(document, events.ui.tag.select, this.triggerSpinLogo);
-        this.on(document, events.mails.available, this.triggerStopSpinningLogo);
-        this.on(document, events.mail.saveDraft, this.triggerSpinLogo);
-        this.on(document, events.mail.draftSaved, this.triggerStopSpinningLogo);
-        this.on(document, events.ui.mail.open, this.triggerSpinLogo);
-        this.on(document, events.dispatchers.rightPane.openDraft, this.triggerSpinLogo);
-        this.on(document, events.search.perform, this.triggerSpinLogo);
-        this.on(document, events.mail.want, this.triggerStopSpinningLogo);
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/page/router.js b/web-ui/app/js/page/router.js
deleted file mode 100644
index ce0d7d04..00000000
--- a/web-ui/app/js/page/router.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(['flight/lib/component', 'page/events', 'page/router/url_params'], function (defineComponent, events, urlParams) {
-  'use strict';
-
-  return defineComponent(function () {
-    this.defaultAttrs({
-      history: window.history
-    });
-
-    function createHash(data) {
-      var hash = '/#/' + data.tag;
-      if (!_.isUndefined(data.mailIdent)) {
-        hash += '/mail/' + data.mailIdent;
-      }
-      return hash;
-    }
-
-    function createState(data, previousState) {
-      return {
-        tag: data.tag || (previousState && previousState.tag) || urlParams.defaultTag(),
-        mailIdent: data.mailIdent,
-        query: data.query,
-        isDisplayNoMessageSelected: !!data.isDisplayNoMessageSelected
-      };
-    }
-
-    this.pushState = function (ev, data) {
-      if (!data.fromPopState) {
-        var nextState = createState(data, this.attr.history.state);
-        this.attr.history.pushState(nextState, '', createHash(nextState));
-      }
-    };
-
-    this.popState = function (ev) {
-      var state = ev.state || {};
-
-      this.trigger(document, events.ui.tag.select, {
-        tag: state.tag || urlParams.getTag(),
-        mailIdent: state.mailIdent,
-        fromPopState: true
-      });
-
-      if (ev.state.isDisplayNoMessageSelected) {
-        this.trigger(document, events.dispatchers.rightPane.openNoMessageSelectedWithoutPushState);
-      }
-    };
-
-    this.after('initialize', function () {
-      this.on(document, events.router.pushState, this.pushState);
-      this.on(document, events.ui.tag.select, this.pushState);
-      this.on(document, events.search.perform, this.pushState);
-      this.on(document, events.search.empty, this.pushState);
-      window.onpopstate = this.popState.bind(this);
-    });
-  });
-});
diff --git a/web-ui/app/js/page/router/url_params.js b/web-ui/app/js/page/router/url_params.js
deleted file mode 100644
index 4fa11c6d..00000000
--- a/web-ui/app/js/page/router/url_params.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define([], function () {
-  'use strict';
-
-  function defaultTag() {
-    return 'inbox';
-  }
-
-  function getDocumentHash() {
-    return document.location.hash.replace(/\/$/, '');
-  }
-
-  function hashTag(hash) {
-    if (hasMailIdent(hash)) {
-      return /\/(.+)\/mail\/[-\w]+$/.exec(getDocumentHash())[1];
-    }
-    return hash.substring(2);
-  }
-
-
-  function getTag() {
-    if (document.location.hash !== '') {
-      return hashTag(getDocumentHash());
-    }
-    return defaultTag();
-  }
-
-  function hasMailIdent() {
-    return getDocumentHash().match(/mail\/[-\w]+$/);
-  }
-
-  function getMailIdent() {
-    return /mail\/([-\w]+)$/.exec(getDocumentHash())[1];
-  }
-
-  return {
-    getTag: getTag,
-    hasMailIdent: hasMailIdent,
-    getMailIdent: getMailIdent,
-    defaultTag: defaultTag
-  };
-});
diff --git a/web-ui/app/js/page/unread_count_title.js b/web-ui/app/js/page/unread_count_title.js
deleted file mode 100644
index 89dcd47d..00000000
--- a/web-ui/app/js/page/unread_count_title.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2015 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-define(
-  [
-    'flight/lib/component',
-    'page/events',
-  ],
-
-  function (defineComponent, events) {
-    'use strict';
-
-    return defineComponent(function () {
-      this.getTitleText = function () {
-        return document.title;
-      };
-
-      this.updateCount = function (ev, data) {
-        var unread = data.mails.filter(function (mail) {
-            return mail.status.indexOf('read') === -1;
-        }).length;
-
-        var tag = this.toTitleCase(data.tag);
-        var counter = unread > 0 ? ' (' + unread + ') - ' : ' - ';
-        document.title = tag + counter  + this.rawTitle;
-      };
-
-      this.toTitleCase = function (str) {
-        return str.replace(/\b\w/g, function (txt) { return txt.toUpperCase(); });
-      };
-
-      this.after('initialize', function () {
-        this.rawTitle = document.title;
-        this.on(document, events.mails.available, this.updateCount);
-      });
-
-    });
-});
diff --git a/web-ui/app/js/page/version.js b/web-ui/app/js/page/version.js
deleted file mode 100644
index 9fd5e629..00000000
--- a/web-ui/app/js/page/version.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2015 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(['flight/lib/component', 'views/templates', 'helpers/view_helper'], function (defineComponent, templates, viewHelper) {
-  'use strict';
-
-  return defineComponent(function () {
-      this.defaultAttrs({
-        'sinceDate': '#version-date'
-      });
-    
-    this.render = function () {
-        this.$node.html(templates.page.version());
-        this.renderCommitDate();
-    };
-
-    this.renderCommitDate = function(){
-      var since = this.select('sinceDate').attr('data-since'),
-        commitDate = viewHelper.sinceDate(since);
-      this.select('sinceDate').html(commitDate + ' ago');
-    };
-
-    this.after('initialize', function () {
-      this.render();
-    });
-
-  });
-});
diff --git a/web-ui/app/js/sandbox.js b/web-ui/app/js/sandbox.js
deleted file mode 100644
index 33b16ea4..00000000
--- a/web-ui/app/js/sandbox.js
+++ /dev/null
@@ -1,11 +0,0 @@
-(function () {
-  'use strict';
-
-  window.onmessage = function (e) {
-    if (e.data.html) {
-      document.body.innerHTML = e.data.html;
-      var mainWindow = e.source;
-      mainWindow.postMessage('data ok', e.origin);
-    }
-  };
-})();
diff --git a/web-ui/app/js/search/results_highlighter.js b/web-ui/app/js/search/results_highlighter.js
deleted file mode 100644
index 831be0cd..00000000
--- a/web-ui/app/js/search/results_highlighter.js
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-  [
-    'flight/lib/component',
-    'page/events'
-  ], function (defineComponent, events) {
-
-    'use strict';
-
-    return defineComponent(resultsHighlighter);
-
-    function resultsHighlighter(){
-      this.defaultAttrs({
-        keywords: []
-      });
-
-      this.getKeywordsSearch = function (event, data) {
-        this.attr.keywords = data.query.split(' ').map(function(keyword) {
-          return keyword.toLowerCase();
-        });
-      };
-
-      this.highlightResults = function (event, data) {
-        var domIdent = data.where;
-        if(this.attr.keywords) {
-          _.each(this.attr.keywords, function (keyword) {
-            keyword = escapeRegExp(keyword);
-            $(domIdent).highlightRegex(new RegExp(keyword, 'i'), {
-              tagType:   'em',
-              className: 'search-highlight'
-            });
-          });
-        }
-      };
-
-      this.clearHighlights = function (event, data) {
-        this.attr.keywords = [];
-        _.each($('em.search-highlight'), function(highlighted) {
-          var jqueryHighlighted = $(highlighted);
-          var text = jqueryHighlighted.text();
-          jqueryHighlighted.replaceWith(text);
-        });
-      };
-
-      this.highlightString = function (string) {
-        _.each(this.attr.keywords, function (keyword) {
-          keyword = escapeRegExp(keyword);
-          var regex = new RegExp('(' + keyword + ')', 'ig');
-          string = string.replace(regex, '<em class="search-highlight">$1</em>');
-        });
-        return string;
-      };
-
-      /*
-       * Alter data.mail.textPlainBody to highlight each of this.attr.keywords
-       * and pass it back to the mail_view when done
-       */
-      this.highlightMailContent = function(ev, data){
-        var mail = data.mail;
-        mail.textPlainBody = this.highlightString(mail.textPlainBody);
-        this.trigger(document, events.mail.display, data);
-      };
-
-      /*
-       * Escapes the special charaters used regular expressions that
-       * would cause problems with strings in the RegExp constructor
-       */
-      function escapeRegExp(string){
-        return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
-      }
-
-      this.after('initialize', function () {
-        this.on(document, events.search.perform, this.getKeywordsSearch);
-        this.on(document, events.ui.tag.select, this.clearHighlights);
-        this.on(document, events.search.resetHighlight, this.clearHighlights);
-
-        this.on(document, events.search.highlightResults, this.highlightResults);
-        this.on(document, events.mail.highlightMailContent, this.highlightMailContent);
-      });
-    }
-});
diff --git a/web-ui/app/js/search/search_trigger.js b/web-ui/app/js/search/search_trigger.js
deleted file mode 100644
index 2aff027c..00000000
--- a/web-ui/app/js/search/search_trigger.js
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-  [
-    'flight/lib/component',
-    'views/templates',
-    'page/events',
-    'views/i18n'
-  ], function (defineComponent, templates, events, i18n) {
-
-    'use strict';
-
-    return defineComponent(searchTrigger);
-
-    function searchTrigger() {
-      this.defaultAttrs({
-        input: 'input[type=search]',
-        form: 'form',
-        searchResultsPrefix: 'search-results-for'
-      });
-
-      this.render = function() {
-        this.$node.html(templates.search.trigger());
-      };
-
-      this.search = function(ev, data) {
-        this.trigger(document, events.search.resetHighlight);
-        ev.preventDefault();
-        var input = this.select('input');
-        var value = input.val();
-        input.blur();
-        if(!_.isEmpty(value)){
-          this.trigger(document, events.search.perform, { query: value });
-        } else {
-          this.trigger(document, events.search.empty);
-        }
-      };
-
-      this.clearInput = function() {
-        this.select('input').val('');
-      };
-
-      this.showOnlySearchTerms = function(event){
-        var value = this.select('input').val();
-        var searchTerms = value.slice((i18n.t(this.attr.searchResultsPrefix) + ': ').length);
-        this.select('input').val(searchTerms);
-      };
-
-      this.showSearchTermsAndPlaceHolder = function(event){
-        var value = this.select('input').val();
-        if (value.length > 0){
-          this.select('input').val(i18n.t(this.attr.searchResultsPrefix) + ': ' + value);
-        }
-      };
-
-      this.after('initialize', function () {
-        this.render();
-        this.on(this.select('form'), 'submit', this.search);
-        this.on(this.select('input'), 'focus', this.showOnlySearchTerms);
-        this.on(this.select('input'), 'blur', this.showSearchTermsAndPlaceHolder);
-        this.on(document, events.ui.tag.selected, this.clearInput);
-        this.on(document, events.ui.tag.select, this.clearInput);
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/services/delete_service.js b/web-ui/app/js/services/delete_service.js
deleted file mode 100644
index 0dfc1bdb..00000000
--- a/web-ui/app/js/services/delete_service.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(['flight/lib/component', 'page/events', 'views/i18n'], function (defineComponent, events, i18n) {
-  'use strict';
-
-  return defineComponent(function() {
-
-    this.successDeleteMessageFor = function(mail) {
-      return mail.isInTrash() ?
-        i18n.t('delete-single') :
-        i18n.t('trash-single');
-    };
-
-    this.successDeleteManyMessageFor = function(mail) {
-      return mail.isInTrash() ?
-        i18n.t('delete-bulk') :
-        i18n.t('trash-bulk');
-    };
-
-    this.deleteEmail = function (event, data) {
-      this.trigger(document, events.mail.delete, {
-        mail: data.mail,
-        successMessage: this.successDeleteMessageFor(data.mail)
-      });
-    };
-
-    this.deleteManyEmails = function (event, data) {
-      var emails = _.values(data.checkedMails),
-         firstEmail = emails[_.first(_.keys(emails))];
-
-      this.trigger(document, events.mail.deleteMany, {
-        mails: emails,
-        successMessage: this.successDeleteManyMessageFor(firstEmail)
-      });
-
-    };
-
-    this.after('initialize', function () {
-      this.on(document, events.ui.mail.delete, this.deleteEmail);
-      this.on(document, events.ui.mail.deleteMany, this.deleteManyEmails);
-    });
-
-  });
-});
diff --git a/web-ui/app/js/services/mail_service.js b/web-ui/app/js/services/mail_service.js
deleted file mode 100644
index 5e4bd4f3..00000000
--- a/web-ui/app/js/services/mail_service.js
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-  [
-    'flight/lib/component',
-    'views/i18n',
-    'services/model/mail',
-    'helpers/monitored_ajax',
-    'page/events',
-    'features',
-    'mixins/with_auto_refresh',
-    'page/router/url_params'
-  ], function (defineComponent, i18n, Mail, monitoredAjax, events, features, withAutoRefresh, urlParams) {
-
-    'use strict';
-
-    return defineComponent(mailService, withAutoRefresh('refreshMails'));
-
-    function mailService() {
-      var that;
-
-      this.defaultAttrs({
-        mailsResource: '/mails',
-        singleMailResource: '/mail',
-        currentTag: '',
-        lastQuery: '',
-        currentPage: 1,
-        numPages: 1,
-        pageSize: 25
-      });
-
-      this.errorMessage = function (msg) {
-        return function () {
-          that.trigger(document, events.ui.userAlerts.displayMessage, { message: msg });
-        };
-      };
-
-      this.updateTags = function (ev, data) {
-        var ident = data.ident;
-
-        var success = function (data) {
-          this.refreshMails();
-          $(document).trigger(events.mail.tags.updated, { ident: ident, tags: data.tags });
-          $(document).trigger(events.dispatchers.tags.refreshTagList, { skipMailListRefresh: true });
-        };
-
-        var failure = function (resp) {
-          var msg = i18n.t('failed-change-tags');
-          if (resp.status === 403) {
-            msg = i18n.t('invalid-tag-name');
-          }
-          this.trigger(document, events.ui.userAlerts.displayMessage, { message: msg });
-        };
-
-        monitoredAjax(this, '/mail/' + ident + '/tags', {
-          type: 'POST',
-          contentType: 'application/json; charset=utf-8',
-          data: JSON.stringify({newtags: data.tags})
-        }).done(success.bind(this)).fail(failure.bind(this));
-
-      };
-
-      this.readMail = function (ev, data) {
-        var mailIdents;
-        if (data.checkedMails) {
-          mailIdents = _.map(data.checkedMails, function (mail) {
-            return mail.ident;
-          });
-        } else {
-          mailIdents = [data.ident];
-        }
-        monitoredAjax(this, '/mails/read', {
-          type: 'POST',
-          data: JSON.stringify({idents: mailIdents})
-        }).done(this.triggerMailsRead(data.checkedMails));
-      };
-
-      this.unreadMail = function (ev, data) {
-        var mailIdents;
-        if (data.checkedMails) {
-          mailIdents = _.map(data.checkedMails, function (mail) {
-            return mail.ident;
-          });
-        } else {
-          mailIdents = [data.ident];
-        }
-        monitoredAjax(this, '/mails/unread', {
-          type: 'POST',
-          data: JSON.stringify({idents: mailIdents})
-        }).done(this.triggerMailsRead(data.checkedMails));
-      };
-
-      this.triggerMailsRead = function (mails) {
-        return _.bind(function () {
-          this.refreshMails();
-          this.trigger(document, events.ui.mails.uncheckAll);
-        }, this);
-      };
-
-      this.triggerDeleted = function (dataToDelete) {
-        return _.bind(function () {
-          var mails = dataToDelete.mails || [dataToDelete.mail];
-
-          this.refreshMails();
-          this.trigger(document, events.ui.userAlerts.displayMessage, { message: dataToDelete.successMessage});
-          this.trigger(document, events.ui.mails.uncheckAll);
-          this.trigger(document, events.mail.deleted, { mails: mails });
-        }, this);
-      };
-
-      this.triggerRecovered = function (dataToRecover) {
-        return _.bind(function () {
-          var mails = dataToRecover.mails || [dataToRecover.mail];
-
-          this.refreshMails();
-          this.trigger(document, events.ui.userAlerts.displayMessage, { message: i18n.t(dataToRecover.successMessage)});
-          this.trigger(document, events.ui.mails.uncheckAll);
-        }, this);
-      };
-
-      this.triggerArchived = function (dataToArchive) {
-        return _.bind(function (response) {
-          this.refreshMails();
-          this.trigger(document, events.ui.userAlerts.displayMessage, { message: i18n.t(response.successMessage)});
-          this.trigger(document, events.ui.mails.uncheckAll);
-        }, this);
-      };
-
-      this.archiveManyMails = function(event, dataToArchive) {
-        var mailIdents = _.map(dataToArchive.checkedMails, function (mail) {
-          return mail.ident;
-        });
-        monitoredAjax(this, '/mails/archive', {
-          type: 'POST',
-          dataType: 'json',
-          contentType: 'application/json; charset=utf-8',
-          data: JSON.stringify({idents: mailIdents})
-        }).done(this.triggerArchived(dataToArchive))
-          .fail(this.errorMessage(i18n.t('failed-archive')));
-      };
-
-      this.deleteMail = function (ev, data) {
-        monitoredAjax(this, '/mail/' + data.mail.ident,
-          {type: 'DELETE'})
-          .done(this.triggerDeleted(data))
-          .fail(this.errorMessage(i18n.t('failed-delete-single')));
-      };
-
-      this.deleteManyMails = function (ev, data) {
-        var dataToDelete = data;
-        var mailIdents = _.map(data.mails, function (mail) {
-          return mail.ident;
-        });
-
-        monitoredAjax(this, '/mails/delete', {
-          type: 'POST',
-          dataType: 'json',
-          contentType: 'application/json; charset=utf-8',
-          data: JSON.stringify({idents: mailIdents})
-        }).done(this.triggerDeleted(dataToDelete))
-          .fail(this.errorMessage(i18n.t('failed-delete-bulk')));
-      };
-
-      this.recoverManyMails = function (ev, data) {
-        var dataToRecover = data;
-        var mailIdents = _.map(data.mails, function (mail) {
-          return mail.ident;
-        });
-
-        monitoredAjax(this, '/mails/recover', {
-          type: 'POST',
-          dataType: 'json',
-          contentType: 'application/json; charset=utf-8',
-          data: JSON.stringify({idents: mailIdents})
-        }).done(this.triggerRecovered(dataToRecover))
-          .fail(this.errorMessage(i18n.t('Could not move emails to inbox')));
-      };
-
-      function compileQuery(data) {
-        var query = 'tag:"' + that.attr.currentTag + '"';
-
-        if (data.tag === 'all') {
-          query = 'in:all';
-        }
-        return query;
-      }
-
-      this.fetchByTag = function (ev, data) {
-        this.attr.currentTag = data.tag;
-        this.attr.lastQuery = compileQuery(data);
-        this.updateCurrentPageNumber(1);
-
-        this.refreshMails();
-      };
-
-      this.newSearch = function (ev, data) {
-        this.attr.lastQuery = data.query;
-        this.attr.currentTag = 'all';
-        this.refreshMails();
-      };
-
-      this.mailFromJSON = function (mail) {
-        return Mail.create(mail);
-      };
-
-      this.parseMails = function (data) {
-        data.mails = _.map(data.mails, this.mailFromJSON, this);
-
-        return data;
-      };
-
-      function escaped(s) {
-        return encodeURIComponent(s);
-      }
-
-      this.excludeTrashedEmailsForDraftsAndSent = function (query) {
-        if (query === 'tag:"drafts"' || query === 'tag:"sent"') {
-          return query + ' -in:"trash"';
-        }
-        return query;
-      };
-
-      this.refreshMails = function () {
-        var url = this.attr.mailsResource + '?q=' + escaped(this.attr.lastQuery) + '&p=' + this.attr.currentPage + '&w=' + this.attr.pageSize;
-
-        this.attr.lastQuery = this.excludeTrashedEmailsForDraftsAndSent(this.attr.lastQuery);
-
-        monitoredAjax(this, url, { dataType: 'json' })
-          .done(function (data) {
-            this.attr.numPages = Math.ceil(data.stats.total / this.attr.pageSize);
-            this.trigger(document, events.mails.available, _.merge({tag: this.attr.currentTag, forSearch: this.attr.lastQuery }, this.parseMails(data)));
-          }.bind(this))
-          .fail(function () {
-            this.trigger(document, events.ui.userAlerts.displayMessage, { message: i18n.t('failed-fetch-messages'), class: 'error' });
-          }.bind(this));
-      };
-
-      function createSingleMailUrl(mailsResource, ident) {
-        return mailsResource + '/' + ident;
-      }
-
-      this.fetchSingle = function (event, data) {
-        var fetchUrl = createSingleMailUrl(this.attr.singleMailResource, data.mail);
-
-        monitoredAjax(this, fetchUrl, { dataType: 'json' })
-          .done(function (mail) {
-            if (_.isNull(mail)) {
-              this.trigger(data.caller, events.mail.notFound);
-              return;
-            }
-
-            this.trigger(data.caller, events.mail.here, { mail: this.mailFromJSON(mail) });
-          }.bind(this));
-      };
-
-      this.previousPage = function () {
-        if (this.attr.currentPage > 1) {
-          this.updateCurrentPageNumber(this.attr.currentPage - 1);
-          this.refreshMails();
-        }
-      };
-
-      this.nextPage = function () {
-        if (this.attr.currentPage < (this.attr.numPages)) {
-          this.updateCurrentPageNumber(this.attr.currentPage + 1);
-          this.refreshMails();
-        }
-      };
-
-      this.updateCurrentPageNumber = function (newCurrentPage) {
-        this.attr.currentPage = newCurrentPage;
-        this.trigger(document, events.ui.page.changed, {
-          currentPage: this.attr.currentPage,
-          numPages: this.attr.numPages
-        });
-      };
-
-      this.wantDraftReplyForMail = function (ev, data) {
-        if (!features.isEnabled('draftReply')) {
-          this.trigger(document, events.mail.draftReply.notFound);
-          return;
-        }
-
-        monitoredAjax(this, '/draft_reply_for/' + data.ident, { dataType: 'json' })
-          .done(function (mail) {
-            if (_.isNull(mail)) {
-              this.trigger(document, events.mail.draftReply.notFound);
-              return;
-            }
-            this.trigger(document, events.mail.draftReply.here, { mail: this.mailFromJSON(mail) });
-          }.bind(this));
-      };
-
-      this.after('initialize', function () {
-        that = this;
-
-        if (features.isEnabled('tags')) {
-          this.on(events.mail.tags.update, this.updateTags);
-        }
-
-        this.on(document, events.mail.draftReply.want, this.wantDraftReplyForMail);
-        this.on(document, events.mail.want, this.fetchSingle);
-        this.on(document, events.mail.read, this.readMail);
-        this.on(document, events.mail.unread, this.unreadMail);
-        this.on(document, events.mail.delete, this.deleteMail);
-        this.on(document, events.mail.deleteMany, this.deleteManyMails);
-        this.on(document, events.mail.recoverMany, this.recoverManyMails);
-        this.on(document, events.mail.archiveMany, this.archiveManyMails);
-        this.on(document, events.search.perform, this.newSearch);
-        this.on(document, events.ui.tag.selected, this.fetchByTag);
-        this.on(document, events.ui.tag.select, this.fetchByTag);
-        this.on(document, events.ui.mails.refresh, this.refreshMails);
-        this.on(document, events.ui.page.previous, this.previousPage);
-        this.on(document, events.ui.page.next, this.nextPage);
-
-        this.fetchByTag(null, {tag: urlParams.getTag()});
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/services/model/mail.js b/web-ui/app/js/services/model/mail.js
deleted file mode 100644
index 64a10c1c..00000000
--- a/web-ui/app/js/services/model/mail.js
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(['helpers/contenttype'], function (contentType) {
-  'use strict';
-  function isSentMail() {
-    return _.has(this, 'mailbox') && this.mailbox.toUpperCase() === 'SENT';
-  }
-
-  function isDraftMail() {
-    return _.has(this, 'mailbox') && this.mailbox.toUpperCase() === 'DRAFTS';
-  }
-
-  function isInTrash() {
-    return _.has(this, 'mailbox') && this.mailbox.toUpperCase() === 'TRASH';
-  }
-
-  function setDraftReplyFor(ident) {
-    this.draft_reply_for = ident;
-  }
-
-  function replyToAddress() {
-    return {
-      to: [this.replying.single],
-      cc: []
-    };
-  }
-
-  function replyToAllAddress() {
-    return {
-      to: this.replying.all['to-field'],
-      cc: this.replying.all['cc-field']
-    };
-  }
-
-  function getHeadersFromMailPart (rawBody) {
-    var lines, headerLines, endOfHeaders, headers;
-
-    lines = rawBody.split('\n');
-    endOfHeaders = _.indexOf(lines, '');
-    headerLines = lines.slice(0, endOfHeaders);
-
-    headers = _.map(headerLines, function (headerLine) {
-      return _.map(headerLine.split(':'), function(elem){return elem.trim();});
-    });
-
-    return _.object(headers);
-  }
-
-  function getBodyFromMailPart (rawBody) {
-    var lines, endOfHeaders;
-
-    lines = rawBody.split('\n');
-    endOfHeaders = _.indexOf(lines, '');
-
-    return lines.slice(endOfHeaders + 1).join('\n');
-  }
-
-  function parseWithHeaders(rawBody) {
-    return {headers: getHeadersFromMailPart(rawBody), body: getBodyFromMailPart(rawBody)};
-  }
-
-  function getMailMultiParts () {
-    var mediaType = this.getMailMediaType();
-    var boundary = '--' + mediaType.params.boundary + '\n';
-    var finalBoundary = '--' + mediaType.params.boundary + '--';
-
-    var bodyParts = this.body.split(finalBoundary)[0].split(boundary);
-
-    bodyParts = _.reject(bodyParts, function(bodyPart) { return _.isEmpty(bodyPart.trim()); });
-
-    return _.map(bodyParts, parseWithHeaders);
-  }
-
-  function getMailMediaType () {
-    return new contentType.MediaType(this.header.content_type);
-  }
-
-  function isMailMultipartAlternative () {
-    return this.getMailMediaType().type === 'multipart/alternative';
-  }
-
-  function availableBodyPartsContentType () {
-    var bodyParts = this.getMailMultiParts();
-
-    return _.pluck(_.pluck(bodyParts, 'headers'), 'Content-Type');
-  }
-
-  function getMailPartByContentType (contentType) {
-    var bodyParts = this.getMailMultiParts();
-
-    return _.findWhere(bodyParts, {headers: {'Content-Type': contentType}});
-  }
-
-  return {
-    create: function (mail) {
-      if (!mail) { return; }
-
-      mail.isSentMail = isSentMail;
-      mail.isDraftMail = isDraftMail;
-      mail.isInTrash = isInTrash;
-      mail.setDraftReplyFor = setDraftReplyFor;
-      mail.replyToAddress = replyToAddress;
-      mail.replyToAllAddress = replyToAllAddress;
-      mail.getMailMediaType = getMailMediaType;
-      mail.isMailMultipartAlternative = isMailMultipartAlternative;
-      mail.getMailMultiParts = getMailMultiParts;
-      mail.availableBodyPartsContentType = availableBodyPartsContentType;
-      mail.getMailPartByContentType = getMailPartByContentType;
-      return mail;
-    }
-  };
-});
diff --git a/web-ui/app/js/services/recover_service.js b/web-ui/app/js/services/recover_service.js
deleted file mode 100644
index d7d9cdc9..00000000
--- a/web-ui/app/js/services/recover_service.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(['flight/lib/component', 'page/events', 'views/i18n'], function (defineComponent, events, i18n) {
-  'use strict';
-
-  return defineComponent(function() {
-
-    this.recoverManyEmails = function (event, data) {
-      var emails = _.values(data.checkedMails);
-
-      this.trigger(document, events.mail.recoverMany, {
-        mails: emails,
-        successMessage: i18n.t('Your messages were moved to inbox!')
-      });
-
-    };
-
-    this.after('initialize', function () {
-      this.on(document, events.ui.mail.recoverMany, this.recoverManyEmails);
-    });
-
-  });
-});
diff --git a/web-ui/app/js/style_guide/main.js b/web-ui/app/js/style_guide/main.js
deleted file mode 100644
index 32c213cf..00000000
--- a/web-ui/app/js/style_guide/main.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-$(document).ready(function(){
-  'use strict';
-  $('a[href*=#]').click(function() {
-    if (location.pathname.replace(/^\//,'') === this.pathname.replace(/^\//,'') &&
-        location.hostname === this.hostname) {
-      var $target = $(this.hash);
-      $target = $target.length && $target ||
-      $('[name=' + this.hash.slice(1) +']');
-      if ($target.length) {
-        var targetOffset = $target.offset().top;
-        $('html,body')
-        .animate({scrollTop: targetOffset}, 500);
-       return false;
-      }
-    }
-  });
-});
diff --git a/web-ui/app/js/tags/data/tags.js b/web-ui/app/js/tags/data/tags.js
deleted file mode 100644
index 31703b2a..00000000
--- a/web-ui/app/js/tags/data/tags.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(['flight/lib/component', 'page/events', 'helpers/monitored_ajax', 'mixins/with_feature_toggle', 'mixins/with_auto_refresh'], function (defineComponent, events, monitoredAjax,  withFeatureToggle, withAutoRefresh) {
-  'use strict';
-
-  var DataTags = defineComponent(dataTags, withFeatureToggle('tags', function() {
-    $(document).trigger(events.ui.mails.refresh);
-  }), withAutoRefresh('refreshTags'));
-
-  DataTags.all = {
-    name: 'all',
-    ident: '8752888923742657436',
-    query: 'in:all',
-    default: true,
-    counts:{
-      total:0,
-        read:0,
-        starred:0,
-        replied:0
-    }
-  };
-
-  function dataTags() {
-    function sendTagsBackTo(on) {
-      return function(data) {
-        data.push(DataTags.all);
-        on.trigger(document, events.tags.received, {tags: data});
-      };
-    }
-
-    this.defaultAttrs({
-      tagsResource: '/tags'
-    });
-
-    this.fetchTags = function(event, params) {
-      monitoredAjax(this, this.attr.tagsResource)
-        .done(sendTagsBackTo(this));
-    };
-
-    this.refreshTags = function() {
-      var notTriggeredByEvent = null;
-      this.fetchTags(notTriggeredByEvent);
-    };
-
-    this.after('initialize', function () {
-      this.on(document, events.tags.want, this.fetchTags);
-      this.on(document, events.mail.sent, this.fetchTags);
-    });
-  }
-
-  return DataTags;
-});
diff --git a/web-ui/app/js/tags/ui/tag.js b/web-ui/app/js/tags/ui/tag.js
deleted file mode 100644
index 37814cfc..00000000
--- a/web-ui/app/js/tags/ui/tag.js
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(
-  [
-    'flight/lib/component',
-    'views/templates',
-    'page/events',
-    'views/i18n'
-  ],
-
-  function (defineComponent, templates, events, i18n) {
-    'use strict';
-
-    var Tag = defineComponent(tag);
-
-    Tag.appendedTo = function (parent, data) {
-      var res = new this();
-      res.renderAndAttach(parent, data);
-      return res;
-    };
-
-    return Tag;
-
-    function tag() {
-
-      var ALWAYS_HIDE_BADGE_FOR = ['sent', 'trash', 'all'];
-      var TOTAL_BADGE = ['drafts'];
-
-      this.displayBadge = function(tag) {
-        if(_.include(ALWAYS_HIDE_BADGE_FOR, tag.name)) { return false; }
-        if(this.badgeType(tag) === 'total') {
-          return tag.counts.total > 0;
-        } else {
-          return (tag.counts.total - tag.counts.read) > 0;
-        }
-      };
-
-      this.badgeType = function(tag) {
-        return _.include(TOTAL_BADGE, tag.name) ? 'total' : 'unread';
-      };
-
-      this.doUnselect = function () {
-        this.$node.removeClass('selected');
-      };
-
-      this.doSelect = function () {
-        this.$node.addClass('selected');
-      };
-
-      this.selectTag = function (ev, data) {
-        this.attr.currentTag = data.tag;
-        if (data.tag === this.attr.tag.name) {
-          this.doSelect();
-        }
-        else {
-          this.doUnselect();
-        }
-      };
-
-      this.selectTagAll = function () {
-        this.selectTag(null, {tag: 'all'});
-      };
-
-      this.viewFor = function (tag, template, currentTag) {
-        return template({
-          tagName: tag.default ? i18n.t('tags.' + tag.name) : tag.name,
-          ident: this.hashIdent(tag.ident),
-          count: this.badgeType(tag) === 'total' ? tag.counts.total : (tag.counts.total - tag.counts.read),
-          displayBadge: this.displayBadge(tag),
-          badgeType: this.badgeType(tag),
-          icon: tag.icon,
-          selected: tag.name === currentTag ? 'selected' : ''
-        });
-      };
-
-      this.decreaseReadCountIfMatchingTag = function (ev, data) {
-        var mailbox_and_tags = _.flatten([data.tags, data.mailbox]);
-        if (_.contains(mailbox_and_tags, this.attr.tag.name)) {
-          this.attr.tag.counts.read++;
-          this.$node.html(this.viewFor(this.attr.tag, templates.tags.tagInner, this.attr.currentTag));
-          if (!_.isUndefined(this.attr.shortcut)) {
-            this.attr.shortcut.reRender();
-          }
-        }
-      };
-
-      this.triggerSelect = function () {
-        this.trigger(document, events.ui.tag.select, { tag: this.attr.tag.name });
-
-        this.removeSearchingClass();
-      };
-
-      this.addSearchingClass = function() {
-        if (this.attr.tag.name === 'all'){
-          this.$node.addClass('searching');
-        }
-      };
-
-      this.hashIdent = function(ident) {
-        if (typeof ident === 'undefined') {
-          return '';
-        }
-        if (typeof ident === 'number') {
-          return ident;
-        }
-        if (ident.match(/^[a-zA-Z0-9]+$/)) {
-          return ident;
-        }
-
-        /*jslint bitwise: true */
-        return Math.abs(String(ident).split('').reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a;},0));
-      };
-
-      this.removeSearchingClass = function() {
-        if (this.attr.tag.name === 'all'){
-          this.$node.removeClass('searching');
-        }
-      };
-
-      this.after('initialize', function () {
-        this.on('click', this.triggerSelect);
-        this.on(document, events.mail.read, this.decreaseReadCountIfMatchingTag);
-        this.on(document, events.search.perform, this.addSearchingClass);
-        this.on(document, events.search.empty, this.removeSearchingClass);
-
-        this.on(document, events.ui.tag.select, this.selectTag);
-        this.on(document, events.search.perform, this.selectTagAll);
-        this.on(document, events.search.empty, this.selectTagAll);
-      });
-
-      this.renderAndAttach = function (parent, data) {
-        var rendered = this.viewFor(data.tag, templates.tags.tag, data.currentTag);
-        parent.append(rendered);
-        this.initialize('#tag-' + this.hashIdent(data.tag.ident), data);
-        this.on(parent, events.tags.teardown, this.teardown);
-      };
-    }
-  }
-);
diff --git a/web-ui/app/js/tags/ui/tag_base.js b/web-ui/app/js/tags/ui/tag_base.js
deleted file mode 100644
index 9dc1ccbb..00000000
--- a/web-ui/app/js/tags/ui/tag_base.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(['views/i18n', 'page/events'], function(i18n, events) {
-  'use strict';
-
-  function tagBase() {
-    var ALWAYS_HIDE_BADGE_FOR = ['sent', 'trash', 'all'];
-    var TOTAL_BADGE = ['drafts'];
-
-    this.displayBadge = function(tag) {
-      if(_.include(ALWAYS_HIDE_BADGE_FOR, tag.name)) { return false; }
-      if(this.badgeType(tag) === 'total') {
-        return tag.counts.total > 0;
-      } else {
-        return (tag.counts.total - tag.counts.read) > 0;
-      }
-    };
-
-    this.badgeType = function(tag) {
-      return _.include(TOTAL_BADGE, tag.name) ? 'total' : 'unread';
-    };
-
-    this.doUnselect = function () {
-      this.$node.removeClass('selected');
-    };
-
-    this.doSelect = function () {
-      this.$node.addClass('selected');
-    };
-
-    this.selectTag = function (ev, data) {
-      this.attr.currentTag = data.tag;
-      if (data.tag === this.attr.tag.name) {
-        this.doSelect();
-      }
-      else {
-        this.doUnselect();
-      }
-    };
-
-    this.selectTagAll = function () {
-      this.selectTag(null, {tag: 'all'});
-    };
-
-    this.after('initialize', function () {
-      this.on(document, events.ui.tag.select, this.selectTag);
-      this.on(document, events.search.perform, this.selectTagAll);
-      this.on(document, events.search.empty, this.selectTagAll);
-    });
-  }
-
-  return tagBase;
-
-});
diff --git a/web-ui/app/js/tags/ui/tag_list.js b/web-ui/app/js/tags/ui/tag_list.js
deleted file mode 100644
index a2172c6d..00000000
--- a/web-ui/app/js/tags/ui/tag_list.js
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'tags/ui/tag',
-    'views/templates',
-    'page/events',
-    'page/router/url_params'
-  ],
-
-  function(defineComponent, Tag, templates, events, urlParams) {
-    'use strict';
-
-    var ICON_FOR = {
-      'inbox': 'inbox',
-      'sent': 'send',
-      'drafts': 'pencil',
-      'trash': 'trash-o',
-      'all': 'archive'
-    };
-
-    var ORDER = {
-      'inbox': '0',
-      'sent': '1',
-      'drafts': '2',
-      'trash': '3',
-      'all': '4'
-    };
-
-    return defineComponent(tagList);
-
-    function tagOrder(nm) {
-      return ORDER[nm.name] || '999' + nm.name;
-    }
-
-    function tagList() {
-      this.defaultAttrs({
-        defaultTagList: '#default-tag-list',
-        customTagList: '#custom-tag-list'
-      });
-
-      function renderTag(tag, defaultList, customList) {
-        var list = tag.default ? defaultList : customList;
-
-        var tagComponent = Tag.appendedTo(list, {tag: tag, currentTag: this.getCurrentTag()});
-      }
-
-      function resetTagList(lists) {
-        _.each(lists, function (list) {
-          this.trigger(list, events.tags.teardown);
-          list.empty();
-        }.bind(this));
-
-      }
-
-      this.renderTagList = function(tags) {
-        var defaultList = this.select('defaultTagList');
-        var customList = this.select('customTagList');
-
-        resetTagList.call(this, [defaultList, customList]);
-
-        tags.forEach(function (tag) {
-          renderTag.call(this, tag, defaultList, customList);
-        }.bind(this));
-      };
-
-      this.displayTags = function(ev, data) {
-        this.renderTagList(_.sortBy(data.tags, tagOrder));
-      };
-
-      this.getCurrentTag = function () {
-        return this.attr.currentTag || urlParams.getTag();
-      };
-
-      this.updateCurrentTag = function(ev, data) {
-        this.attr.currentTag = data.tag;
-      };
-
-      this.renderTagListTemplate = function () {
-        this.$node.html(templates.tags.tagList());
-      };
-
-      this.after('initialize', function() {
-        this.on(document, events.tags.received, this.displayTags);
-        this.on(document, events.ui.tag.select, this.updateCurrentTag);
-        this.renderTagListTemplate();
-      });
-    }
-  }
-);
diff --git a/web-ui/app/js/user_alerts/ui/user_alerts.js b/web-ui/app/js/user_alerts/ui/user_alerts.js
deleted file mode 100644
index e944a7a5..00000000
--- a/web-ui/app/js/user_alerts/ui/user_alerts.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'views/templates',
-    'mixins/with_hide_and_show',
-    'page/events'
-  ],
-
-  function(defineComponent, templates, withHideAndShow, events) {
-    'use strict';
-
-    return defineComponent(userAlerts, withHideAndShow);
-
-    function userAlerts() {
-      this.defaultAttrs({
-        dismissTimeout: 3000
-      });
-
-      this.render = function(message) {
-        this.$node.html(templates.userAlerts.message(message));
-        this.show();
-        setTimeout(this.hide.bind(this), this.attr.dismissTimeout);
-      };
-
-
-      this.displayMessage = function(ev, data) {
-        this.render({
-          message: {
-            content: data.message,
-            class: 'message-panel__growl--' + (data.class || 'success')
-          }
-        });
-      };
-
-      this.after('initialize', function() {
-        this.on(document, events.ui.userAlerts.displayMessage, this.displayMessage);
-      });
-    }
-  }
-);
-
diff --git a/web-ui/app/js/user_settings/data/user_settings.js b/web-ui/app/js/user_settings/data/user_settings.js
deleted file mode 100644
index dac29cec..00000000
--- a/web-ui/app/js/user_settings/data/user_settings.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2015 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'helpers/monitored_ajax',
-    'page/events'
-  ],
-  function (defineComponent, monitoredAjax, events) {
-    'use strict';
-
-  return defineComponent(function() {
-    this.defaultAttrs({
-      userSettingsResource: '/user-settings',
-      userSettings: {}
-    });
-
-    this.sendInfo = function() {
-      this.trigger(document, events.userSettings.here, this.attr.userSettings);
-    };
-
-    this.getUserSettings = function() {
-      var getUserSettingsSuccess = function (userSettings) {
-        this.attr.userSettings = userSettings;
-      };
-    
-      monitoredAjax(this, this.attr.userSettingsResource, {
-        type: 'GET',
-        contentType: 'application/json; charset=utf-8'
-      }).done(getUserSettingsSuccess.bind(this));
-    };
-
-    this.after('initialize', function() {
-      this.getUserSettings();
-      this.on(document, events.userSettings.getInfo, this.sendInfo);
-    });
-  });
-});
diff --git a/web-ui/app/js/user_settings/ui/user_settings_box.js b/web-ui/app/js/user_settings/ui/user_settings_box.js
deleted file mode 100644
index d3de23ed..00000000
--- a/web-ui/app/js/user_settings/ui/user_settings_box.js
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'features',
-    'views/templates',
-    'page/events',
-    'helpers/monitored_ajax'
-  ], function (defineComponent, features, templates, events, monitoredAjax) {
-
-  'use strict';
-
-  return defineComponent(function () {
-    this.defaultAttrs({
-      close: '#user-settings-close',
-      userSettingsBoxContainer: '#user-settings-box'
-    });
-      
-    this.render = function (event, userSettings) {
-      if (features.isLogoutEnabled()) {
-        this.$node.addClass('extra-bottom-space');
-      }
-
-      this.$node.addClass('arrow-box');
-      this.$node.html(templates.page.userSettingsBox(userSettings));
-
-      this.on(this.attr.close, 'click', function() {
-        this.trigger(document, events.userSettings.destroyPopup);
-      });
-
-      this.on(document, 'click', function(e) {
-        var userSettingsBoxContainer = $(this.attr.userSettingsBoxContainer).get(0);
-        var target = e.target || e.srcElement;
-
-        if (target !== userSettingsBoxContainer && !isChildOf(target, userSettingsBoxContainer)) {
-          this.destroy();
-        }
-      });
-
-      function isChildOf(child, parent) {
-          if (child.parentNode === parent) {
-              return true;
-          } else if (child.parentNode === null) {
-              return false;
-          } else {
-              return isChildOf(child.parentNode, parent);
-          }
-      }
-    };
-
-    this.destroy = function () {
-      this.$node.remove();
-      this.teardown();
-    };
-
-    this.after('initialize', function () {
-      this.on(document, events.userSettings.here, this.render);
-      this.on(document, events.userSettings.destroyPopup, this.destroy);
-      this.trigger(document, events.userSettings.getInfo);
-    });
-  });
-});
diff --git a/web-ui/app/js/user_settings/ui/user_settings_icon.js b/web-ui/app/js/user_settings/ui/user_settings_icon.js
deleted file mode 100644
index a6385dc1..00000000
--- a/web-ui/app/js/user_settings/ui/user_settings_icon.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(
-  [
-    'flight/lib/component',
-    'views/templates',
-    'page/events',
-    'user_settings/ui/user_settings_box'
-  ], function (defineComponent, templates, events, userSettingsBox) {
-  'use strict';
-
-  return defineComponent(function () {
-    this.defaultAttrs({
-      userSettingsBox: $('#user-settings-box')
-    });
-
-    this.render = function () {
-      this.$node.html(templates.page.userSettingsIcon());
-    };
-
-    this.toggleUserSettingsBox = function() {
-      if(this.attr.userSettingsBox.children().length === 0) {
-        var div = $('<div>');
-        $(this.attr.userSettingsBox).append(div);
-        userSettingsBox.attachTo(div);
-        this.attr.userSettingsInfo = userSettingsBox;
-      } else {
-        this.trigger(document, events.userSettings.destroyPopup);
-      }
-    };
-
-    this.triggerToggleUserSettingsBox = function(e) {
-      this.trigger(document, events.ui.userSettingsBox.toggle);
-      e.stopPropagation();
-    };
-
-    this.after('initialize', function () {
-      this.render();
-      this.on('click', this.triggerToggleUserSettingsBox);
-      this.on(document, events.ui.userSettingsBox.toggle, this.toggleUserSettingsBox);
-    });
-  });
-});
diff --git a/web-ui/app/js/views/i18n.js b/web-ui/app/js/views/i18n.js
deleted file mode 100644
index 29a1beca..00000000
--- a/web-ui/app/js/views/i18n.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-define(['i18next',
-        'i18nextXHRBackend',
-        'i18nextBrowserLanguageDetector'],
-function(i18n, i18n_backend, I18n_detector) {
-  'use strict';
-
-  var detector = new I18n_detector();
-  var detect = detector.detect.bind(detector);
-
-  detector.detect = function(detectionOrder)  {
-    var result = detect(detectionOrder);
-    return result.replace('-', '_');
-  };
-
-  function t(i18n_key, options) {
-    var result = i18n.t(i18n_key, options);
-    var safe_string = new Handlebars.SafeString(result);
-    return safe_string.string;
-  }
-
-  function loaded(callback) {
-    i18n.on('loaded', function(loaded) {
-        callback();
-    });
-  }
-
-  function init(path) {
-    i18n
-      .use(i18n_backend)
-      .use(detector)
-      .init({
-        fallbackLng: 'en_US',
-        backend: {
-          loadPath: path + 'locales/{{lng}}/{{ns}}.json'
-        }
-      });
-    // Handlebars.registerHelper('t', self.bind(self));
-    Handlebars.registerHelper('t', t);
-  }
-
-  return {
-    t: t,
-    init: init,
-    loaded: loaded
-  };
-});
diff --git a/web-ui/app/js/views/recipientListFormatter.js b/web-ui/app/js/views/recipientListFormatter.js
deleted file mode 100644
index 0b887142..00000000
--- a/web-ui/app/js/views/recipientListFormatter.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(function() {
-  'use strict';
-  Handlebars.registerHelper('formatRecipients', function (header) {
-    function wrapWith(begin, end) {
-      return function (x) {
-        return begin + Handlebars.Utils.escapeExpression(x) + end;
-      };
-    }
-
-    var to = _.map(header.to, wrapWith('<span class="to">', '</span>'));
-    var cc = _.map(header.cc, wrapWith('<span class="cc">cc: ', '</span>'));
-    var bcc = _.map(header.bcc, wrapWith('<span class="bcc">bcc: ', '</span>'));
-
-    return new Handlebars.SafeString(to.concat(cc, bcc).join(', '));
-  });
-});
diff --git a/web-ui/app/js/views/templates.js b/web-ui/app/js/views/templates.js
deleted file mode 100644
index d4185471..00000000
--- a/web-ui/app/js/views/templates.js
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2014 ThoughtWorks, Inc.
- *
- * Pixelated is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Pixelated is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
- */
-
-define(['hbs/templates'], function (templates) {
-  'use strict';
-
-  var Templates = {
-    compose: {
-      box: window.Pixelated['app/templates/compose/compose_box.hbs'],
-      inlineBox: window.Pixelated['app/templates/compose/inline_box.hbs'],
-      replySection: window.Pixelated['app/templates/compose/reply_section.hbs'],
-      recipientInput: window.Pixelated['app/templates/compose/recipient_input.hbs'],
-      fixedRecipient: window.Pixelated['app/templates/compose/fixed_recipient.hbs'],
-      recipients: window.Pixelated['app/templates/compose/recipients.hbs'],
-      feedback: window.Pixelated['app/templates/compose/feedback_box.hbs'],
-      attachmentsList: window.Pixelated['app/templates/compose/attachments_list.hbs'],
-      attachmentItem: window.Pixelated['app/templates/compose/attachment_item.hbs'],
-      attachmentUploadItem: window.Pixelated['app/templates/compose/attachment_upload_item.hbs'],
-      uploadAttachmentFailed: window.Pixelated['app/templates/compose/upload_attachment_failed.hbs']
-    },
-    tags: {
-      tagList: window.Pixelated['app/templates/tags/tag_list.hbs'],
-      tag: window.Pixelated['app/templates/tags/tag.hbs'],
-      tagInner: window.Pixelated['app/templates/tags/tag_inner.hbs'],
-      shortcut: window.Pixelated['app/templates/tags/shortcut.hbs']
-    },
-    userAlerts: {
-      message: window.Pixelated['app/templates/user_alerts/message.hbs']
-    },
-    mails: {
-      single: window.Pixelated['app/templates/mails/single.hbs'],
-      fullView: window.Pixelated['app/templates/mails/full_view.hbs'],
-      mailActions: window.Pixelated['app/templates/mails/mail_actions.hbs'],
-      draft: window.Pixelated['app/templates/mails/draft.hbs'],
-      sent: window.Pixelated['app/templates/mails/sent.hbs'],
-      trash: window.Pixelated['app/templates/mails/trash.hbs']
-    },
-    mailActions: {
-      actionsBox: window.Pixelated['app/templates/mail_actions/actions_box.hbs'],
-      trashActionsBox: window.Pixelated['app/templates/mail_actions/trash_actions_box.hbs'],
-      composeTrigger: window.Pixelated['app/templates/mail_actions/compose_trigger.hbs'],
-      refreshTrigger: window.Pixelated['app/templates/mail_actions/refresh_trigger.hbs'],
-      paginationTrigger: window.Pixelated['app/templates/mail_actions/pagination_trigger.hbs']
-    },
-    noMessageSelected: window.Pixelated['app/templates/compose/no_message_selected.hbs'],
-    noMailsAvailable: window.Pixelated['app/templates/compose/no_mails_available.hbs'],
-    search: {
-      trigger: window.Pixelated['app/templates/search/search_trigger.hbs']
-    },
-    page: {
-      userSettingsIcon: window.Pixelated['app/templates/page/user_settings_icon.hbs'],
-      userSettingsBox: window.Pixelated['app/templates/page/user_settings_box.hbs'],
-      logout: window.Pixelated['app/templates/page/logout.hbs'],
-      logoutShortcut: window.Pixelated['app/templates/page/logout_shortcut.hbs'],
-      version: window.Pixelated['app/templates/page/version.hbs']
-    },
-    feedback: {
-      feedback: window.Pixelated['app/templates/feedback/feedback_trigger.hbs']
-    }
-  };
-
-  Handlebars.registerPartial('tag_inner', Templates.tags.tagInner);
-  Handlebars.registerPartial('recipients', Templates.compose.recipients);
-  Handlebars.registerPartial('attachments_list', Templates.compose.attachmentsList);
-  Handlebars.registerPartial('attachments_upload', Templates.compose.attachmentsList);
-  Handlebars.registerPartial('attachment_item', Templates.compose.attachmentItem);
-  Handlebars.registerPartial('attachment_upload_item', Templates.compose.attachmentUploadItem);
-  Handlebars.registerPartial('uploadAttachmentFailed', Templates.compose.uploadAttachmentFailed);
-
-  return Templates;
-});
-- 
cgit v1.2.3