diff --git a/app/assets/javascripts/admin/components/site-setting.js.es6 b/app/assets/javascripts/admin/components/site-setting.js.es6
index f89996c70..93e65743c 100644
--- a/app/assets/javascripts/admin/components/site-setting.js.es6
+++ b/app/assets/javascripts/admin/components/site-setting.js.es6
@@ -4,7 +4,7 @@ import SiteSetting from 'admin/models/site-setting';
 import { propertyNotEqual } from 'discourse/lib/computed';
 import computed from 'ember-addons/ember-computed-decorators';
 
-const CustomTypes = ['bool', 'enum', 'list', 'url_list', 'host_list'];
+const CustomTypes = ['bool', 'enum', 'list', 'url_list', 'host_list', 'category_list'];
 
 export default Ember.Component.extend(BufferedContent, ScrollTop, {
   classNameBindings: [':row', ':setting', 'setting.overridden', 'typeClass'],
@@ -12,44 +12,32 @@ export default Ember.Component.extend(BufferedContent, ScrollTop, {
   dirty: propertyNotEqual('buffered.value', 'setting.value'),
   validationMessage: null,
 
-  preview: function() {
-    const preview = this.get('setting.preview');
+  @computed("setting.preview", "buffered.value")
+  preview(preview, value) {
     if (preview) {
-      return new Handlebars.SafeString("<div class='preview'>" +
-                                        preview.replace(/\{\{value\}\}/g, this.get('buffered.value')) +
-                                        "</div>");
-    }
-  }.property('buffered.value'),
-
-  @computed('partialType')
-  typeClass() {
-    return this.get('partialType').replace("_", "-");
-  },
-
-  @computed('buffered.value')
-  enabled: {
-    get(bufferedValue) {
-      if (Ember.isEmpty(bufferedValue)) { return false; }
-      return bufferedValue === 'true';
-    },
-    set(value) {
-      this.set('buffered.value', value ? 'true' : 'false');
-      return value;
+      return new Handlebars.SafeString("<div class='preview'>" + preview.replace(/\{\{value\}\}/g, value) + "</div>");
     }
   },
 
-  settingName: function() {
-    return this.get('setting.setting').replace(/\_/g, ' ');
-  }.property('setting.setting'),
+  @computed('componentType')
+  typeClass(componentType) {
+    return componentType.replace("_", "-");
+  },
 
-  partialType: function()  {
-    let type = this.get('setting.type');
+  @computed("setting.setting")
+  settingName(setting) {
+    return setting.replace(/\_/g, ' ');
+  },
+
+  @computed("setting.type")
+  componentType(type) {
     return CustomTypes.indexOf(type) !== -1 ? type : 'string';
-  }.property('setting.type'),
+  },
 
-  partialName: function() {
-    return 'admin/templates/site-settings/' + this.get('partialType');
-  }.property('partialType'),
+  @computed("typeClass")
+  componentName(typeClass) {
+    return "site-settings/" + typeClass;
+  },
 
   _watchEnterKey: function() {
     const self = this;
@@ -65,8 +53,8 @@ export default Ember.Component.extend(BufferedContent, ScrollTop, {
   }.on("willDestroyElement"),
 
   _save() {
-    const setting = this.get('buffered');
-    const self = this;
+    const self = this,
+          setting = this.get('buffered');
     SiteSetting.update(setting.get('setting'), setting.get('value')).then(function() {
       self.set('validationMessage', null);
       self.commitBuffer();
diff --git a/app/assets/javascripts/admin/components/site-settings/bool.js.es6 b/app/assets/javascripts/admin/components/site-settings/bool.js.es6
new file mode 100644
index 000000000..40fcfb354
--- /dev/null
+++ b/app/assets/javascripts/admin/components/site-settings/bool.js.es6
@@ -0,0 +1,17 @@
+import computed from "ember-addons/ember-computed-decorators";
+
+export default Ember.Component.extend({
+
+  @computed("value")
+  enabled: {
+    get(value) {
+      if (Ember.isEmpty(value)) { return false; }
+      return value === "true";
+    },
+    set(value) {
+      this.set("value", value ? "true" : "false");
+      return value;
+    }
+  },
+
+});
diff --git a/app/assets/javascripts/admin/components/site-settings/category-list.js.es6 b/app/assets/javascripts/admin/components/site-settings/category-list.js.es6
new file mode 100644
index 000000000..487239b78
--- /dev/null
+++ b/app/assets/javascripts/admin/components/site-settings/category-list.js.es6
@@ -0,0 +1,16 @@
+import computed from "ember-addons/ember-computed-decorators";
+
+export default Ember.Component.extend({
+
+  @computed("value")
+  selectedCategories: {
+    get(value) {
+      return Discourse.Category.findByIds(value.split("|"));
+    },
+    set(value) {
+      this.set("value", value.mapBy("id").join("|"));
+      return value;
+    }
+  }
+
+});
diff --git a/app/assets/javascripts/admin/templates/components/site-setting.hbs b/app/assets/javascripts/admin/templates/components/site-setting.hbs
index 15821600e..be0d4d8a0 100644
--- a/app/assets/javascripts/admin/templates/components/site-setting.hbs
+++ b/app/assets/javascripts/admin/templates/components/site-setting.hbs
@@ -2,7 +2,7 @@
    <h3>{{unbound settingName}}</h3>
 </div>
 <div class="setting-value">
-  {{partial partialName}}
+{{component componentName setting=setting value=buffered.value validationMessage=validationMessage}}
 </div>
 {{#if dirty}}
   <div class='setting-controls'>
diff --git a/app/assets/javascripts/admin/templates/site-settings/bool.hbs b/app/assets/javascripts/admin/templates/components/site-settings/bool.hbs
similarity index 100%
rename from app/assets/javascripts/admin/templates/site-settings/bool.hbs
rename to app/assets/javascripts/admin/templates/components/site-settings/bool.hbs
diff --git a/app/assets/javascripts/admin/templates/components/site-settings/category-list.hbs b/app/assets/javascripts/admin/templates/components/site-settings/category-list.hbs
new file mode 100644
index 000000000..621f3fa70
--- /dev/null
+++ b/app/assets/javascripts/admin/templates/components/site-settings/category-list.hbs
@@ -0,0 +1,3 @@
+{{category-group categories=selectedCategories blacklist=selectedCategories}}
+<div class='desc'>{{{unbound setting.description}}}</div>
+{{setting-validation-message message=validationMessage}}
diff --git a/app/assets/javascripts/admin/templates/site-settings/enum.hbs b/app/assets/javascripts/admin/templates/components/site-settings/enum.hbs
similarity index 80%
rename from app/assets/javascripts/admin/templates/site-settings/enum.hbs
rename to app/assets/javascripts/admin/templates/components/site-settings/enum.hbs
index 67cbfc92a..765a0e20d 100644
--- a/app/assets/javascripts/admin/templates/site-settings/enum.hbs
+++ b/app/assets/javascripts/admin/templates/components/site-settings/enum.hbs
@@ -1,4 +1,4 @@
-{{combo-box valueAttribute="value" content=setting.validValues value=buffered.value none=setting.allowsNone}}
+{{combo-box valueAttribute="value" content=setting.validValues value=value none=setting.allowsNone}}
 {{preview}}
 {{setting-validation-message message=validationMessage}}
 <div class='desc'>{{{unbound setting.description}}}</div>
diff --git a/app/assets/javascripts/admin/templates/site-settings/url_list.hbs b/app/assets/javascripts/admin/templates/components/site-settings/host-list.hbs
similarity index 60%
rename from app/assets/javascripts/admin/templates/site-settings/url_list.hbs
rename to app/assets/javascripts/admin/templates/components/site-settings/host-list.hbs
index ec8ecaf39..5107f5b4a 100644
--- a/app/assets/javascripts/admin/templates/site-settings/url_list.hbs
+++ b/app/assets/javascripts/admin/templates/components/site-settings/host-list.hbs
@@ -1,3 +1,3 @@
-{{value-list values=buffered.value addKey="admin.site_settings.add_url"}}
+{{value-list values=value addKey="admin.site_settings.add_host"}}
 {{setting-validation-message message=validationMessage}}
 <div class='desc'>{{{unbound setting.description}}}</div>
diff --git a/app/assets/javascripts/admin/templates/site-settings/list.hbs b/app/assets/javascripts/admin/templates/components/site-settings/list.hbs
similarity index 54%
rename from app/assets/javascripts/admin/templates/site-settings/list.hbs
rename to app/assets/javascripts/admin/templates/components/site-settings/list.hbs
index bc1cf2b51..e741bea5e 100644
--- a/app/assets/javascripts/admin/templates/site-settings/list.hbs
+++ b/app/assets/javascripts/admin/templates/components/site-settings/list.hbs
@@ -1,3 +1,3 @@
-{{list-setting settingValue=buffered.value choices=setting.choices settingName=setting.setting}}
+{{list-setting settingValue=value choices=setting.choices settingName=setting.setting}}
 {{setting-validation-message message=validationMessage}}
 <div class='desc'>{{{unbound setting.description}}}</div>
diff --git a/app/assets/javascripts/admin/templates/site-settings/string.hbs b/app/assets/javascripts/admin/templates/components/site-settings/string.hbs
similarity index 62%
rename from app/assets/javascripts/admin/templates/site-settings/string.hbs
rename to app/assets/javascripts/admin/templates/components/site-settings/string.hbs
index f8427094a..71d7216f2 100644
--- a/app/assets/javascripts/admin/templates/site-settings/string.hbs
+++ b/app/assets/javascripts/admin/templates/components/site-settings/string.hbs
@@ -1,3 +1,3 @@
-{{text-field value=buffered.value classNames="input-setting-string"}}
+{{text-field value=value classNames="input-setting-string"}}
 {{setting-validation-message message=validationMessage}}
 <div class='desc'>{{{unbound setting.description}}}</div>
diff --git a/app/assets/javascripts/admin/templates/site-settings/host_list.hbs b/app/assets/javascripts/admin/templates/components/site-settings/url-list.hbs
similarity index 60%
rename from app/assets/javascripts/admin/templates/site-settings/host_list.hbs
rename to app/assets/javascripts/admin/templates/components/site-settings/url-list.hbs
index 5f0c301d0..41213777e 100644
--- a/app/assets/javascripts/admin/templates/site-settings/host_list.hbs
+++ b/app/assets/javascripts/admin/templates/components/site-settings/url-list.hbs
@@ -1,3 +1,3 @@
-{{value-list values=buffered.value addKey="admin.site_settings.add_host"}}
+{{value-list values=value addKey="admin.site_settings.add_url"}}
 {{setting-validation-message message=validationMessage}}
 <div class='desc'>{{{unbound setting.description}}}</div>
diff --git a/app/assets/javascripts/discourse/components/category-group.js.es6 b/app/assets/javascripts/discourse/components/category-group.js.es6
index 13906ed31..e81fa5d1d 100644
--- a/app/assets/javascripts/discourse/components/category-group.js.es6
+++ b/app/assets/javascripts/discourse/components/category-group.js.es6
@@ -24,13 +24,13 @@ export default Ember.Component.extend({
           const slug = link.match(regexp)[1];
           return Discourse.Category.findSingleBySlug(slug);
         });
-        self.set("categories", categories);
+        Em.run.next(() => self.set("categories", categories));
       },
       template,
       transformComplete(category) {
         return categoryBadgeHTML(category, {allowUncategorized: true});
       }
     });
-  }.on('didInsertElement')
+  }.on('didInsertElement'),
 
 });
diff --git a/app/assets/javascripts/discourse/controllers/preferences.js.es6 b/app/assets/javascripts/discourse/controllers/preferences.js.es6
index dd729eab2..ee3e86e9d 100644
--- a/app/assets/javascripts/discourse/controllers/preferences.js.es6
+++ b/app/assets/javascripts/discourse/controllers/preferences.js.es6
@@ -71,19 +71,19 @@ export default Ember.Controller.extend(CanCheckEmails, {
 
   autoTrackDurations: [{ name: I18n.t('user.auto_track_options.never'), value: -1 },
                        { name: I18n.t('user.auto_track_options.immediately'), value: 0 },
-                       { name: I18n.t('user.auto_track_options.after_n_seconds', { count: 30 }), value: 30000 },
-                       { name: I18n.t('user.auto_track_options.after_n_minutes', { count: 1 }), value: 60000 },
-                       { name: I18n.t('user.auto_track_options.after_n_minutes', { count: 2 }), value: 120000 },
-                       { name: I18n.t('user.auto_track_options.after_n_minutes', { count: 3 }), value: 180000 },
-                       { name: I18n.t('user.auto_track_options.after_n_minutes', { count: 4 }), value: 240000 },
-                       { name: I18n.t('user.auto_track_options.after_n_minutes', { count: 5 }), value: 300000 },
-                       { name: I18n.t('user.auto_track_options.after_n_minutes', { count: 10 }), value: 600000 }],
+                       { name: I18n.t('user.auto_track_options.after_30_seconds'), value: 30000 },
+                       { name: I18n.t('user.auto_track_options.after_1_minute'), value: 60000 },
+                       { name: I18n.t('user.auto_track_options.after_2_minutes'), value: 120000 },
+                       { name: I18n.t('user.auto_track_options.after_3_minutes'), value: 180000 },
+                       { name: I18n.t('user.auto_track_options.after_4_minutes'), value: 240000 },
+                       { name: I18n.t('user.auto_track_options.after_5_minutes'), value: 300000 },
+                       { name: I18n.t('user.auto_track_options.after_10_minutes'), value: 600000 }],
 
   considerNewTopicOptions: [{ name: I18n.t('user.new_topic_duration.not_viewed'), value: -1 },
-                            { name: I18n.t('user.new_topic_duration.after_n_days', { count: 1 }), value: 60 * 24 },
-                            { name: I18n.t('user.new_topic_duration.after_n_days', { count: 2 }), value: 60 * 48 },
-                            { name: I18n.t('user.new_topic_duration.after_n_weeks', { count: 1 }), value: 7 * 60 * 24 },
-                            { name: I18n.t('user.new_topic_duration.after_n_weeks', { count: 2 }), value: 2 * 7 * 60 * 24 },
+                            { name: I18n.t('user.new_topic_duration.after_1_day'), value: 60 * 24 },
+                            { name: I18n.t('user.new_topic_duration.after_2_days'), value: 60 * 48 },
+                            { name: I18n.t('user.new_topic_duration.after_1_week'), value: 7 * 60 * 24 },
+                            { name: I18n.t('user.new_topic_duration.after_2_weeks'), value: 2 * 7 * 60 * 24 },
                             { name: I18n.t('user.new_topic_duration.last_here'), value: -2 }],
 
   saveButtonText: function() {
diff --git a/app/assets/stylesheets/common/admin/admin_base.scss b/app/assets/stylesheets/common/admin/admin_base.scss
index 15875c0d2..d7686805a 100644
--- a/app/assets/stylesheets/common/admin/admin_base.scss
+++ b/app/assets/stylesheets/common/admin/admin_base.scss
@@ -312,6 +312,9 @@ td.flaggers td {
     .setting-value {
       float: left;
       width: 53%;
+      .category-group {
+        width: 95%;
+      }
       @media (max-width: $mobile-breakpoint) {
         width: 100%;
       }
diff --git a/app/models/auto_track_duration_site_setting.rb b/app/models/auto_track_duration_site_setting.rb
new file mode 100644
index 000000000..6b10f80a5
--- /dev/null
+++ b/app/models/auto_track_duration_site_setting.rb
@@ -0,0 +1,27 @@
+require_dependency 'enum_site_setting'
+
+class AutoTrackDurationSiteSetting < EnumSiteSetting
+
+  def self.valid_value?(val)
+    values.any? { |v| v[:value].to_s == val.to_s }
+  end
+
+  def self.values
+    @values ||= [
+      { name: 'user.auto_track_options.never',            value: -1 },
+      { name: 'user.auto_track_options.immediately',      value: 0 },
+      { name: 'user.auto_track_options.after_30_seconds', value: 1000 * 30 },
+      { name: 'user.auto_track_options.after_1_minute',   value: 1000 * 60 },
+      { name: 'user.auto_track_options.after_2_minutes',  value: 1000 * 60 * 2 },
+      { name: 'user.auto_track_options.after_3_minutes',  value: 1000 * 60 * 3 },
+      { name: 'user.auto_track_options.after_4_minutes',  value: 1000 * 60 * 4 },
+      { name: 'user.auto_track_options.after_5_minutes',  value: 1000 * 60 * 5 },
+      { name: 'user.auto_track_options.after_10_minutes', value: 1000 * 60 * 10 },
+    ]
+  end
+
+  def self.translate_names?
+    true
+  end
+
+end
diff --git a/app/models/new_topic_duration_site_setting.rb b/app/models/new_topic_duration_site_setting.rb
new file mode 100644
index 000000000..92a00ea1c
--- /dev/null
+++ b/app/models/new_topic_duration_site_setting.rb
@@ -0,0 +1,24 @@
+require_dependency 'enum_site_setting'
+
+class NewTopicDurationSiteSetting < EnumSiteSetting
+
+  def self.valid_value?(val)
+    values.any? { |v| v[:value].to_s == val.to_s }
+  end
+
+  def self.values
+    @values ||= [
+      { name: 'user.new_topic_duration.not_viewed',    value: -1 },
+      { name: 'user.new_topic_duration.after_1_day',   value: 60 * 24 },
+      { name: 'user.new_topic_duration.after_2_days',  value: 60 * 24 * 2 },
+      { name: 'user.new_topic_duration.after_1_week',  value: 60 * 24 * 7 },
+      { name: 'user.new_topic_duration.after_2_weeks', value: 60 * 24 * 7 * 2 },
+      { name: 'user.new_topic_duration.last_here',     value: -2 },
+    ]
+  end
+
+  def self.translate_names?
+    true
+  end
+
+end
diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb
index ff1d17c00..8dbcb329c 100644
--- a/app/models/site_setting.rb
+++ b/app/models/site_setting.rb
@@ -99,6 +99,14 @@ class SiteSetting < ActiveRecord::Base
     false
   end
 
+  def self.default_categories_selected
+    [
+      SiteSetting.default_categories_watching.split("|"),
+      SiteSetting.default_categories_tracking.split("|"),
+      SiteSetting.default_categories_muted.split("|"),
+    ].flatten.to_set
+  end
+
 end
 
 # == Schema Information
diff --git a/app/models/topic_tracking_state.rb b/app/models/topic_tracking_state.rb
index e5272922f..12370fa23 100644
--- a/app/models/topic_tracking_state.rb
+++ b/app/models/topic_tracking_state.rb
@@ -110,7 +110,7 @@ class TopicTrackingState
                 now: DateTime.now,
                 last_visit: User::NewTopicDuration::LAST_VISIT,
                 always: User::NewTopicDuration::ALWAYS,
-                default_duration: SiteSetting.new_topic_duration_minutes
+                default_duration: SiteSetting.default_other_new_topic_duration_minutes
               ).where_values[0]
   end
 
diff --git a/app/models/topic_user.rb b/app/models/topic_user.rb
index b900c9b0a..01d57c580 100644
--- a/app/models/topic_user.rb
+++ b/app/models/topic_user.rb
@@ -97,7 +97,7 @@ class TopicUser < ActiveRecord::Base
         if rows == 0
           now = DateTime.now
           auto_track_after = User.select(:auto_track_topics_after_msecs).find_by(id: user_id).auto_track_topics_after_msecs
-          auto_track_after ||= SiteSetting.auto_track_topics_after
+          auto_track_after ||= SiteSetting.default_other_auto_track_topics_after_msecs
 
           if auto_track_after >= 0 && auto_track_after <= (attrs[:total_msecs_viewed] || 0)
             attrs[:notification_level] ||= notification_levels[:tracking]
@@ -143,7 +143,7 @@ class TopicUser < ActiveRecord::Base
         now: DateTime.now,
         msecs: msecs,
         tracking: notification_levels[:tracking],
-        threshold: SiteSetting.auto_track_topics_after
+        threshold: SiteSetting.default_other_auto_track_topics_after_msecs
       }
 
       # In case anyone seens "highest_seen_post_number" and gets confused, like I do.
@@ -198,7 +198,7 @@ class TopicUser < ActiveRecord::Base
       if rows.length == 0
         # The user read at least one post in a topic that they haven't viewed before.
         args[:new_status] = notification_levels[:regular]
-        if (user.auto_track_topics_after_msecs || SiteSetting.auto_track_topics_after) == 0
+        if (user.auto_track_topics_after_msecs || SiteSetting.default_other_auto_track_topics_after_msecs) == 0
           args[:new_status] = notification_levels[:tracking]
         end
         TopicTrackingState.publish_read(topic_id, post_number, user.id, args[:new_status])
diff --git a/app/models/user.rb b/app/models/user.rb
index 6b25f4f55..650d2b9ee 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -75,14 +75,15 @@ class User < ActiveRecord::Base
   validates :ip_address, allowed_ip_address: {on: :create, message: :signup_not_allowed}
 
   after_initialize :add_trust_level
-  after_initialize :set_default_email_digest
-  after_initialize :set_default_external_links_in_new_tab
+
+  before_create :set_default_user_preferences
 
   after_create :create_email_token
   after_create :create_user_stat
   after_create :create_user_profile
   after_create :ensure_in_trust_level_group
   after_create :automatic_group_membership
+  after_create :set_default_categories_preferences
 
   before_save :update_username_lower
   before_save :ensure_password_is_hashed
@@ -578,7 +579,7 @@ class User < ActiveRecord::Base
   end
 
   def treat_as_new_topic_start_date
-    duration = new_topic_duration_minutes || SiteSetting.new_topic_duration_minutes
+    duration = new_topic_duration_minutes || SiteSetting.default_other_new_topic_duration_minutes
     [case duration
       when User::NewTopicDuration::ALWAYS
         created_at
@@ -901,26 +902,42 @@ class User < ActiveRecord::Base
     end
   end
 
-  def set_default_email_digest
-    if has_attribute?(:email_digests) && self.email_digests.nil?
-      if SiteSetting.default_digest_email_frequency.blank?
-        self.email_digests = false
-      else
-        self.email_digests = true
-        self.digest_after_days ||= SiteSetting.default_digest_email_frequency.to_i if has_attribute?(:digest_after_days)
-      end
-    end
+  def set_default_user_preferences
+    set_default_email_digest_frequency
+    set_default_email_private_messages
+    set_default_email_direct
+    set_default_email_mailing_list_mode
+    set_default_email_always
+
+    set_default_other_new_topic_duration_minutes
+    set_default_other_auto_track_topics_after_msecs
+    set_default_other_external_links_in_new_tab
+    set_default_other_enable_quoting
+    set_default_other_dynamic_favicon
+    set_default_other_disable_jump_reply
+    set_default_other_edit_history_public
+
+    # needed, otherwise the callback chain is broken...
+    true
   end
 
-  def set_default_external_links_in_new_tab
-    if has_attribute?(:external_links_in_new_tab) && self.external_links_in_new_tab.nil?
-      self.external_links_in_new_tab = !SiteSetting.default_external_links_in_new_tab.blank?
+  def set_default_categories_preferences
+    values = []
+
+    %w{watching tracking muted}.each do |s|
+      category_ids = SiteSetting.send("default_categories_#{s}").split("|")
+      category_ids.each do |category_id|
+        values << "(#{self.id}, #{category_id}, #{CategoryUser.notification_levels[s.to_sym]})"
+      end
+    end
+
+    if values.present?
+      exec_sql("INSERT INTO category_users (user_id, category_id, notification_level) VALUES #{values.join(",")}")
     end
   end
 
   # Delete unactivated accounts (without verified email) that are over a week old
   def self.purge_unactivated
-
     to_destroy = User.where(active: false)
                      .joins('INNER JOIN user_stats AS us ON us.user_id = users.id')
                      .where("created_at < ?", SiteSetting.purge_unactivated_users_grace_period_days.days.ago)
@@ -950,6 +967,39 @@ class User < ActiveRecord::Base
     end
   end
 
+  def set_default_email_digest_frequency
+    if has_attribute?(:email_digests)
+      if SiteSetting.default_email_digest_frequency.blank?
+        self.email_digests = false
+      else
+        self.email_digests = true
+        self.digest_after_days ||= SiteSetting.default_email_digest_frequency.to_i if has_attribute?(:digest_after_days)
+      end
+    end
+  end
+
+  def set_default_email_mailing_list_mode
+    self.mailing_list_mode = SiteSetting.default_email_mailing_list_mode if has_attribute?(:mailing_list_mode)
+  end
+
+  %w{private_messages direct always}.each do |s|
+    define_method("set_default_email_#{s}") do
+      self.send("email_#{s}=", SiteSetting.send("default_email_#{s}")) if has_attribute?("email_#{s}")
+    end
+  end
+
+  %w{new_topic_duration_minutes auto_track_topics_after_msecs}.each do |s|
+    define_method("set_default_other_#{s}") do
+      self.send("#{s}=", SiteSetting.send("default_other_#{s}").to_i) if has_attribute?(s)
+    end
+  end
+
+  %w{external_links_in_new_tab enable_quoting dynamic_favicon disable_jump_reply edit_history_public}.each do |s|
+    define_method("set_default_other_#{s}") do
+      self.send("#{s}=", SiteSetting.send("default_other_#{s}")) if has_attribute?(s)
+    end
+  end
+
 end
 
 # == Schema Information
diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb
index dd5132504..a17dd36d2 100644
--- a/app/serializers/user_serializer.rb
+++ b/app/serializers/user_serializer.rb
@@ -249,11 +249,11 @@ class UserSerializer < BasicUserSerializer
   ###
 
   def auto_track_topics_after_msecs
-    object.auto_track_topics_after_msecs || SiteSetting.auto_track_topics_after
+    object.auto_track_topics_after_msecs || SiteSetting.default_other_auto_track_topics_after_msecs
   end
 
   def new_topic_duration_minutes
-    object.new_topic_duration_minutes || SiteSetting.new_topic_duration_minutes
+    object.new_topic_duration_minutes || SiteSetting.default_other_new_topic_duration_minutes
   end
 
   def muted_category_ids
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index d85e2a46d..c00d476af 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -583,23 +583,22 @@ en:
         label: "Consider topics new when"
         not_viewed: "I haven't viewed them yet"
         last_here: "created since I was here last"
-        after_n_days:
-          one: "created in the last day"
-          other: "created in the last {{count}} days"
-        after_n_weeks:
-          one: "created in the last week"
-          other: "created in the last {{count}} weeks"
+        after_1_day: "created in the last day"
+        after_2_days: "created in the last 2 days"
+        after_1_week: "created in the last week"
+        after_2_weeks: "created in the last 2 weeks"
 
       auto_track_topics: "Automatically track topics I enter"
       auto_track_options:
         never: "never"
         immediately: "immediately"
-        after_n_seconds:
-          one: "after 1 second"
-          other: "after {{count}} seconds"
-        after_n_minutes:
-          one: "after 1 minute"
-          other: "after {{count}} minutes"
+        after_30_seconds: "after 30 seconds"
+        after_1_minute: "after 1 minute"
+        after_2_minutes: "after 2 minutes"
+        after_3_minutes: "after 3 minutes"
+        after_4_minutes: "after 4 minutes"
+        after_5_minutes: "after 5 minutes"
+        after_10_minutes: "after 10 minutes"
 
       invited:
         search: "type to search invites..."
@@ -2422,6 +2421,7 @@ en:
           backups: "Backups"
           login: "Login"
           plugins: "Plugins"
+          user_preferences: "User Preferences"
 
       badges:
         title: Badges
diff --git a/config/locales/server.bs_BA.yml b/config/locales/server.bs_BA.yml
index 6757d882a..4b690b99d 100644
--- a/config/locales/server.bs_BA.yml
+++ b/config/locales/server.bs_BA.yml
@@ -698,8 +698,8 @@ bs_BA:
     automatically_download_gravatars: "Download Gravatars for users upon account creation or email change."
     digest_topics: "The maximum number of topics to display in the email digest."
     digest_min_excerpt_length: "Minimum post excerpt in the email digest, in characters."
-    default_digest_email_frequency: "How often users receive digest emails by default. They can change this setting in their preferences."
-    default_external_links_in_new_tab: "Open external links in a new tab. Users can change this in their preferences."
+    default_email_digest_frequency: "How often users receive digest emails by default. They can change this setting in their preferences."
+    default_other_external_links_in_new_tab: "Open external links in a new tab. Users can change this in their preferences."
     max_daily_gravatar_crawls: "Maximum number of times Discourse will check Gravatar for custom avatars in a day"
     public_user_custom_fields: "A whitelist of custom fields for a user that can be shown publically."
     allow_profile_backgrounds: "Allow users to upload profile backgrounds."
diff --git a/config/locales/server.cs.yml b/config/locales/server.cs.yml
index d185b5996..a80f177c7 100644
--- a/config/locales/server.cs.yml
+++ b/config/locales/server.cs.yml
@@ -668,8 +668,8 @@ cs:
     delete_all_posts_max: "Maximální počet příspěvků, které mohou být smazány najednou tlačítkem 'Odstranit všechny příspěvky'. Pokud má uživatel více příspěvků než je zde nastaveno, nemohou být jeho příspěvky smazány najednou a uživatele nelze odstranit."
     username_change_period: "Počet dní od registrace za kolik si uživatel může změnit svoje uživatelské jméno (0 pokud chcete změnu uživatelského jména úplně zakázat)."
     email_editable: "Povolit uživatelům změnit si po registraci emailovou adresu."
-    default_digest_email_frequency: "How often users receive digest emails by default. They can change this setting in their preferences."
-    default_external_links_in_new_tab: "Otevírat odkazy na externí weby v novém tabu. Uživatelé si toto můžou změnit v svém nastavení."
+    default_email_digest_frequency: "How often users receive digest emails by default. They can change this setting in their preferences."
+    default_other_external_links_in_new_tab: "Otevírat odkazy na externí weby v novém tabu. Uživatelé si toto můžou změnit v svém nastavení."
     enable_mobile_theme: "Používat na mobilních zařízeních verzi přizpůsobenou pro mobily s možností přejít na plnou verzi. Zruště pokud chcete používat vlastní plně responzivní kaskádový styl."
     short_progress_text_threshold: "After the number of posts in a topic goes above this number, the progress bar will only show the current post number. If you change the progress bar's width, you may need to change this value."
     default_code_lang: "Default programming language syntax highlighting applied to GitHub code blocks (lang-auto, ruby, python etc.)"
diff --git a/config/locales/server.da.yml b/config/locales/server.da.yml
index 68addb92f..ab8aa0037 100644
--- a/config/locales/server.da.yml
+++ b/config/locales/server.da.yml
@@ -626,8 +626,8 @@ da:
     delete_all_posts_max: "Det maksimale antal indlæg der kan slettes på én gang med “Slet alle indlæg”-knappen. Hvis en bruger har mere end dette antal indlæg, kan indlæggene ikke slettes på én gang og brugeren kan ikke slettes."
     username_change_period: "Antal dage efter oprettelsen hvor brugere kan ændre deres brugernavn (0 for ikke at tillade skift af brugernavn)."
     email_editable: "Lad brugerne skifte deres e-mail-adresse efter oprettelsen."
-    default_digest_email_frequency: "Hvor ofte brugerne som standard modtager e-mail-sammendrag. De kan ændre indstillingen på deres profil."
-    default_external_links_in_new_tab: "Åbn eksterne links i en nu fane; brugerne kan ændre dette på deres profil"
+    default_email_digest_frequency: "Hvor ofte brugerne som standard modtager e-mail-sammendrag. De kan ændre indstillingen på deres profil."
+    default_other_external_links_in_new_tab: "Åbn eksterne links i en nu fane; brugerne kan ændre dette på deres profil"
     enable_mobile_theme: "Mobile enheder bruger et mobilvenligt tema, med mulighed for at skifte til det fulde site. Deaktivér dette hvis du ønsker at anvende et brugerdefineret stylesheet som er fuldstændigt responsivt."
     short_progress_text_threshold: "Når antallet af indlæg overstiger dette tal viser statuslinjen kun det aktuelle indlægsnummer. Hvis du ændrer bredden af statuslinjen kan det være nødvendigt at opdatere denne værdi."
     default_code_lang: "Standard syntax highlighting som bruges i GitHub kodeblokke (lang-auto, ruby, python etc.)."
diff --git a/config/locales/server.de.yml b/config/locales/server.de.yml
index 356ef447b..02b0b3202 100644
--- a/config/locales/server.de.yml
+++ b/config/locales/server.de.yml
@@ -912,10 +912,10 @@ de:
     automatically_download_gravatars: "Avatare von Gravatar herunterladen, wenn ein Nutzer sich registriert oder seine E-Mail-Adresse ändert."
     digest_topics: "Maximale Anzahl von Themen, die in der E-Mail-Zusammenfassung angezeigt werden."
     digest_min_excerpt_length: "Minimale Länge des Auszugs aus einem Beitrag in der E-Mail-Zusammenfassung, in Zeichen."
-    default_digest_email_frequency: "Wie oft man Zusammenfassungen per Mail standardmässig erhält. Diese Einstellung kann von jedem geändert werden."
+    default_email_digest_frequency: "Wie oft man Zusammenfassungen per Mail standardmässig erhält. Diese Einstellung kann von jedem geändert werden."
     suppress_digest_email_after_days: "Sende keine E-Mail-Zusammenfassungen an Benutzer, die die Seite seit mehr als (n) Tagen nicht mehr besucht haben."
     disable_digest_emails: "E-Mail-Zusammenfassungen für alle Benutzer deaktivieren."
-    default_external_links_in_new_tab: "Öffne externe Links in einem neuen Tab. Benutzer können dies in ihren Einstellungen ändern."
+    default_other_external_links_in_new_tab: "Öffne externe Links in einem neuen Tab. Benutzer können dies in ihren Einstellungen ändern."
     max_daily_gravatar_crawls: "Wie oft pro Tag Discourse höchstens auf Gravatar nach benuterdefinierten Avataren suchen soll."
     public_user_custom_fields: "Liste selbst definierter Profil-Felder, die öffentlich angezeigt werden dürfen."
     staff_user_custom_fields: "Liste selbst definierter Profil-Felder, die Mitarbeitern angezeigt werden dürfen."
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index dba03554a..31391bf51 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -95,6 +95,7 @@ en:
       min_username_length_range: "You cannot set the minimum above the maximum."
       max_username_length_exists: "You cannot set the maximum username length below the longest username."
       max_username_length_range: "You cannot set the maximum above the minimum."
+      default_categories_already_selected: "You cannot select a category used in another list."
 
   activemodel:
     errors:
@@ -829,9 +830,6 @@ en:
     anon_polling_interval: "How often should anonymous clients poll in milliseconds"
     background_polling_interval: "How often should the clients poll in milliseconds (when the window is in the background)"
 
-    auto_track_topics_after: "Global default milliseconds before a topic is automatically tracked, users can override (0 for always, -1 for never)"
-    new_topic_duration_minutes: "Global default number of minutes a topic is considered new, users can override (-1 for always, -2 for last visit)"
-
     flags_required_to_hide_post: "Number of flags that cause a post to be automatically hidden and PM sent to the user (0 for never)"
     cooldown_minutes_after_hiding_posts: "Number of minutes a user must wait before they can edit a post hidden via community flagging"
 
@@ -1124,10 +1122,8 @@ en:
     automatically_download_gravatars: "Download Gravatars for users upon account creation or email change."
     digest_topics: "The maximum number of topics to display in the email digest."
     digest_min_excerpt_length: "Minimum post excerpt in the email digest, in characters."
-    default_digest_email_frequency: "How often users receive digest emails by default. They can change this setting in their preferences."
     suppress_digest_email_after_days: "Suppress digest emails for users not seen on the site for more than (n) days."
     disable_digest_emails: "Disable digest emails for all users."
-    default_external_links_in_new_tab: "Open external links in a new tab. Users can change this in their preferences."
 
     detect_custom_avatars: "Whether or not to check that users have uploaded custom profile pictures."
     max_daily_gravatar_crawls: "Maximum number of times Discourse will check Gravatar for custom avatars in a day"
@@ -1195,6 +1191,24 @@ en:
     approve_unless_trust_level: "Posts for users below this trust level must be approved"
     notify_about_queued_posts_after: "If there are posts that have been waiting to be reviewed for more than this many hours, an email will be sent to the contact email. Set to 0 to disable these emails."
 
+    default_email_digest_frequency: "How often users receive digest emails by default."
+    default_email_private_messages: "Send an email when someone messages the user by default."
+    default_email_direct: "Send an email when someone quotes/replies to/mentions or invites the user by default."
+    default_email_mailing_list_mode: "Send an email for every new post by default."
+    default_email_always: "Send an email notification even when the user is active by default."
+
+    default_other_new_topic_duration_minutes: "Global default number of minutes a topic is considered new, users can override (-1 for always, -2 for last visit)"
+    default_other_auto_track_topics_after_msecs: "Global default milliseconds before a topic is automatically tracked, users can override (0 for always, -1 for never)"
+    default_other_external_links_in_new_tab: "Open external links in a new tab by default."
+    default_other_enable_quoting: "Enable quote reply for highlighted text by default."
+    default_other_dynamic_favicon: "Show new/updated topic count on browser icon by default."
+    default_other_disable_jump_reply: "Don't jump to user's post after they reply by default."
+    default_other_edit_history_public: "Make the post revisions public by default."
+
+    default_categories_watching: "List of categories that are watched by default."
+    default_categories_tracking: "List of categories that are tracked by default."
+    default_categories_muted: "List of categories that are muted by default."
+
     errors:
       invalid_email: "Invalid email address."
       invalid_username: "There's no user with that username."
diff --git a/config/locales/server.es.yml b/config/locales/server.es.yml
index 825daf4a6..cd70349ba 100644
--- a/config/locales/server.es.yml
+++ b/config/locales/server.es.yml
@@ -962,10 +962,10 @@ es:
     automatically_download_gravatars: "Descargar Gravatars para usuarios cuando se creen una cuenta o cambien el email."
     digest_topics: "El número máximo de temas a mostrar en el resumen por email."
     digest_min_excerpt_length: "La extensión mínima, en caracteres, del extracto de un post en el resumen por email."
-    default_digest_email_frequency: "Cada cuánto tiempo los usuarios recibirán emails con el resumen del sitio por defecto. Cada usuario puede cambiar esta opción para sí en sus preferencias."
+    default_email_digest_frequency: "Cada cuánto tiempo los usuarios recibirán emails con el resumen del sitio por defecto. Cada usuario puede cambiar esta opción para sí en sus preferencias."
     suppress_digest_email_after_days: "Suprimir los emails de resumen para aquellos usuarios que no han visto el sitio desde más de (n) días."
     disable_digest_emails: "Inhabilitar e-mails de resumen para todos los usuarios."
-    default_external_links_in_new_tab: "Abrir enlaces externos en una nueva pestaña. Los usuarios pueden cambiar esto en sus preferencias."
+    default_other_external_links_in_new_tab: "Abrir enlaces externos en una nueva pestaña. Los usuarios pueden cambiar esto en sus preferencias."
     detect_custom_avatars: "Verificar o no que los usuarios han subido una imagen de perfil."
     max_daily_gravatar_crawls: "Máximo número de veces que Discourse comprobará Gravatar en busca de avatares personalizados en un día"
     public_user_custom_fields: "Una lista con campos personalizados para el usuario que pueden ser mostrados públicamente."
diff --git a/config/locales/server.fa_IR.yml b/config/locales/server.fa_IR.yml
index 60c71fcf5..1920ee6b2 100644
--- a/config/locales/server.fa_IR.yml
+++ b/config/locales/server.fa_IR.yml
@@ -903,10 +903,10 @@ fa_IR:
     automatically_download_gravatars: "آواتار را برای کاربران دریافت کن برای ساختن حساب کاربری یا ایمیل. "
     digest_topics: "حداکثر تعداد جستارهایی که در دایجست ایمیل نشان داده می شود "
     digest_min_excerpt_length: "حداقل نوشته های گزیده در ایمیل دایجست٬‌ در کاراکتر."
-    default_digest_email_frequency: "هر چند وقت یکبار کاربران ایمیل های  دایجست دریافت کنند بطور پیش فرض. آنها می توانند آن را در بخش تنظیمات عوض کنند. "
+    default_email_digest_frequency: "هر چند وقت یکبار کاربران ایمیل های  دایجست دریافت کنند بطور پیش فرض. آنها می توانند آن را در بخش تنظیمات عوض کنند. "
     suppress_digest_email_after_days: "ایمیل های خلاصه را مهار کن برای کاربرانی که در وب سایت دیده نشده اند بیشتر از (n) روز  "
     disable_digest_emails: "ایمیل های دایجست را برای تمام کاربران غیر فعال کن. "
-    default_external_links_in_new_tab: "پیوند های خارجی را در یک تب جدید باز کن. کاربران می توانند این را در قسمت تنظیماتشان تغییر دهند."
+    default_other_external_links_in_new_tab: "پیوند های خارجی را در یک تب جدید باز کن. کاربران می توانند این را در قسمت تنظیماتشان تغییر دهند."
     max_daily_gravatar_crawls: "حداکثرتعداد زمانی که دیسکورس Gravatar را چک می کند برای آواتار سفارشی در هر روز. "
     public_user_custom_fields: "لیست مجاز فیلد سفارشی برای کاربر که می تواند به همه نشان داده شود."
     staff_user_custom_fields: "لیست مجاز فیلد سفارشی برای کاربر که می تواند به مدیران نشان داده شود."
diff --git a/config/locales/server.fi.yml b/config/locales/server.fi.yml
index fb87dbf2b..91ca213c0 100644
--- a/config/locales/server.fi.yml
+++ b/config/locales/server.fi.yml
@@ -971,10 +971,10 @@ fi:
     automatically_download_gravatars: "Lataa käyttäjille Gravatarit automaattisesti tilin luonnin ja sähköpostin vaihdon yhteydessä."
     digest_topics: "Sähköpostitiivistelmässä näytettävien ketjujen maksimimäärä."
     digest_min_excerpt_length: "Viestin katkelman vähimmäispituus sähköpostitiivistelmässä, merkeissä"
-    default_digest_email_frequency: "Kuinka usein käyttäjän saavat sähköpostitiivistelmän oletuksena. He voivat muuttaa asetusta omista asetuksistaan."
+    default_email_digest_frequency: "Kuinka usein käyttäjän saavat sähköpostitiivistelmän oletuksena. He voivat muuttaa asetusta omista asetuksistaan."
     suppress_digest_email_after_days: "Jätä lähettämättä tiivistelmäsähköpostit käyttäjille, joita ei ole nähty (n) päivän aikana."
     disable_digest_emails: "Ota tiivistelmäsähköpostit pois käytöstä kaikilta käyttäjiltä."
-    default_external_links_in_new_tab: "Avaa ulkoiset linkit uudessa välilehdessä. Käyttäjät voivat muuttaa tämän asetuksistaan."
+    default_other_external_links_in_new_tab: "Avaa ulkoiset linkit uudessa välilehdessä. Käyttäjät voivat muuttaa tämän asetuksistaan."
     detect_custom_avatars: "Tarkistetaanko, ovatko käyttäjät ladanneet oman profiilikuvan."
     max_daily_gravatar_crawls: "Korkeintaan kuinka monta kertaa Discourse tarkistaa avatarit Gravatarista päivässä"
     public_user_custom_fields: "Whitelist käyttäjän mukautetuista kentistä, jotka voidaan näyttää julkisesti."
diff --git a/config/locales/server.fr.yml b/config/locales/server.fr.yml
index 137666d21..3d85c31a8 100644
--- a/config/locales/server.fr.yml
+++ b/config/locales/server.fr.yml
@@ -966,10 +966,10 @@ fr:
     automatically_download_gravatars: "Télécharger les gravatars pour les utilisateurs lors de la création de compte ou de la modification de courriel."
     digest_topics: "Nombre maximum de sujets à afficher dans le courriel de résumé."
     digest_min_excerpt_length: "Taille minimum du résumé des messages dans les courriels, en caractères."
-    default_digest_email_frequency: "A quelle fréquence les utilisateurs reçoivent-ils les courriels par défaut. Ils peuvent modifier ce paramétrage dans leur préférences."
+    default_email_digest_frequency: "A quelle fréquence les utilisateurs reçoivent-ils les courriels par défaut. Ils peuvent modifier ce paramétrage dans leur préférences."
     suppress_digest_email_after_days: "Ne pas envoyer de résumés courriel aux utilisateurs qui n'ont pas visité le site depuis (n) jours."
     disable_digest_emails: "Désactiver les résumés par courriels pour tous les utilisateurs."
-    default_external_links_in_new_tab: "Les liens externes s'ouvrent dans un nouvel onglet. Les utilisateurs peuvent modifier ceci dans leurs préférences."
+    default_other_external_links_in_new_tab: "Les liens externes s'ouvrent dans un nouvel onglet. Les utilisateurs peuvent modifier ceci dans leurs préférences."
     detect_custom_avatars: "Vérifier ou non si les utilisateurs ont envoyé une photo de profil personnalisée."
     max_daily_gravatar_crawls: "Nombre maximum de fois que Discourse vérifiera Gravatar pour des avatars personnalisés en une journée."
     public_user_custom_fields: "Une liste blanche des champs personnalisés pour un utilisateur  qui peuvent être affichés publiquement."
diff --git a/config/locales/server.he.yml b/config/locales/server.he.yml
index 5b5fc89d7..86aa93036 100644
--- a/config/locales/server.he.yml
+++ b/config/locales/server.he.yml
@@ -950,10 +950,10 @@ he:
     automatically_download_gravatars: "הורדת גראווטרים למשתמשים בעת יצירת החשבון או שינוי כתובת הדוא\"ל."
     digest_topics: "מספר הנושאים המקסימלי להצגה במייל סיכום."
     digest_min_excerpt_length: "מספר התווים המינימלי למובאות מתוך הפרסום במייל הסיכום."
-    default_digest_email_frequency: "How often users receive digest emails by default. They can change this setting in their preferences."
+    default_email_digest_frequency: "How often users receive digest emails by default. They can change this setting in their preferences."
     suppress_digest_email_after_days: "השהיית מיילים מסכמים עבור משתמשים שלא נראו באתר במשך יותר מ(n) ימים."
     disable_digest_emails: "נטרול דוא\"ל סיכום לכל המשתמשים."
-    default_external_links_in_new_tab: "Open external links in a new tab. Users can change this in their preferences."
+    default_other_external_links_in_new_tab: "Open external links in a new tab. Users can change this in their preferences."
     detect_custom_avatars: "Whether or not to check that users have uploaded custom profile pictures."
     max_daily_gravatar_crawls: "מספר הפעמים המקסימלי ש-Discourse יבדוק אווטרים ב-Gravatar ביום"
     public_user_custom_fields: "רשימה לבנה (whitelist) של שדות מותאמים למשתמש שיכולים להיות מוצגים באופן פומבי."
diff --git a/config/locales/server.it.yml b/config/locales/server.it.yml
index 0e72e1dea..bdd270d2e 100644
--- a/config/locales/server.it.yml
+++ b/config/locales/server.it.yml
@@ -896,8 +896,8 @@ it:
     default_avatars: "URL degli avatar che verranno utilizzati come predefiniti per tutti i nuovi utenti, fintanto che non li cambieranno esplicitamente."
     automatically_download_gravatars: "Scarica i Gravatars per gli utenti quando viene creato l'account o quando viene modificata l'email"
     digest_topics: "Numero massimo di argomenti da mostrare nel riassunto email."
-    default_digest_email_frequency: "Quanto spesso gli utenti ricevono email di riepilogo. Gli utenti possono modificare questa impostazione nelle loro preferenze."
-    default_external_links_in_new_tab: "Apri i collegamenti esterni in una nuova scheda. Gli utenti possono modificare questa impostazione nelle loro preferenze."
+    default_email_digest_frequency: "Quanto spesso gli utenti ricevono email di riepilogo. Gli utenti possono modificare questa impostazione nelle loro preferenze."
+    default_other_external_links_in_new_tab: "Apri i collegamenti esterni in una nuova scheda. Gli utenti possono modificare questa impostazione nelle loro preferenze."
     allow_profile_backgrounds: "Permetti agli utenti di caricare immagini di sfondo per il profilo."
     enable_mobile_theme: "I dispositivi mobili usano un tema apposito, con possibilità di passare alla visualizzazione completa. Disabilita questa opzione se vuoi usare un foglio di stile personalizzato che sia completamente reattivo."
     suppress_uncategorized_badge: "Non mostrare la targhetta per gli argomenti senza categoria nell'elenco degli argomenti."
diff --git a/config/locales/server.ja.yml b/config/locales/server.ja.yml
index 2c997ccda..7e797cde4 100644
--- a/config/locales/server.ja.yml
+++ b/config/locales/server.ja.yml
@@ -897,10 +897,10 @@ ja:
     automatically_download_gravatars: "アカウントの生成時、メールアドレスの変更時にGravatarをダウンロード"
     digest_topics: "ダイジェストメールに表示されるトピックの最大数"
     digest_min_excerpt_length: "ダイジェストメール内の投稿の抜粋の最小文字数"
-    default_digest_email_frequency: "ユーザがダイジェストメールを受け取る頻度のデフォルト値。ユーザは設定画面でこの値をカスタマイズできます。"
+    default_email_digest_frequency: "ユーザがダイジェストメールを受け取る頻度のデフォルト値。ユーザは設定画面でこの値をカスタマイズできます。"
     suppress_digest_email_after_days: "(n)日以上ユーザが参照していなければダイジェストメールを抑制します"
     disable_digest_emails: "全てのユーザのダイジェストメールを無効にする"
-    default_external_links_in_new_tab: "外部リンクは新しいタブで開きます。ユーザーはこの設定を変更する事が出来ます"
+    default_other_external_links_in_new_tab: "外部リンクは新しいタブで開きます。ユーザーはこの設定を変更する事が出来ます"
     detect_custom_avatars: "ユーザがプロフィール画像をアップロードしたか確認する"
     max_daily_gravatar_crawls: "Discourseがプロフィール画像の確認をgravastarに行う回数の上限"
     public_user_custom_fields: "パブリックに公開されるカスタムフィールドのホワイトリスト"
diff --git a/config/locales/server.ko.yml b/config/locales/server.ko.yml
index 0b2b79d33..d1e54c3b2 100644
--- a/config/locales/server.ko.yml
+++ b/config/locales/server.ko.yml
@@ -886,10 +886,10 @@ ko:
     automatically_download_gravatars: "사용자가 계정을 만들거나 이메일을 변경하자마자 Gravatar를 다운로드합니다."
     digest_topics: "요약 이메일에서 보여질 최대 토픽 개수"
     digest_min_excerpt_length: "요약 이메일에서 최소 포스트 발췌 수"
-    default_digest_email_frequency: "사용자가 요약 이메일을 받는 횟수 기본값. 사용자는 그들의 환경설정에서 변경할 수 있음"
+    default_email_digest_frequency: "사용자가 요약 이메일을 받는 횟수 기본값. 사용자는 그들의 환경설정에서 변경할 수 있음"
     suppress_digest_email_after_days: "(n)일동안 사이트에서 보지 못한 사용자에게는 이메일 요약을 보내지 않습니다."
     disable_digest_emails: "모든 유저들 이메일 다이제스트 못하게 하기"
-    default_external_links_in_new_tab: "다른 싸이트의 링크는 새 탭으로 연다. 사용자는 자신의 설정에 따라 바꿀 수 있음"
+    default_other_external_links_in_new_tab: "다른 싸이트의 링크는 새 탭으로 연다. 사용자는 자신의 설정에 따라 바꿀 수 있음"
     max_daily_gravatar_crawls: "하루에 Discourse가 커스텀 아파타를 위해 Gravatar를 체크하는 최대 횟수"
     public_user_custom_fields: "유저가 쓸 수 있는 공개 커스텀 필드 목록"
     staff_user_custom_fields: "스태프가 쓸 수 있는 공개 커스텀 필드 목록"
diff --git a/config/locales/server.nl.yml b/config/locales/server.nl.yml
index 9ccb24406..54fd386f9 100644
--- a/config/locales/server.nl.yml
+++ b/config/locales/server.nl.yml
@@ -840,8 +840,8 @@ nl:
     email_editable: "Gebruikers mogen hun e-mailadres na registratie nog wijzigen."
     digest_topics: "Het maximum aantal topics dat in de e-maildigest opgenomen wordt."
     digest_min_excerpt_length: "Hoeveel karakters er per bericht getoond worden in de mail digest"
-    default_digest_email_frequency: "Hoe vaak ontvangen gebruikers standaard de digestmails. Ze kunnen dit in hun eigen instellingen nog aanpassen."
-    default_external_links_in_new_tab: "Open externe links in a nieuwe tab. Gebruikers kunnen dit wijzigen in hun instellingen."
+    default_email_digest_frequency: "Hoe vaak ontvangen gebruikers standaard de digestmails. Ze kunnen dit in hun eigen instellingen nog aanpassen."
+    default_other_external_links_in_new_tab: "Open externe links in a nieuwe tab. Gebruikers kunnen dit wijzigen in hun instellingen."
     allow_profile_backgrounds: "Gebruikers mogen een profielachtergrond instellen."
     enable_mobile_theme: "Mobiele apparaten gebruiken een mobiel-vriendelijke theme met de mogelijkheid te schakelen naar de volledige site. Schakel deze optie uit als je een eigen stylesheet wil gebruiken die volledig responsive is."
     suppress_uncategorized_badge: "Laat de badge niet zien voor topics zonder categorie in de topiclijsten."
diff --git a/config/locales/server.pl_PL.yml b/config/locales/server.pl_PL.yml
index 1677c38ad..d76b6f508 100644
--- a/config/locales/server.pl_PL.yml
+++ b/config/locales/server.pl_PL.yml
@@ -796,10 +796,10 @@ pl_PL:
     email_editable: "Allow users to change their e-mail address after registration."
     digest_topics: "Maksymalna liczba tematów w podsumowaniu e-mail."
     digest_min_excerpt_length: "Minimalny wycinek wpisu (liczba znaków) w podsumowaniu e-mail."
-    default_digest_email_frequency: "How often users receive digest emails by default. They can change this setting in their preferences."
+    default_email_digest_frequency: "How often users receive digest emails by default. They can change this setting in their preferences."
     suppress_digest_email_after_days: "Nie wysyłaj podsumowań e-mail użytkownikom, którzy nie odwiedzili serwisu dłużej niż (n) dni."
     disable_digest_emails: "Wyłącz wysyłanie podsumowania e-mail wszystkim uzytkownikom. "
-    default_external_links_in_new_tab: "Otwieraj zewnętrzne odnośniki w nowej karcie. Użytkownicy mogą zmienić to ustawienie w swoich preferencjach."
+    default_other_external_links_in_new_tab: "Otwieraj zewnętrzne odnośniki w nowej karcie. Użytkownicy mogą zmienić to ustawienie w swoich preferencjach."
     allow_profile_backgrounds: "Zezwól użytkownikom na przesyłanie obrazu tła dla profilu."
     enable_mobile_theme: "Urządzenia mobilne używają dedykowanego mobilnego szablonu. Wyłącz to, jeśli chcesz użyć własnego, pojedynczego i responsywnego szablonu stylów. "
     suppress_uncategorized_badge: "Nie pokazuj etykiety z nazwą kategorii Inne na listach tematów."
diff --git a/config/locales/server.pt.yml b/config/locales/server.pt.yml
index d702d4825..a56c7fe21 100644
--- a/config/locales/server.pt.yml
+++ b/config/locales/server.pt.yml
@@ -975,10 +975,10 @@ pt:
     automatically_download_gravatars: "Descarregar Gravatars para os utilizadores após criação de conta ou mudança de email."
     digest_topics: "Número máximo de tópicos a serem apresentados no resumo do email."
     digest_min_excerpt_length: "Tamanho mínimo do excerto da mensagem no resumo do email, em caracteres."
-    default_digest_email_frequency: "Por defeito, quantas vezes os utilizadores recebem emails de resumo. Os utilizadores podem alterar esta configuração nas suas preferências."
+    default_email_digest_frequency: "Por defeito, quantas vezes os utilizadores recebem emails de resumo. Os utilizadores podem alterar esta configuração nas suas preferências."
     suppress_digest_email_after_days: "Suprimir emails de resumos para utilizadores não vistos no sítio por mais de (n) dias."
     disable_digest_emails: "Desativar os emails de resumo para todos os utilizadores."
-    default_external_links_in_new_tab: "Abrir hiperligações externas num novo separador. Os utilizadores podem alterar isto nas suas preferências."
+    default_other_external_links_in_new_tab: "Abrir hiperligações externas num novo separador. Os utilizadores podem alterar isto nas suas preferências."
     detect_custom_avatars: "Se deve ou não verificar que os utilizadores carregaram fotografias de perfil personalizadas."
     max_daily_gravatar_crawls: "Número máximo de vezes que o Discourse irá verificar o Gravatar para avatars personalizados, por dia"
     public_user_custom_fields: "Lista de campos personalizados para um utilizador e que podem ser exibidos publicamente."
diff --git a/config/locales/server.pt_BR.yml b/config/locales/server.pt_BR.yml
index 6ea462196..c1d7dbd42 100644
--- a/config/locales/server.pt_BR.yml
+++ b/config/locales/server.pt_BR.yml
@@ -938,10 +938,10 @@ pt_BR:
     automatically_download_gravatars: "Fazer download de Gravatars dos usuários ao criar conta ou mudança de email."
     digest_topics: "O número máximo de tópicos a serem mostrados no resumo via email."
     digest_min_excerpt_length: "O excerto mínimo de post no resumo via email, em caracteres."
-    default_digest_email_frequency: "Quantas vezes os usuários recebem emails de resumo por padrão. Eles podem alterar essa configuração em suas preferências."
+    default_email_digest_frequency: "Quantas vezes os usuários recebem emails de resumo por padrão. Eles podem alterar essa configuração em suas preferências."
     suppress_digest_email_after_days: "Suprimir emails de resumo para usuários não vistos no site há mais do que (n) dias."
     disable_digest_emails: "Desabilitar emails de resumo para todos os usuários."
-    default_external_links_in_new_tab: "Abrir links externos em uma nova guia. Os usuários podem mudar isso em suas preferências."
+    default_other_external_links_in_new_tab: "Abrir links externos em uma nova guia. Os usuários podem mudar isso em suas preferências."
     max_daily_gravatar_crawls: "Número máximo de vezes que o Discourse irá checar o Gravatar por avatares personalizados em um dia"
     public_user_custom_fields: "Um conjunto de campos personalizados para um usuário que podem ser apresentados publicamente."
     staff_user_custom_fields: "Um conjunto de campos personalizados para um usuário que pode ser mostrado para membros da equipe."
diff --git a/config/locales/server.ro.yml b/config/locales/server.ro.yml
index fc589c87c..d3bef4d66 100644
--- a/config/locales/server.ro.yml
+++ b/config/locales/server.ro.yml
@@ -770,7 +770,7 @@ ro:
     automatically_download_gravatars: "Descarcă Gravatare pentru utilizatori la crearea contului sau schimbarea email-ului."
     digest_topics: "Numărul maxim de discuții arătate în email-ul rezumat."
     digest_min_excerpt_length: "Numărul minimum de extrase din postări din email-ul rezumat, în caractere."
-    default_digest_email_frequency: "Cat de des utliziatorii primesc emailuri rezumat din oficiu. Utilizatorii pot schimba această opțiune în preferințe."
+    default_email_digest_frequency: "Cat de des utliziatorii primesc emailuri rezumat din oficiu. Utilizatorii pot schimba această opțiune în preferințe."
     max_daily_gravatar_crawls: "Numărul maxim de verificări făcute de Discourse pentru existența unui gravatar preferențial într-o zi"
     allow_profile_backgrounds: "Permite utilizatorilor să încarce fundaluri de profil."
     sequential_replies_threshold: "Numărul de postări la rând într-o discuție până să-i fie amintit utilizatorului că sunt prea multe răspunsuri secvențiale. "
diff --git a/config/locales/server.ru.yml b/config/locales/server.ru.yml
index faade29e2..49f466e65 100644
--- a/config/locales/server.ru.yml
+++ b/config/locales/server.ru.yml
@@ -986,10 +986,10 @@ ru:
     automatically_download_gravatars: "Скачивать аватарку Gravatar пользователя во время создания учетной записи или изменения e-mail."
     digest_topics: "Максимальное количество тем в письме - сводке новостей."
     digest_min_excerpt_length: "Минимальная длина (в символах) вытяжки из сообщения в письме - сводке новостей."
-    default_digest_email_frequency: "Как часто пользователи получают дайджест по умолчанию. Возможно изменение этой настройки каждым пользователем."
+    default_email_digest_frequency: "Как часто пользователи получают дайджест по умолчанию. Возможно изменение этой настройки каждым пользователем."
     suppress_digest_email_after_days: "Не рассылать новости для пользователей, которые не заходили на сайт в течении (n) дней."
     disable_digest_emails: "Отключить рассылку новостей  для всех пользователей."
-    default_external_links_in_new_tab: "Открывать внешние ссылки в новом окне. Пользователи могут изменить данное поведение в настройках."
+    default_other_external_links_in_new_tab: "Открывать внешние ссылки в новом окне. Пользователи могут изменить данное поведение в настройках."
     max_daily_gravatar_crawls: "Максимальное количество загрузок аватаорок с Gravatar за один день"
     public_user_custom_fields: "Список разрешенных дополнительных полей пользователей, которые могут быть отображены публично."
     staff_user_custom_fields: "Список разрешенных дополнительных полей пользователей, которые могут быть отображены для модераторов."
diff --git a/config/locales/server.sq.yml b/config/locales/server.sq.yml
index 3cf162ef8..b2639ae2f 100644
--- a/config/locales/server.sq.yml
+++ b/config/locales/server.sq.yml
@@ -971,10 +971,10 @@ sq:
     automatically_download_gravatars: "Download Gravatars for users upon account creation or email change."
     digest_topics: "The maximum number of topics to display in the email digest."
     digest_min_excerpt_length: "Minimum post excerpt in the email digest, in characters."
-    default_digest_email_frequency: "How often users receive digest emails by default. They can change this setting in their preferences."
+    default_email_digest_frequency: "How often users receive digest emails by default. They can change this setting in their preferences."
     suppress_digest_email_after_days: "Suppress digest emails for users not seen on the site for more than (n) days."
     disable_digest_emails: "Disable digest emails for all users."
-    default_external_links_in_new_tab: "Open external links in a new tab. Users can change this in their preferences."
+    default_other_external_links_in_new_tab: "Open external links in a new tab. Users can change this in their preferences."
     detect_custom_avatars: "Whether or not to check that users have uploaded custom profile pictures."
     max_daily_gravatar_crawls: "Maximum number of times Discourse will check Gravatar for custom avatars in a day"
     public_user_custom_fields: "A whitelist of custom fields for a user that can be shown publicly."
diff --git a/config/locales/server.sv.yml b/config/locales/server.sv.yml
index 6e939fcfd..2c7bcaaf3 100644
--- a/config/locales/server.sv.yml
+++ b/config/locales/server.sv.yml
@@ -719,7 +719,7 @@ sv:
     disable_emails: "Förhindra Discourse från att skicka någon form av e-post"
     pop3_polling_ssl: "Använd SSL vid anslutning till POP3-servern. (Rekommenderat)"
     email_editable: "Tillåt användare att ändra deras e-postadress efter registrering."
-    default_digest_email_frequency: "Hur ofta användare får emailutskick som standard. De kan ändra detta val under sina inställningar."
+    default_email_digest_frequency: "Hur ofta användare får emailutskick som standard. De kan ändra detta val under sina inställningar."
     enable_user_directory: "Tillhandahåll en bläddringsbar användarkatalog"
     allow_anonymous_posting: "Tillåt användare att växla till anonymt läge"
     anonymous_posting_min_trust_level: "Lägsta förtroendenivå som krävs för att aktivera anonyma inlägg"
diff --git a/config/locales/server.tr_TR.yml b/config/locales/server.tr_TR.yml
index 053737520..d938e4cf6 100644
--- a/config/locales/server.tr_TR.yml
+++ b/config/locales/server.tr_TR.yml
@@ -889,10 +889,10 @@ tr_TR:
     automatically_download_gravatars: "Hesap oluşturma veya e-posta değişikliği esnasında kullanıcılar için Gravatarları indir"
     digest_topics: "Özet e-postalarda yer alacak en fazla konu sayısı. "
     digest_min_excerpt_length: "Özet e-postalarında, gönderi alıntılarında olması gereken en az karakter sayısı."
-    default_digest_email_frequency: "Varsayılan olarak, özet e-postalar hangi sıklıkta gönderilsin? Üyeler, ayarlar sayfasından bu değeri değiştirebilir."
+    default_email_digest_frequency: "Varsayılan olarak, özet e-postalar hangi sıklıkta gönderilsin? Üyeler, ayarlar sayfasından bu değeri değiştirebilir."
     suppress_digest_email_after_days: "Siteye (n) günden fazla süredir uğramayan kullanıcılar için özet e-posta gönderimini durdur"
     disable_digest_emails: "Tüm kullanıcılar için özet e-postalarını devre dışı bırak."
-    default_external_links_in_new_tab: "Dış bağlantıları yeni sekmede aç. Üyeler, ayarlar sayfasından bu ayarı değiştirebilir."
+    default_other_external_links_in_new_tab: "Dış bağlantıları yeni sekmede aç. Üyeler, ayarlar sayfasından bu ayarı değiştirebilir."
     max_daily_gravatar_crawls: "Discourse'un gün içinde özel avatarlar için Gravatar'ı en fazla kaç kere kontrol edeceği."
     public_user_custom_fields: "Kullanıcıların için, herkes tarafından görüntülenebilir özel alanların beyaz listesi."
     staff_user_custom_fields: "Kullanıcıların için, sadece görevlilere görüntülenebilir özel alanların beyaz listesi."
diff --git a/config/locales/server.uk.yml b/config/locales/server.uk.yml
index 9ad9d639e..07262f513 100644
--- a/config/locales/server.uk.yml
+++ b/config/locales/server.uk.yml
@@ -371,8 +371,8 @@ uk:
     delete_all_posts_max: "Максимальне число дописів, які можна видалити за один раз кнопкою \"Видалити всі дописи\". Якщо користувач має більше дописів, ніж це число, їх не можна буде видалити за один раз, і користувача також."
     username_change_period: "Кількість днів після реєстрації, протягом яких новим обліковим записам можна змінювати своє ім'я користувача (0 щоб заборонити зміну імені користувача)."
     email_editable: "Дозволити користувачам змінювати свою електронну скриньку після реєстрації."
-    default_digest_email_frequency: "Як часто користувачі отримують листи зі стислим викладом новин за замовчуванням. Вони можуть змінити це у своїх налаштуваннях."
-    default_external_links_in_new_tab: "Відкривати нові посилання у новій вкладці. Користувачі можуть змінити це у своїх налаштуваннях."
+    default_email_digest_frequency: "Як часто користувачі отримують листи зі стислим викладом новин за замовчуванням. Вони можуть змінити це у своїх налаштуваннях."
+    default_other_external_links_in_new_tab: "Відкривати нові посилання у новій вкладці. Користувачі можуть змінити це у своїх налаштуваннях."
     allow_profile_backgrounds: "Дозволити користувачам завантажувати фони профілю."
     enable_mobile_theme: "Мобільні пристрої використовуватимуть тему, дружню для них, з можливістю перемикатися на повний сайт. Відключіть це, якщо хочете використовувати власну, повністю чутливу, таблицю стилів."
     display_name_on_posts: "Показувати повні імена користувачів на їх дописах у додаток до їх @username."
diff --git a/config/locales/server.zh_CN.yml b/config/locales/server.zh_CN.yml
index 13821a111..5c834650d 100644
--- a/config/locales/server.zh_CN.yml
+++ b/config/locales/server.zh_CN.yml
@@ -937,10 +937,10 @@ zh_CN:
     automatically_download_gravatars: "为注册或更改邮箱的用户下载 Gravatar 头像。"
     digest_topics: "邮件摘要中显示的最大主题数目。"
     digest_min_excerpt_length: "在邮件摘要中每个帖子最少显示的字符数量。"
-    default_digest_email_frequency: "用户收到摘要邮件的默认间隔。用户可以在参数设置中更改这个设置。"
+    default_email_digest_frequency: "用户收到摘要邮件的默认间隔。用户可以在参数设置中更改这个设置。"
     suppress_digest_email_after_days: "不发送摘要邮件给超过 (n) 天未出现的用户。"
     disable_digest_emails: "为所有用户禁用摘要邮件。"
-    default_external_links_in_new_tab: "在新标签页中打开外部链接。用户可以在参数设置中更改这个设置。"
+    default_other_external_links_in_new_tab: "在新标签页中打开外部链接。用户可以在参数设置中更改这个设置。"
     detect_custom_avatars: "检测用户是否上传了自定义个人头像。"
     max_daily_gravatar_crawls: "一天内 Discourse 将自动检查 gravatar 自定义头像的次数"
     public_user_custom_fields: "可公开显示的用户自定义属性白名单"
diff --git a/config/locales/server.zh_TW.yml b/config/locales/server.zh_TW.yml
index 4c8efad4c..dd0d0c985 100644
--- a/config/locales/server.zh_TW.yml
+++ b/config/locales/server.zh_TW.yml
@@ -769,10 +769,10 @@ zh_TW:
     automatically_download_gravatars: "當用戶註冊或更改EMail時下載 Gravatars 圖片"
     digest_topics: "EMail 摘要中顯示的最大話題數量"
     digest_min_excerpt_length: "EMail 摘要中每篇文章最少顯示的字元數量"
-    default_digest_email_frequency: "用戶收到摘要郵件的默認間隔。用戶可以在設定中更改。"
+    default_email_digest_frequency: "用戶收到摘要郵件的默認間隔。用戶可以在設定中更改。"
     suppress_digest_email_after_days: "不發送摘要郵件給超過 (n) 天閒置的用戶。"
     disable_digest_emails: "禁用發送摘要郵件給所有用戶。"
-    default_external_links_in_new_tab: "以新分頁開啟所有外部連結,用戶可於個人偏好設定更改設定。"
+    default_other_external_links_in_new_tab: "以新分頁開啟所有外部連結,用戶可於個人偏好設定更改設定。"
     max_daily_gravatar_crawls: "一天內 Discourse 將自動檢查 Gravatar 自訂個人圖示的次數"
     public_user_custom_fields: "用戶可設定公開顯示的自定欄位白名單。"
     staff_user_custom_fields: "用戶可設定只給管理員顯示的自定欄位白名單。"
diff --git a/config/site_settings.yml b/config/site_settings.yml
index 3dd9f0305..7720cf890 100644
--- a/config/site_settings.yml
+++ b/config/site_settings.yml
@@ -70,7 +70,6 @@ basic:
     min: 0
   limit_suggested_to_category:
     default: false
-  default_external_links_in_new_tab: false
   track_external_right_clicks:
     client: true
     default: false
@@ -282,7 +281,6 @@ users:
     default: ''
     hidden: true
   username_change_period: 3
-  auto_track_topics_after: 240000
   email_editable: true
   logout_redirect:
     client: true
@@ -474,9 +472,6 @@ email:
   email_posts_context: 5
   digest_min_excerpt_length: 100
   digest_topics: 20
-  default_digest_email_frequency:
-    default: 7
-    enum: 'DigestEmailSiteSetting'
   suppress_digest_email_after_days: 365
   disable_digest_emails:
     default: false
@@ -841,7 +836,6 @@ uncategorized:
   max_similar_results: 5
   minimum_topics_similar: 50
 
-  new_topic_duration_minutes: 2880
   previous_visit_timeout_hours: 1
   staff_like_weight: 3
   topic_view_duration_hours: 8
@@ -959,3 +953,34 @@ uncategorized:
   privacy_topic_id:
     default: -1
     hidden: true
+
+user_preferences:
+  default_email_digest_frequency:
+    enum: 'DigestEmailSiteSetting'
+    default: 7
+  default_email_private_messages: true
+  default_email_direct: true
+  default_email_mailing_list_mode: false
+  default_email_always: false
+
+  default_other_new_topic_duration_minutes:
+    enum: 'NewTopicDurationSiteSetting'
+    default: 2880
+  default_other_auto_track_topics_after_msecs:
+    enum: 'AutoTrackDurationSiteSetting'
+    default: 240000
+  default_other_external_links_in_new_tab: false
+  default_other_enable_quoting: true
+  default_other_dynamic_favicon: false
+  default_other_disable_jump_reply: false
+  default_other_edit_history_public: false
+
+  default_categories_watching:
+    type: category_list
+    default: ''
+  default_categories_tracking:
+    type: category_list
+    default: ''
+  default_categories_muted:
+    type: category_list
+    default: ''
diff --git a/lib/site_setting_extension.rb b/lib/site_setting_extension.rb
index f4c7c1df2..19ad366f0 100644
--- a/lib/site_setting_extension.rb
+++ b/lib/site_setting_extension.rb
@@ -21,7 +21,7 @@ module SiteSettingExtension
   end
 
   def types
-    @types ||= Enum.new(:string, :time, :fixnum, :float, :bool, :null, :enum, :list, :url_list, :host_list)
+    @types ||= Enum.new(:string, :time, :fixnum, :float, :bool, :null, :enum, :list, :url_list, :host_list, :category_list)
   end
 
   def mutex
diff --git a/lib/site_setting_validations.rb b/lib/site_setting_validations.rb
index 6ed44df80..5a9fbb2fb 100644
--- a/lib/site_setting_validations.rb
+++ b/lib/site_setting_validations.rb
@@ -14,4 +14,13 @@ module SiteSettingValidations
     validate_error :min_username_length_range if new_val < SiteSetting.min_username_length
     validate_error :max_username_length_exists if User.where('length(username) > ?', new_val).exists?
   end
+
+  def validate_default_categories(new_val)
+    validate_error :default_categories_already_selected if (new_val.split("|").to_set & SiteSetting.default_categories_selected).size > 0
+  end
+
+  alias_method :validate_default_categories_watching, :validate_default_categories
+  alias_method :validate_default_categories_tracking, :validate_default_categories
+  alias_method :validate_default_categories_muted, :validate_default_categories
+
 end
diff --git a/spec/components/site_settings/yaml_loader_spec.rb b/spec/components/site_settings/yaml_loader_spec.rb
index a6800a113..6fc59b623 100644
--- a/spec/components/site_settings/yaml_loader_spec.rb
+++ b/spec/components/site_settings/yaml_loader_spec.rb
@@ -64,7 +64,7 @@ describe SiteSettings::YamlLoader do
   end
 
   it "can load enum settings" do
-    receiver.expects(:setting).with('email', 'default_digest_email_frequency', 7, {enum: 'DigestEmailSiteSetting'})
+    receiver.expects(:setting).with('email', 'default_email_digest_frequency', 7, {enum: 'DigestEmailSiteSetting'})
     receiver.load_yaml(enum)
   end
 
diff --git a/spec/fixtures/site_settings/enum.yml b/spec/fixtures/site_settings/enum.yml
index 999b30b5e..638caeee2 100644
--- a/spec/fixtures/site_settings/enum.yml
+++ b/spec/fixtures/site_settings/enum.yml
@@ -1,4 +1,4 @@
 email:
-  default_digest_email_frequency:
+  default_email_digest_frequency:
     default: 7
     enum: 'DigestEmailSiteSetting'
diff --git a/spec/jobs/enqueue_digest_emails_spec.rb b/spec/jobs/enqueue_digest_emails_spec.rb
index 2c32d3431..459e08705 100644
--- a/spec/jobs/enqueue_digest_emails_spec.rb
+++ b/spec/jobs/enqueue_digest_emails_spec.rb
@@ -3,11 +3,11 @@ require_dependency 'jobs/base'
 
 describe Jobs::EnqueueDigestEmails do
 
-
   describe '#target_users' do
 
     context 'disabled digests' do
-      let!(:user_no_digests) { Fabricate(:active_user, email_digests: false, last_emailed_at: 8.days.ago, last_seen_at: 10.days.ago) }
+      before { SiteSetting.stubs(:default_email_digest_frequency).returns("") }
+      let!(:user_no_digests) { Fabricate(:active_user, last_emailed_at: 8.days.ago, last_seen_at: 10.days.ago) }
 
       it "doesn't return users with email disabled" do
         expect(Jobs::EnqueueDigestEmails.new.target_user_ids.include?(user_no_digests.id)).to eq(false)
diff --git a/spec/jobs/notify_mailing_list_subscribers_spec.rb b/spec/jobs/notify_mailing_list_subscribers_spec.rb
index bd70b7d3d..84e94dc58 100644
--- a/spec/jobs/notify_mailing_list_subscribers_spec.rb
+++ b/spec/jobs/notify_mailing_list_subscribers_spec.rb
@@ -3,62 +3,69 @@ require "spec_helper"
 describe Jobs::NotifyMailingListSubscribers do
 
   context "with mailing list on" do
-    let(:user) { Fabricate(:user, mailing_list_mode: true) }
+    before { SiteSetting.stubs(:default_email_mailing_list_mode).returns(true) }
 
-    context "with a valid post" do
+    context "with mailing list on" do
+      let(:user) { Fabricate(:user) }
+
+      context "with a valid post" do
+        let!(:post) { Fabricate(:post, user: user) }
+
+        it "sends the email to the user" do
+          UserNotifications.expects(:mailing_list_notify).with(user, post).once
+          Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id)
+        end
+      end
+
+      context "with a deleted post" do
+        let!(:post) { Fabricate(:post, user: user, deleted_at: Time.now) }
+
+        it "doesn't send the email to the user" do
+          UserNotifications.expects(:mailing_list_notify).with(user, post).never
+          Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id)
+        end
+      end
+
+      context "with a user_deleted post" do
+        let!(:post) { Fabricate(:post, user: user, user_deleted: true) }
+
+        it "doesn't send the email to the user" do
+          UserNotifications.expects(:mailing_list_notify).with(user, post).never
+          Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id)
+        end
+      end
+
+      context "with a deleted topic" do
+        let!(:post) { Fabricate(:post, user: user) }
+
+        before do
+          post.topic.update_column(:deleted_at, Time.now)
+        end
+
+        it "doesn't send the email to the user" do
+          UserNotifications.expects(:mailing_list_notify).with(user, post).never
+          Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id)
+        end
+      end
+
+    end
+
+    context "to an anonymous user with mailing list on" do
+      let(:user) { Fabricate(:anonymous) }
       let!(:post) { Fabricate(:post, user: user) }
 
-      it "sends the email to the user" do
-        UserNotifications.expects(:mailing_list_notify).with(user, post).once
-        Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id)
-      end
-    end
-
-    context "with a deleted post" do
-      let!(:post) { Fabricate(:post, user: user, deleted_at: Time.now) }
-
       it "doesn't send the email to the user" do
         UserNotifications.expects(:mailing_list_notify).with(user, post).never
         Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id)
       end
     end
 
-    context "with a user_deleted post" do
-      let!(:post) { Fabricate(:post, user: user, user_deleted: true) }
-
-      it "doesn't send the email to the user" do
-        UserNotifications.expects(:mailing_list_notify).with(user, post).never
-        Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id)
-      end
-    end
-
-    context "with a deleted topic" do
-      let!(:post) { Fabricate(:post, user: user) }
-
-      before do
-        post.topic.update_column(:deleted_at, Time.now)
-      end
-
-      it "doesn't send the email to the user" do
-        UserNotifications.expects(:mailing_list_notify).with(user, post).never
-        Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id)
-      end
-    end
-
-  end
-
-  context "to an anonymous user with mailing list on" do
-    let(:user) { Fabricate(:anonymous, mailing_list_mode: true) }
-    let!(:post) { Fabricate(:post, user: user) }
-
-    it "doesn't send the email to the user" do
-      UserNotifications.expects(:mailing_list_notify).with(user, post).never
-      Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id)
-    end
   end
 
   context "with mailing list off" do
-    let(:user) { Fabricate(:user, mailing_list_mode: false) }
+    before { SiteSetting.stubs(:default_email_mailing_list_mode).returns(false) }
+
+    let(:user) { Fabricate(:user) }
     let!(:post) { Fabricate(:post, user: user) }
 
     it "doesn't send the email to the user" do
diff --git a/spec/models/topic_user_spec.rb b/spec/models/topic_user_spec.rb
index ce8ec92a9..4498d6e36 100644
--- a/spec/models/topic_user_spec.rb
+++ b/spec/models/topic_user_spec.rb
@@ -181,13 +181,13 @@ describe TopicUser do
 
       it 'should automatically track topics after they are read for long enough' do
         expect(topic_new_user.notification_level).to eq(TopicUser.notification_levels[:regular])
-        TopicUser.update_last_read(new_user, topic.id, 2, 1001)
+        TopicUser.update_last_read(new_user, topic.id, 2, SiteSetting.default_other_auto_track_topics_after_msecs + 1)
         expect(TopicUser.get(topic, new_user).notification_level).to eq(TopicUser.notification_levels[:tracking])
       end
 
       it 'should not automatically track topics after they are read for long enough if changed manually' do
         TopicUser.change(new_user, topic, notification_level: TopicUser.notification_levels[:regular])
-        TopicUser.update_last_read(new_user, topic, 2, 1001)
+        TopicUser.update_last_read(new_user, topic, 2, SiteSetting.default_other_auto_track_topics_after_msecs + 1)
         expect(topic_new_user.notification_level).to eq(TopicUser.notification_levels[:regular])
       end
     end
@@ -256,9 +256,13 @@ describe TopicUser do
 
     it "will receive email notification for every topic" do
       user1 = Fabricate(:user)
-      user2 = Fabricate(:user, mailing_list_mode: true)
+
+      SiteSetting.stubs(:default_email_mailing_list_mode).returns(true)
+
+      user2 = Fabricate(:user)
       post = create_post
-      user3 = Fabricate(:user, mailing_list_mode: true)
+
+      user3 = Fabricate(:user)
       create_post(topic_id: post.topic_id)
 
       # mails posts from earlier topics
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 7f3aeb681..e2bd09f77 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -156,24 +156,6 @@ describe User do
       expect(subject.email_direct).to eq(true)
     end
 
-    context 'digest emails' do
-      it 'defaults to digests every week' do
-        expect(subject.email_digests).to eq(true)
-        expect(subject.digest_after_days).to eq(7)
-      end
-
-      it 'uses default_digest_email_frequency' do
-        SiteSetting.stubs(:default_digest_email_frequency).returns(1)
-        expect(subject.email_digests).to eq(true)
-        expect(subject.digest_after_days).to eq(1)
-      end
-
-      it 'disables digests by default if site setting says so' do
-        SiteSetting.stubs(:default_digest_email_frequency).returns('')
-        expect(subject.email_digests).to eq(false)
-      end
-    end
-
     context 'after_save' do
       before { subject.save }
 
@@ -1223,4 +1205,50 @@ describe User do
     end
   end
 
+  context "when user preferences are overriden" do
+
+    before do
+      SiteSetting.stubs(:default_email_digest_frequency).returns(1) # daily
+      SiteSetting.stubs(:default_email_private_messages).returns(false)
+      SiteSetting.stubs(:default_email_direct).returns(false)
+      SiteSetting.stubs(:default_email_mailing_list_mode).returns(true)
+      SiteSetting.stubs(:default_email_always).returns(true)
+
+      SiteSetting.stubs(:default_other_new_topic_duration_minutes).returns(-1) # not viewed
+      SiteSetting.stubs(:default_other_auto_track_topics_after_msecs).returns(0) # immediately
+      SiteSetting.stubs(:default_other_external_links_in_new_tab).returns(true)
+      SiteSetting.stubs(:default_other_enable_quoting).returns(false)
+      SiteSetting.stubs(:default_other_dynamic_favicon).returns(true)
+      SiteSetting.stubs(:default_other_disable_jump_reply).returns(true)
+      SiteSetting.stubs(:default_other_edit_history_public).returns(true)
+
+      SiteSetting.stubs(:default_categories_watching).returns("1")
+      SiteSetting.stubs(:default_categories_tracking).returns("2")
+      SiteSetting.stubs(:default_categories_muted).returns("3")
+    end
+
+    it "has overriden preferences" do
+      user = Fabricate(:user)
+
+      expect(user.digest_after_days).to eq(1)
+      expect(user.email_private_messages).to eq(false)
+      expect(user.email_direct).to eq(false)
+      expect(user.mailing_list_mode).to eq(true)
+      expect(user.email_always).to eq(true)
+
+      expect(user.new_topic_duration_minutes).to eq(-1)
+      expect(user.auto_track_topics_after_msecs).to eq(0)
+      expect(user.external_links_in_new_tab).to eq(true)
+      expect(user.enable_quoting).to eq(false)
+      expect(user.dynamic_favicon).to eq(true)
+      expect(user.disable_jump_reply).to eq(true)
+      expect(user.edit_history_public).to eq(true)
+
+      expect(CategoryUser.lookup(user, :watching).pluck(:category_id)).to eq([1])
+      expect(CategoryUser.lookup(user, :tracking).pluck(:category_id)).to eq([2])
+      expect(CategoryUser.lookup(user, :muted).pluck(:category_id)).to eq([3])
+    end
+
+  end
+
 end