diff --git a/.gitignore b/.gitignore
index 2ae4ddd56cc016c35b9152208a8b4a890dcd55d9..fdec437e0c511fe7c8546584cc2139143273c897 100644
--- a/.gitignore
+++ b/.gitignore
@@ -66,3 +66,4 @@ tramp
 ecosystem.json
 pm2.json
 settings.json
+build.sh
diff --git a/.meteor/packages b/.meteor/packages
index 16ac606c7c0b9cca1be870b9529e95451a7807d9..2e0df8c465da7829a7707619d0fe4e256716afb5 100644
--- a/.meteor/packages
+++ b/.meteor/packages
@@ -41,6 +41,7 @@ rocketchat:lib
 rocketchat:authorization
 rocketchat:autolinker
 rocketchat:channel-settings
+rocketchat:channel-settings-mail-messages
 rocketchat:colors
 rocketchat:custom-oauth
 rocketchat:emojione
diff --git a/.meteor/versions b/.meteor/versions
index 179bf18b1d60e02913851bd389763500a3b0aacc..11a58480adcda44c7c7df3fa48ccabaf87c5a7d3 100644
--- a/.meteor/versions
+++ b/.meteor/versions
@@ -7,7 +7,7 @@ accounts-oauth@1.1.8
 accounts-password@1.1.4
 accounts-twitter@1.0.6
 alanning:roles@1.2.14
-aldeed:simple-schema@1.5.1
+aldeed:simple-schema@1.5.2
 arunoda:streams@0.1.17
 autoupdate@1.2.4
 babel-compiler@5.8.24_1
@@ -25,7 +25,7 @@ cfs:http-methods@0.0.30
 check@1.1.0
 chrismbeckett:toastr@2.1.2_1
 coffeescript@1.0.11
-cosmos:browserify@0.9.2
+cosmos:browserify@0.9.3
 dandv:caret-position@2.1.1
 ddp@1.2.2
 ddp-client@1.2.1
@@ -39,7 +39,7 @@ ecmascript@0.1.6
 ecmascript-runtime@0.2.6
 ejson@1.0.7
 email@1.0.8
-emojione:emojione@1.5.2
+emojione:emojione@2.0.0
 facebook@1.2.2
 fastclick@1.0.7
 francocatena:status@1.5.0
@@ -75,7 +75,7 @@ livedata@1.0.15
 localstorage@1.0.5
 logging@1.0.8
 matb33:collection-hooks@0.8.1
-mdg:validation-error@0.1.0
+mdg:validation-error@0.2.0
 meteor@1.1.10
 meteor-base@1.0.1
 meteor-developer@1.1.5
@@ -125,6 +125,7 @@ rocketchat:assets@0.0.1
 rocketchat:authorization@0.0.1
 rocketchat:autolinker@0.0.1
 rocketchat:channel-settings@0.0.1
+rocketchat:channel-settings-mail-messages@0.0.1
 rocketchat:colors@0.0.1
 rocketchat:cors@0.0.1
 rocketchat:custom-oauth@1.0.0
diff --git a/.sandstorm/sandstorm-pkgdef.capnp b/.sandstorm/sandstorm-pkgdef.capnp
index ec6a58efe8ca90cd6b1fdbccbce2f8719b95d3a5..9e2a5f678efa6bdaf3a0b2f2f7c1c9bc03d10814 100644
--- a/.sandstorm/sandstorm-pkgdef.capnp
+++ b/.sandstorm/sandstorm-pkgdef.capnp
@@ -21,7 +21,7 @@ const pkgdef :Spk.PackageDefinition = (
 
     appVersion = 6,  # Increment this for every release.
 
-    appMarketingVersion = (defaultText = "0.10.1"),
+    appMarketingVersion = (defaultText = "0.10.2"),
     # Human-readable representation of appVersion. Should match the way you
     # identify versions of your app in documentation and marketing.
 
diff --git a/build.sh b/example-build.sh
similarity index 100%
rename from build.sh
rename to example-build.sh
diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json
index 7de4cc7c6c107efd08eb10b10cec3e0911aeacb4..bfe22fc2fd4710b3c878aa2e6cc19e03f784b77c 100644
--- a/i18n/en.i18n.json
+++ b/i18n/en.i18n.json
@@ -76,6 +76,7 @@
   "API_Embed" : "Embed",
   "API_EmbedDisabledFor" : "Disable Embed for Users",
   "API_EmbedDisabledFor_Description" : "Comma-separated list of usernames",
+  "Archive" : "Archive",
   "are_also_typing" : "are also typing",
   "are_typing" : "are typing",
   "Are_you_sure" : "Are you sure?",
@@ -139,6 +140,8 @@
   "Disable_New_Room_Notification" : "Disable New Room Notification",
   "Do_you_want_to_change_to_s_question" : "Do you want to change to <strong>%s</strong>?",
   "Drop_to_upload_file" : "Drop to upload file",
+  "Duplicate_archived_channel_name" : "An archived Channel with name '%s' exists",
+  "Duplicate_archived_private_group_name" : "An archived Private Group with name '%s' exists",
   "Duplicate_channel_name" : "A Channel with name '%s' exists",
   "Duplicate_private_group_name" : "A Private Group with name '%s' exists",
   "E-mail" : "E-mail",
@@ -217,8 +220,8 @@
   "italics" : "italics",
   "join" : "Join",
   "Join_the_Community" : "Join the Community",
-  "Jump_to_recent_messages" : "Jump to recent messages",
   "Jump_to_message" : "Jump to message",
+  "Jump_to_recent_messages" : "Jump to recent messages",
   "Language" : "Language",
   "Language_Version" : "English Version",
   "Last_login" : "Last login",
@@ -383,10 +386,12 @@
   "Restart" : "Restart",
   "Restart_the_server" : "Restart the server",
   "Room" : "Room",
+  "Room_archived" : "Room archived",
   "Room_has_been_deleted" : "Room has been deleted",
   "Room_name_changed" : "Room name changed to: <em>__room_name__</em> by <em>__user_by__</em>",
   "Room_name_changed_successfully" : "Room name changed successfully",
   "Room_not_found" : "Room not found",
+  "Room_unarchived" : "Room unarchived",
   "Room_uploaded_file_list" : "Files List",
   "Room_uploaded_file_list_empty" : "No files available.",
   "room_user_count" : "%s users",
@@ -426,6 +431,7 @@
   "Settings_updated" : "Settings updated",
   "Should_be_a_URL_of_an_image" : "Should be a URL of an image.",
   "Should_exists_a_user_with_this_username" : "The user must already exist.",
+  "Showing_archived_results" : "<p>Showing <b>%s</b> archived results</p>",
   "Showing_online_users" : "Showing <b>__total_online__</b> of __total__ users",
   "Showing_results" : "<p>Showing <b>%s</b> results</p>",
   "Silence" : "Silence",
@@ -477,6 +483,7 @@
   "There_is_no_integrations" : "There is no integrations",
   "This_is_a_push_test_messsage" : "This is a push test messsage",
   "True" : "True",
+  "Unarchive" : "Unarchive",
   "Unmute_user" : "Unmute user",
   "Unnamed" : "Unnamed",
   "Unread_Rooms" : "Unread Rooms",
@@ -548,4 +555,4 @@
   "Your_entry_has_been_deleted" : "Your entry has been deleted.",
   "Your_Open_Source_solution" : "Your own Open Source chat solution",
   "Your_push_was_sent_to_s_devices" : "Your push was sent to %s devices"
-}
\ No newline at end of file
+}
diff --git a/packages/rocketchat-authorization/server/startup.coffee b/packages/rocketchat-authorization/server/startup.coffee
index 1fc3643b4d276786ecb0c5857ab6f8677bc420d1..663f7354970ade72d0a74e1c673df4574256d43f 100644
--- a/packages/rocketchat-authorization/server/startup.coffee
+++ b/packages/rocketchat-authorization/server/startup.coffee
@@ -27,6 +27,9 @@ Meteor.startup ->
 		{ _id: 'edit-other-user-info',
 		roles : ['admin']}
 
+		{ _id: 'edit-other-user-password',
+		roles : ['admin']}
+
 		{ _id: 'assign-admin-role',
 		roles : ['admin']}
 
diff --git a/packages/rocketchat-channel-settings-mail-messages/client/lib/startup.coffee b/packages/rocketchat-channel-settings-mail-messages/client/lib/startup.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..9cf0b62207494f8797dd02f11c62b9e1f9bb2d36
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/client/lib/startup.coffee
@@ -0,0 +1,11 @@
+Meteor.startup ->
+	RocketChat.ChannelSettings.addOption
+		id: 'mail-messages'
+		template: 'channelSettingsMailMessages'
+		validation: ->
+			return RocketChat.authz.hasAllPermission('mail-messages')
+
+	RocketChat.callbacks.add 'roomExit', (mainNode) ->
+		instance = Blaze.getView($('.messages-box')?[0])?.templateInstance()
+		instance?.resetSelection(false)
+	, RocketChat.callbacks.priority.MEDIUM, 'room-exit-mail-messages'
diff --git a/packages/rocketchat-channel-settings-mail-messages/client/stylesheets/mail-messages.less b/packages/rocketchat-channel-settings-mail-messages/client/stylesheets/mail-messages.less
new file mode 100644
index 0000000000000000000000000000000000000000..6b5e9dd4a5b695c7fb866492494ac21dbd808a9f
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/client/stylesheets/mail-messages.less
@@ -0,0 +1,24 @@
+.flex-tab {
+	.mail-message {
+		form {
+			margin-top: 20px;
+
+			.input-line.double-col {
+				margin-bottom: 20px;
+
+				label {
+					line-height: 15px;
+				}
+
+				div {
+					line-height: 15px;
+					i.octicon {
+						font-size: 13px;
+						opacity: 0.4;
+						vertical-align: top;
+					}
+				}
+			}
+		}
+	}
+}
diff --git a/packages/rocketchat-channel-settings-mail-messages/client/views/channelSettingsMailMessages.coffee b/packages/rocketchat-channel-settings-mail-messages/client/views/channelSettingsMailMessages.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..855a105f0f4c96ff6889df49149839c42f1054de
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/client/views/channelSettingsMailMessages.coffee
@@ -0,0 +1,10 @@
+Template.channelSettingsMailMessages.events
+	'click button.mail-messages': (e, t) ->
+		Session.set 'channelSettingsMailMessages', Session.get('openedRoom')
+		RocketChat.TabBar.setTemplate('mailMessagesInstructions')
+		view = Blaze.getView($('.messages-box')[0])
+		view?.templateInstance?().resetSelection?(true)
+
+Template.channelSettingsMailMessages.onCreated ->
+	view = Blaze.getView($('.messages-box')[0])
+	view?.templateInstance?().resetSelection?(false)
diff --git a/packages/rocketchat-channel-settings-mail-messages/client/views/channelSettingsMailMessages.html b/packages/rocketchat-channel-settings-mail-messages/client/views/channelSettingsMailMessages.html
new file mode 100644
index 0000000000000000000000000000000000000000..10b1cce82fe7934fea31b5bed1a2866b29dc3578
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/client/views/channelSettingsMailMessages.html
@@ -0,0 +1,8 @@
+<template name="channelSettingsMailMessages">
+	<li>
+		<label>{{_ "Mail_Messages"}}</label>
+		<div>
+			<button type="button" class="button primary mail-messages">{{_ "Choose_messages"}}</button>
+		</div>
+	</li>
+</template>
diff --git a/packages/rocketchat-channel-settings-mail-messages/client/views/mailMessagesInstructions.coffee b/packages/rocketchat-channel-settings-mail-messages/client/views/mailMessagesInstructions.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..ed30d543765229f35f1ef24db191f031b09ea7ca
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/client/views/mailMessagesInstructions.coffee
@@ -0,0 +1,79 @@
+Template.mailMessagesInstructions.helpers
+	name: ->
+		return Meteor.user().name
+	email: ->
+		return Meteor.user().emails?[0]?.address
+	roomName: ->
+		return ChatRoom.findOne(Session.get('openedRoom'))?.name
+	erroredEmails: ->
+		return Template.instance()?.erroredEmails.get().join(', ')
+
+Template.mailMessagesInstructions.events
+	'click .cancel': (e, t) ->
+		t.reset()
+
+	'click .send': (e, t) ->
+		t.$('.error').hide()
+		$btn = t.$('button.send')
+		oldBtnValue = $btn.html()
+		$btn.html(TAPi18n.__('Sending'))
+
+		selectedMessages = $('.messages-box .message.selected')
+
+		error = false
+		if selectedMessages.length is 0
+			t.$('.error-select').show()
+			error = true
+
+		if t.$('input[name=to]').val().trim()
+			rfcMailPatternWithName = /^(?:.*<)?([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)(?:>?)$/
+			emails = t.$('input[name=to]').val().trim().split(',')
+			erroredEmails = []
+			for email in emails
+				unless rfcMailPatternWithName.test email.trim()
+					erroredEmails.push email.trim()
+
+			t.erroredEmails.set erroredEmails
+			if erroredEmails.length > 0
+				t.$('.error-invalid-emails').show()
+				error = true
+		else
+			t.$('.error-missing-to').show()
+			error = true
+
+		if error
+			$btn.html(oldBtnValue)
+		else
+			data =
+				rid: Session.get('openedRoom')
+				to: t.$('input[name=to]').val().trim()
+				subject: t.$('input[name=subject]').val().trim()
+				messages: selectedMessages.map((i, message) -> return message.id).toArray()
+				language: localStorage.getItem('userLanguage')
+
+			Meteor.call 'mailMessages', data, (err, result) ->
+				$btn.html(oldBtnValue)
+				if err?
+					return toastr.error(err.reason or err.message)
+
+				toastr.success(TAPi18n.__('Your_email_has_been_queued_for_sending'))
+				t.reset()
+
+	'click .select-all': (e, t) ->
+		t.$('.error-select').hide()
+
+		view = Blaze.getView($('.messages-box')[0])
+		view?.templateInstance?().selectedMessages = _.pluck(ChatMessage.find({rid: Session.get('openedRoom')})?.fetch(), '_id')
+		$(".messages-box .message").addClass('selected')
+
+Template.mailMessagesInstructions.onCreated ->
+	@erroredEmails = new ReactiveVar []
+
+	@reset = ->
+		RocketChat.TabBar.setTemplate('channelSettings')
+		view = Blaze.getView($('.messages-box')[0])
+		view?.templateInstance?().resetSelection?(false)
+
+	@autorun =>
+		if Session.get('channelSettingsMailMessages') isnt Session.get('openedRoom')
+			this.reset()
diff --git a/packages/rocketchat-channel-settings-mail-messages/client/views/mailMessagesInstructions.html b/packages/rocketchat-channel-settings-mail-messages/client/views/mailMessagesInstructions.html
new file mode 100644
index 0000000000000000000000000000000000000000..c8c27429f6d9b48fa9e491ea9cd387762f7613d4
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/client/views/mailMessagesInstructions.html
@@ -0,0 +1,44 @@
+<template name="mailMessagesInstructions">
+	<div class="content">
+		<div class="list-view mail-message">
+			<div class="status">
+				<h2>{{_ "Mail_Messages"}}</h2>
+			</div>
+			<p>{{_ "Mail_Messages_Instructions"}}</p>
+			<form>
+				<fieldset>
+					<div class="input-line double-col">
+						<label>{{_ "From"}}</label>
+						<div>{{name}}</div>
+						<div>{{email}}</div>
+					</div>
+					<div class="input-line double-col">
+						<label>{{_ "To"}}</label>
+						<div>
+							<input type="text" name="to" value="" />
+						</div>
+					</div>
+					<div class="input-line double-col">
+						<label>{{_ "Subject"}}</label>
+						<div>
+							<input type="text" name="subject" value="{{_ "Mail_Messages_Subject" roomName}}" />
+						</div>
+					</div>
+				</fieldset>
+			</form>
+			<div class="error error-missing-to alert alert-danger" style="display: none">
+				{{_ "Mail_Message_Missing_to"}}
+			</div>
+			<div class="error error-invalid-emails alert alert-danger" style="display: none">
+				{{_ "Mail_Message_Invalid_emails" erroredEmails}}
+			</div>
+			<div class="error error-select alert alert-danger" style="display: none">
+				{{{_ "Mail_Message_No_messages_selected_select_all"}}}
+			</div>
+			<p style="margin-top: 30px">
+				<button type="button" class="button secondary cancel">{{_ "Cancel"}}</button>
+				<button type="button" class="button primary send">{{_ "Send"}}</button>
+			</p>
+		</div>
+	</div>
+</template>
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/en.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/en.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..32ec45e9cdb50673ef64eb9f8160454c6acc49d8
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/en.i18n.json
@@ -0,0 +1,17 @@
+{
+	"Body" : "Body",
+	"Cancel" : "Cancel",
+	"Choose_messages" : "Choose messages",
+	"From" : "From",
+	"Mail_Message_Missing_to" : "You must provide one or more To e-mail addresses, separated by commas.",
+	"Mail_Message_No_messages_selected_select_all" : "You haven't selected any messages. Would you like to <a href='#' class='select-all'>select all</a> visible messages?",
+	"Mail_Messages" : "Mail Messages",
+	"Mail_Messages_Instructions" : "Choose which messages you want to send via e-mail by clicking the messages",
+	"Mail_Messages_Subject" : "Here's a selected portion of %s messages",
+	"Mail_Message_Invalid_emails" : "You have provided one or more invalid e-mails: %s",
+	"Send" : "Send",
+	"Sending" : "Sending...",
+	"Subject" : "Subject",
+	"To" : "To",
+	"Your_email_has_been_queued_for_sending" : "Your email has been queued for sending"
+}
diff --git a/packages/rocketchat-channel-settings-mail-messages/package.js b/packages/rocketchat-channel-settings-mail-messages/package.js
new file mode 100644
index 0000000000000000000000000000000000000000..b0fb444889dd0f9b284e5f21b963d8b23a24abf3
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/package.js
@@ -0,0 +1,51 @@
+Package.describe({
+	name: 'rocketchat:channel-settings-mail-messages',
+	version: '0.0.1',
+	summary: 'Channel Settings - Mail Messages',
+	git: ''
+});
+
+Package.onUse(function(api) {
+	api.versionsFrom('1.0');
+
+	api.use([
+		'coffeescript',
+		'templating',
+		'reactive-var',
+		'less@2.5.0',
+		'rocketchat:lib@0.0.1',
+		'rocketchat:channel-settings',
+		'momentjs:moment'
+	]);
+
+	api.addFiles([
+		'client/lib/startup.coffee',
+		'client/stylesheets/mail-messages.less',
+		'client/views/channelSettingsMailMessages.html',
+		'client/views/channelSettingsMailMessages.coffee',
+		'client/views/mailMessagesInstructions.html',
+		'client/views/mailMessagesInstructions.coffee'
+	], 'client');
+
+
+	api.addFiles([
+		'server/lib/startup.coffee',
+		'server/methods/mailMessages.coffee'
+	], 'server');
+
+	// TAPi18n
+	var _ = Npm.require('underscore');
+	var fs = Npm.require('fs');
+	tapi18nFiles = _.compact(_.map(fs.readdirSync('packages/rocketchat-channel-settings-mail-messages/i18n'), function(filename) {
+		if (fs.statSync('packages/rocketchat-channel-settings-mail-messages/i18n/' + filename).size > 16) {
+			return 'i18n/' + filename;
+		}
+	}));
+	api.use('tap:i18n@1.6.1');
+	api.imply('tap:i18n');
+	api.addFiles(tapi18nFiles);
+});
+
+Package.onTest(function(api) {
+
+});
diff --git a/packages/rocketchat-channel-settings-mail-messages/server/lib/startup.coffee b/packages/rocketchat-channel-settings-mail-messages/server/lib/startup.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..0a30dd195e4989f195fef4b0592e907b3bf0fda7
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/server/lib/startup.coffee
@@ -0,0 +1,3 @@
+Meteor.startup ->
+	permission = { _id: 'mail-messages', roles : [ 'admin' ] }
+	RocketChat.models.Permissions.upsert( permission._id, { $setOnInsert : permission })
diff --git a/packages/rocketchat-channel-settings-mail-messages/server/methods/mailMessages.coffee b/packages/rocketchat-channel-settings-mail-messages/server/methods/mailMessages.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..499543047cd730e4d3229c56847a438616fa98d1
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/server/methods/mailMessages.coffee
@@ -0,0 +1,46 @@
+Meteor.methods
+	'mailMessages': (data) ->
+		if not Meteor.userId()
+			throw new Meteor.Error('invalid-user', "[methods] mailMessages -> Invalid user")
+
+		check(data, Match.ObjectIncluding({ rid: String, to: String, subject: String, messages: [ String ], language: String }))
+
+		room = Meteor.call 'canAccessRoom', data.rid, Meteor.userId()
+		unless room
+			throw new Meteor.Error('invalid-room', "[methods] mailMessages -> Invalid room")
+
+		unless RocketChat.authz.hasPermission(Meteor.userId(), 'mail-messages')
+			throw new Meteor.Error 'not-authorized'
+
+		rfcMailPatternWithName = /^(?:.*<)?([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)(?:>?)$/
+		emails = data.to.trim().split(',')
+		for email in emails
+			unless rfcMailPatternWithName.test email.trim()
+				throw new Meteor.Error('invalid-email', "[methods] mailMessages -> Invalid e-mail")
+
+		user = Meteor.user()
+		name = user.name
+		email = user.emails?[0]?.address
+
+		if data.language isnt 'en'
+			localeFn = Meteor.call 'loadLocale', data.language
+			if localeFn
+				Function(localeFn)()
+
+		html = ""
+		RocketChat.models.Messages.findByRoomIdAndMessageIds(data.rid, data.messages, { sort: { ts: 1 } }).forEach (message) ->
+			dateTime = moment(message.ts).locale(data.language).format('L LT')
+			html += "<p style='margin-bottom: 5px'><b>#{message.u.username}</b> <span style='color: #aaa; font-size: 12px'>#{dateTime}</span><br />" + RocketChat.Message.parse(message, data.language) + "</p>"
+
+		Meteor.defer ->
+			Email.send
+				to: emails
+				from: RocketChat.settings.get('From_Email')
+				replyTo: email
+				subject: data.subject
+				html: html
+
+			console.log 'Sending email to ' + emails.join(', ')
+
+
+		return true
diff --git a/packages/rocketchat-channel-settings/client/lib/ChannelSettings.coffee b/packages/rocketchat-channel-settings/client/lib/ChannelSettings.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..f9322fbb446e609e226c5cb24962ee35d1bccf81
--- /dev/null
+++ b/packages/rocketchat-channel-settings/client/lib/ChannelSettings.coffee
@@ -0,0 +1,29 @@
+RocketChat.ChannelSettings = new class
+	options = new ReactiveVar {}
+
+	###
+	# Adds an option in Channel Settings
+	# @config (object)
+	#   id: option id (required)
+	#   template (string): template name to render (required)
+	#   validation (function): if option should be displayed
+	###
+	addOption = (config) ->
+		unless config?.id
+			throw new Meteor.Error "ChannelSettings-addOption-error", "Option id was not informed."
+
+		Tracker.nonreactive ->
+			opts = options.get()
+			opts[config.id] = config
+			options.set opts
+
+	getOptions = ->
+		allOptions = _.toArray options.get()
+		allowedOptions = _.compact _.map allOptions, (option) ->
+			if not option.validation? or option.validation()
+				return option
+
+		return _.sortBy allowedOptions, 'order'
+
+	addOption: addOption
+	getOptions: getOptions
diff --git a/packages/rocketchat-channel-settings/client/stylesheets/channel-settings.less b/packages/rocketchat-channel-settings/client/stylesheets/channel-settings.less
index a09d3ee179c2e5800f74f5b334bc852563d37dca..872c1a7331835eeff8df795a9fd45e08f4bbb968 100644
--- a/packages/rocketchat-channel-settings/client/stylesheets/channel-settings.less
+++ b/packages/rocketchat-channel-settings/client/stylesheets/channel-settings.less
@@ -1,11 +1,25 @@
 .flex-tab {
 	.channel-settings {
-		margin-top: 60px;
-		padding: 20px;
+		ul {
+			li {
+				margin-bottom: 20px;
+			}
+		}
 
 		form {
 			label {
+				display: block;
+				font-weight: bold;
+				margin-bottom: 5px;
+			}
 
+			div span {
+				font-size: 14px;
+				i.octicon {
+					font-size: 12px;
+					vertical-align: middle;
+					margin-left: 3px;
+				}
 			}
 		}
 
@@ -19,15 +33,3 @@
 		}
 	}
 }
-
-.input-line.double-col {
-	div {
-		line-height: 15px;
-		padding: 10px 20px 10px 0;
-		i.octicon {
-			font-size: 13px;
-			opacity: 0.4;
-			vertical-align: top;
-		}
-	}
-}
diff --git a/packages/rocketchat-channel-settings/client/views/channelSettings.coffee b/packages/rocketchat-channel-settings/client/views/channelSettings.coffee
index 7f5639384fe1a1e628078e36028a9ca694cf9ce7..30529f9a8091ef7ff082cd6366ad5b25e14989ea 100644
--- a/packages/rocketchat-channel-settings/client/views/channelSettings.coffee
+++ b/packages/rocketchat-channel-settings/client/views/channelSettings.coffee
@@ -7,6 +7,8 @@ Template.channelSettings.helpers
 		return ChatRoom.findOne(@rid)?.t isnt 'd'
 	roomType: ->
 		return ChatRoom.findOne(@rid)?.t
+	channelSettings: ->
+		return RocketChat.ChannelSettings.getOptions()
 	roomTypeDescription: ->
 		roomType = ChatRoom.findOne(@rid)?.t
 		if roomType is 'c'
@@ -17,27 +19,10 @@ Template.channelSettings.helpers
 		return ChatRoom.findOne(@rid)?.name
 	roomTopic: ->
 		return ChatRoom.findOne(@rid)?.topic
+	archived: ->
+		return ChatRoom.findOne(@rid)?.archived
 
 Template.channelSettings.events
-	# 'click .save': (e, t) ->
-	# 	e.preventDefault()
-
-	# 	settings =
-	# 		roomType: t.$('input[name=roomType]:checked').val()
-	# 		roomName: t.$('input[name=roomName]').val()
-	# 		roomTopic: t.$('input[name=roomTopic]').val()
-
-	# 	if t.validate()
-	# 		Meteor.call 'saveRoomSettings', t.data.rid, settings, (err, results) ->
-	# 			if err
-	# 				if err.error in [ 'duplicate-name', 'name-invalid' ]
-	# 					return toastr.error TAPi18n.__(err.reason, err.details.channelName)
-	# 				if err.error is 'invalid-room-type'
-	# 					return toastr.error TAPi18n.__(err.reason, err.details.roomType)
-	# 				return toastr.error TAPi18n.__(err.reason)
-
-	# 			toastr.success TAPi18n.__ 'Settings_updated'
-
 	'keydown input[type=text]': (e, t) ->
 		if e.keyCode is 13
 			e.preventDefault()
@@ -56,6 +41,20 @@ Template.channelSettings.events
 		e.preventDefault()
 		t.saveSetting()
 
+	'click .archive': (e, t) ->
+		e.preventDefault()
+
+		Meteor.call 'archiveRoom', t.data.rid, true, (err, results) ->
+			return toastr.error err.reason if err
+			toastr.success TAPi18n.__ 'Room_archived'
+
+	'click .unarchive': (e, t) ->
+		e.preventDefault()
+
+		Meteor.call 'unarchiveRoom', t.data.rid, true, (err, results) ->
+			return toastr.error err.reason if err
+			toastr.success TAPi18n.__ 'Room_unarchived'
+
 Template.channelSettings.onCreated ->
 	@editing = new ReactiveVar
 
diff --git a/packages/rocketchat-channel-settings/client/views/channelSettings.html b/packages/rocketchat-channel-settings/client/views/channelSettings.html
index bba2381095c2b6e0f5b6f4bd881374581e806e4d..8a326bd49117b25d98d02235dbe8fc83efd3ea35 100644
--- a/packages/rocketchat-channel-settings/client/views/channelSettings.html
+++ b/packages/rocketchat-channel-settings/client/views/channelSettings.html
@@ -1,50 +1,63 @@
 <template name="channelSettings">
-	<div class="control">
-		<div class="header">
-			<h2>{{_ "Room_Info"}}</h2>
-		</div>
-	</div>
-	<div class="channel-settings scrollable">
-		<form>
-			<fieldset>
-				{{#if notDirect}}
-					<div class="input-line double-col">
-						<label>{{_ "Name"}}</label>
+	<div class="content">
+		<div class="list-view channel-settings">
+			<div class="status">
+				<h2>{{_ "Room_Info"}}</h2>
+			</div>
+			<form>
+				<ul class="list clearfix">
+					{{#if notDirect}}
+						<li>
+							<label>{{_ "Name"}}</label>
+							<div>
+								{{#if editing 'roomName'}}
+									<input type="text" name="roomName" value="{{roomName}}" class="editing" /> <button type="button" class="button secondary cancel">{{_ "Cancel"}}</button> <button type="button" class="button primary save">{{_ "Save"}}</button>
+								{{else}}
+									<span>{{roomName}}{{#if canEdit}} <i class="octicon octicon-pencil" data-edit="roomName"></i>{{/if}}</span>
+								{{/if}}
+							</div>
+						</li>
+					{{/if}}
+					<li>
+						<label>{{_ "Topic"}}</label>
 						<div>
-							{{#if editing 'roomName'}}
-								<input type="text" name="roomName" value="{{roomName}}" class="editing" /> <button type="button" class="button secondary cancel">{{_ "Cancel"}}</button> <button type="button" class="button primary save">{{_ "Save"}}</button>
+							{{#if editing 'roomTopic'}}
+								<input type="text" name="roomTopic" value="{{roomTopic}}" class="editing" /> <button type="button" class="button secondary cancel">{{_ "Cancel"}}</button> <button type="button" class="button primary save">{{_ "Save"}}</button>
 							{{else}}
-								{{roomName}}{{#if canEdit}} <i class="octicon octicon-pencil" data-edit="roomName"></i>{{/if}}
+								<span>{{roomTopic}}{{#if canEdit}} <i class="octicon octicon-pencil" data-edit="roomTopic"></i>{{/if}}</span>
 							{{/if}}
 						</div>
-					</div>
-				{{/if}}
-				<div class="input-line double-col">
-					<label>{{_ "Topic"}}</label>
-					<div>
-						{{#if editing 'roomTopic'}}
-							<input type="text" name="roomTopic" value="{{roomTopic}}" class="editing" /> <button type="button" class="button secondary cancel">{{_ "Cancel"}}</button> <button type="button" class="button primary save">{{_ "Save"}}</button>
-						{{else}}
-							{{roomTopic}}{{#if canEdit}} <i class="octicon octicon-pencil" data-edit="roomTopic"></i>{{/if}}
-						{{/if}}
-					</div>
-				</div>
-				{{#if notDirect}}
-					<div class="input-line double-col">
-						<label>{{_ "Type"}}</label>
-						<div>
-							{{#if editing 'roomType'}}
-								<label><input type="radio" name="roomType" class="editing" value="c" checked="{{$eq roomType 'c'}}" /> {{_ "Channel"}}</label>
-								<label><input type="radio" name="roomType" value="p" checked="{{$eq roomType 'p'}}" /> {{_ "Private_Group"}}</label>
-								<button type="button" class="button secondary cancel">{{_ "Cancel"}}</button>
-								<button type="button" class="button primary save">{{_ "Save"}}</button>
+					</li>
+					{{#if notDirect}}
+						<li>
+							<label>{{_ "Type"}}</label>
+							<div>
+								{{#if editing 'roomType'}}
+									<label><input type="radio" name="roomType" class="editing" value="c" checked="{{$eq roomType 'c'}}" /> {{_ "Channel"}}</label>
+									<label><input type="radio" name="roomType" value="p" checked="{{$eq roomType 'p'}}" /> {{_ "Private_Group"}}</label>
+									<button type="button" class="button secondary cancel">{{_ "Cancel"}}</button>
+									<button type="button" class="button primary save">{{_ "Save"}}</button>
+								{{else}}
+									<span>{{roomTypeDescription}}{{#if canEdit}} <i class="octicon octicon-pencil" data-edit="roomType"></i>{{/if}}</span>
+								{{/if}}
+							</div>
+						</li>
+					{{/if}}
+					{{#if notDirect}}
+						<li>
+							<label>{{_ "Archive_Unarchive"}}</label>
+							{{#if archived}}
+								<button class="button unarchive"><span>{{_ "Unarchive"}}</span></button>
 							{{else}}
-								{{roomTypeDescription}}{{#if canEdit}} <i class="octicon octicon-pencil" data-edit="roomType"></i>{{/if}}
+								<button class="button archive"><span>{{_ "Archive"}}</span></button>
 							{{/if}}
-						</div>
-					</div>
-				{{/if}}
-			</fieldset>
-		</form>
+						</li>
+					{{/if}}
+					{{#each channelSettings}}
+						{{> Template.dynamic template=template data=data}}
+					{{/each}}
+				</ul>
+			</form>
+		</div>
 	</div>
 </template>
diff --git a/packages/rocketchat-channel-settings/i18n/en.i18n.json b/packages/rocketchat-channel-settings/i18n/en.i18n.json
index 44e8aa2ccb9567719ab90a880f031f2a47ba7d94..c6ebf4e70dc93148390527264bfcf51fc5c352c2 100644
--- a/packages/rocketchat-channel-settings/i18n/en.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/en.i18n.json
@@ -1,4 +1,5 @@
 {
+	"Archive_Unarchive": "Archive / Unarchive",
 	"Cancel": "Cancel",
 	"Channel": "Channel",
 	"Private_Group": "Private Group",
diff --git a/packages/rocketchat-channel-settings/package.js b/packages/rocketchat-channel-settings/package.js
index 127e12269405c9a3569bf37acb62640590698884..c6f17e5b597ba1e38a71bcca7a94a164173dbad7 100644
--- a/packages/rocketchat-channel-settings/package.js
+++ b/packages/rocketchat-channel-settings/package.js
@@ -10,12 +10,15 @@ Package.onUse(function(api) {
 
 	api.use([
 		'coffeescript',
+		'reactive-var',
+		'tracker',
 		'templating',
 		'less@2.5.0',
 		'rocketchat:lib@0.0.1'
 	]);
 
 	api.addFiles([
+		'client/lib/ChannelSettings.coffee',
 		'client/startup/messageTypes.coffee',
 		'client/startup/tabBar.coffee',
 		'client/startup/trackSettingsChange.coffee',
diff --git a/packages/rocketchat-file/file.server.coffee b/packages/rocketchat-file/file.server.coffee
index a47489fac2447895e0d34bf506f3bc9d1a1ce73c..80b6e64bfc7f4d051ebbf77e8b9e9e3d289e7dfe 100644
--- a/packages/rocketchat-file/file.server.coffee
+++ b/packages/rocketchat-file/file.server.coffee
@@ -20,34 +20,50 @@ RocketChatFile =
 		RocketChat.settings.updateOptionsById 'Accounts_AvatarResize', {alert: 'The_image_resize_will_not_work_because_we_can_not_detect_ImageMagick_or_GraphicsMagick_installed_in_your_server'}
 
 
-exec 'gm version', Meteor.bindEnvironment (error, stdout, stderr) ->
-	if not error? and stdout.indexOf('GraphicsMagick') > -1
-		RocketChatFile.enable()
-
-		RocketChat.Info.GraphicsMagick =
-			enabled: true
-			version: stdout
-	else
-		RocketChat.Info.GraphicsMagick =
-			enabled: false
-
-	exec 'convert -version', Meteor.bindEnvironment (error, stdout, stderr) ->
-		if not error? and stdout.indexOf('ImageMagick') > -1
-			if RocketChatFile.enabled isnt true
-				# Enable GM to work with ImageMagick if no GraphicsMagick
-				RocketChatFile.gm = RocketChatFile.gm.subClass({imageMagick: true})
-				RocketChatFile.enable()
-
-			RocketChat.Info.ImageMagick =
+detectGM = ->
+	console.log 'GM: Getting GraphicsMagick version'
+	exec 'gm version', Meteor.bindEnvironment (error, stdout, stderr) ->
+		console.log 'GM: GraphicsMagick', arguments
+		if not error? and stdout.indexOf('GraphicsMagick') > -1
+			console.log 'GM: GraphicsMagick installed'
+			RocketChatFile.enable()
+
+			RocketChat.Info.GraphicsMagick =
 				enabled: true
 				version: stdout
 		else
-			if RocketChatFile.enabled isnt true
-				RocketChatFile.disable()
-
-			RocketChat.Info.ImageMagick =
+			console.log 'GM: GraphicsMagick not installed'
+			RocketChat.Info.GraphicsMagick =
 				enabled: false
 
+		console.log 'GM: Getting ImageMagick version'
+		exec 'convert -version', Meteor.bindEnvironment (error, stdout, stderr) ->
+			console.log 'GM: ImageMagick', arguments
+			if not error? and stdout.indexOf('ImageMagick') > -1
+				console.log 'GM: ImageMagick installed'
+				if RocketChatFile.enabled isnt true
+					# Enable GM to work with ImageMagick if no GraphicsMagick
+					RocketChatFile.gm = RocketChatFile.gm.subClass({imageMagick: true})
+					RocketChatFile.enable()
+
+				RocketChat.Info.ImageMagick =
+					enabled: true
+					version: stdout
+			else
+				console.log 'GM: ImageMagick not installed'
+				if RocketChatFile.enabled isnt true
+					RocketChatFile.disable()
+
+				RocketChat.Info.ImageMagick =
+					enabled: false
+
+detectGM()
+
+Meteor.methods
+	'detectGM': ->
+		detectGM()
+		return
+
 
 RocketChatFile.bufferToStream = (buffer) ->
 	bufferStream = new stream.PassThrough()
diff --git a/packages/rocketchat-lib/client/lib/roomExit.coffee b/packages/rocketchat-lib/client/lib/roomExit.coffee
index 7ee736f5e2ea1661e584d971b7224aee8e50131d..d7da9ed4a8718746e4b3c507e468a6411e9d59b6 100644
--- a/packages/rocketchat-lib/client/lib/roomExit.coffee
+++ b/packages/rocketchat-lib/client/lib/roomExit.coffee
@@ -1,4 +1,6 @@
 @roomExit = ->
+	RocketChat.callbacks.run 'roomExit'
+
 	BlazeLayout.render 'main', {center: 'none'}
 
 	if currentTracker?
diff --git a/packages/rocketchat-lib/lib/Message.coffee b/packages/rocketchat-lib/lib/Message.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..cbf6e92a89ff0e80376e19e12bfa538ea6abdeb2
--- /dev/null
+++ b/packages/rocketchat-lib/lib/Message.coffee
@@ -0,0 +1,26 @@
+RocketChat.Message =
+	parse: (msg, language) ->
+		messageType = RocketChat.MessageTypes.getType(msg)
+		if messageType?.render?
+			return messageType.render(msg)
+		else if messageType?.template?
+			# render template
+		else if messageType?.message?
+			if not language and localStorage?.getItem('userLanguage')
+				language = localStorage.getItem('userLanguage')
+			if messageType.data?(msg)?
+				return TAPi18n.__(messageType.message, messageType.data(msg), language)
+			else
+				return TAPi18n.__(messageType.message, {}, language)
+		else
+			if msg.u?.username is RocketChat.settings.get('Chatops_Username')
+				msg.html = msg.msg
+				return msg.html
+
+			msg.html = msg.msg
+			if _.trim(msg.html) isnt ''
+				msg.html = _.escapeHTML msg.html
+
+			# message = RocketChat.callbacks.run 'renderMessage', msg
+			msg.html = msg.html.replace /\n/gm, '<br/>'
+			return msg.html
diff --git a/packages/rocketchat-lib/client/MessageTypes.coffee b/packages/rocketchat-lib/lib/MessageTypes.coffee
similarity index 100%
rename from packages/rocketchat-lib/client/MessageTypes.coffee
rename to packages/rocketchat-lib/lib/MessageTypes.coffee
diff --git a/packages/rocketchat-lib/package.js b/packages/rocketchat-lib/package.js
index aacfc1337ffca1168b1be25ee2d67bc9b887ac74..34e49b1c7f330b6d61801c73dbf9092942516390 100644
--- a/packages/rocketchat-lib/package.js
+++ b/packages/rocketchat-lib/package.js
@@ -33,6 +33,8 @@ Package.onUse(function(api) {
 	api.addFiles('lib/settings.coffee');
 	api.addFiles('lib/callbacks.coffee');
 	api.addFiles('lib/slashCommand.coffee');
+	api.addFiles('lib/Message.coffee');
+	api.addFiles('lib/MessageTypes.coffee');
 
 	// SERVER LIB
 	api.addFiles('server/lib/RateLimiter.coffee', 'server');
@@ -92,7 +94,6 @@ Package.onUse(function(api) {
 	api.addFiles('client/Notifications.coffee', 'client');
 	api.addFiles('client/TabBar.coffee', 'client');
 	api.addFiles('client/MessageAction.coffee', 'client');
-	api.addFiles('client/MessageTypes.coffee', 'client');
 
 	// VERSION
 	api.addFiles('rocketchat.info');
diff --git a/packages/rocketchat-lib/rocketchat.info b/packages/rocketchat-lib/rocketchat.info
index 506e7cd2a4c1e179445526c6bbd32fba4b8ad694..f8dc5a090df3ce2c296fe9654038f7362423e808 100644
--- a/packages/rocketchat-lib/rocketchat.info
+++ b/packages/rocketchat-lib/rocketchat.info
@@ -1,3 +1,3 @@
 {
-	"version": "0.10.1"
+	"version": "0.10.2"
 }
diff --git a/packages/rocketchat-lib/server/methods/updateUser.coffee b/packages/rocketchat-lib/server/methods/updateUser.coffee
index 53f3536d0d8ee424e2d938d7e2f6f3ab37ce778e..2416d3d11846058197b35372e529bc6bc88c2c1c 100644
--- a/packages/rocketchat-lib/server/methods/updateUser.coffee
+++ b/packages/rocketchat-lib/server/methods/updateUser.coffee
@@ -23,4 +23,8 @@ Meteor.methods
 		Meteor.runAsUser userData._id, ->
 			Meteor.call 'setUsername', userData.username
 
+		canEditUserPassword = RocketChat.authz.hasPermission( user._id, 'edit-other-user-password')
+		if canEditUserPassword and userData.password.trim()
+			Accounts.setPassword userData._id, userData.password.trim()
+
 		return true
diff --git a/packages/rocketchat-lib/server/models/Messages.coffee b/packages/rocketchat-lib/server/models/Messages.coffee
index 5010fc05d4c69368b0fe4020b0a1ada3b42ec578..3c9375f075b69e90738ea223032771e0ca00267f 100644
--- a/packages/rocketchat-lib/server/models/Messages.coffee
+++ b/packages/rocketchat-lib/server/models/Messages.coffee
@@ -116,6 +116,14 @@ RocketChat.models.Messages = new class extends RocketChat.models._Base
 
 		return @find(query, options)?.fetch?()?[0]?.ts
 
+	findByRoomIdAndMessageIds: (rid, messageIds, options) ->
+		query =
+			rid: rid
+			_id:
+				$in: messageIds
+
+		return @find query, options
+
 	cloneAndSaveAsHistoryById: (_id) ->
 		me = RocketChat.models.Users.findOneById Meteor.userId()
 		record = @findOneById _id
@@ -134,7 +142,6 @@ RocketChat.models.Messages = new class extends RocketChat.models._Base
 
 		return @insert record
 
-
 	# UPDATE
 	setHiddenById: (_id, hidden=true) ->
 		query =
diff --git a/packages/rocketchat-lib/server/models/Rooms.coffee b/packages/rocketchat-lib/server/models/Rooms.coffee
index a611abaec164f6f43f75e074bd9a6e29b8de456e..4befae7bfe04eb56461e5ded048e15751f4760d4 100644
--- a/packages/rocketchat-lib/server/models/Rooms.coffee
+++ b/packages/rocketchat-lib/server/models/Rooms.coffee
@@ -147,6 +147,17 @@ RocketChat.models.Rooms = new class extends RocketChat.models._Base
 
 		return @find query, options
 
+	findByTypeAndArchivationState: (type, archivationstate, options) ->
+		query =
+			t: type
+
+		if archivationstate
+			query.archived = true
+		else
+			query.archived = { $ne: true }
+
+		return @find query, options
+
 	findByVisitorToken: (visitorToken, options) ->
 		query =
 			"v.token": visitorToken
diff --git a/packages/rocketchat-lib/server/models/Subscriptions.coffee b/packages/rocketchat-lib/server/models/Subscriptions.coffee
index 209464bd1bb15f3f354aafeff151caa0735aa91e..77c697dd41aeed24082cb06e58c3cae4d456ad4c 100644
--- a/packages/rocketchat-lib/server/models/Subscriptions.coffee
+++ b/packages/rocketchat-lib/server/models/Subscriptions.coffee
@@ -54,7 +54,7 @@ RocketChat.models.Subscriptions = new class extends RocketChat.models._Base
 		update =
 			$set:
 				alert: false
-				open: false
+				open: true
 				archived: false
 
 		return @update query, update
diff --git a/packages/rocketchat-livechat/client/collections/AgentUsers.js b/packages/rocketchat-livechat/client/collections/AgentUsers.js
new file mode 100644
index 0000000000000000000000000000000000000000..e571fad61d2b47890c451156e30a86abce926e07
--- /dev/null
+++ b/packages/rocketchat-livechat/client/collections/AgentUsers.js
@@ -0,0 +1 @@
+this.AgentUsers = new Mongo.Collection('agentUsers');
diff --git a/packages/rocketchat-livechat/client/lib/LivechatDepartment.js b/packages/rocketchat-livechat/client/collections/LivechatDepartment.js
similarity index 100%
rename from packages/rocketchat-livechat/client/lib/LivechatDepartment.js
rename to packages/rocketchat-livechat/client/collections/LivechatDepartment.js
diff --git a/packages/rocketchat-livechat/client/collections/LivechatDepartmentAgents.js b/packages/rocketchat-livechat/client/collections/LivechatDepartmentAgents.js
new file mode 100644
index 0000000000000000000000000000000000000000..08ea1741134bb6e9997d804c392ef8898f4dffc3
--- /dev/null
+++ b/packages/rocketchat-livechat/client/collections/LivechatDepartmentAgents.js
@@ -0,0 +1 @@
+this.LivechatDepartmentAgents = new Mongo.Collection('rocketchat_livechat_department_agents');
diff --git a/packages/rocketchat-livechat/client/lib/LivechatTrigger.js b/packages/rocketchat-livechat/client/collections/LivechatTrigger.js
similarity index 100%
rename from packages/rocketchat-livechat/client/lib/LivechatTrigger.js
rename to packages/rocketchat-livechat/client/collections/LivechatTrigger.js
diff --git a/packages/rocketchat-livechat/client/stylesheets/livechat.less b/packages/rocketchat-livechat/client/stylesheets/livechat.less
index dc12fb153ec48c1bf2259304f6abdba3a31321cf..b389c38d398b9e3b73031a76dc70c23c38959ca8 100644
--- a/packages/rocketchat-livechat/client/stylesheets/livechat.less
+++ b/packages/rocketchat-livechat/client/stylesheets/livechat.less
@@ -411,3 +411,29 @@
 		}
 	}
 }
+
+.department-agents {
+	list-style-type: none;
+
+	li {
+		display: inline-block;
+		background-color: #DDD;
+		border-radius: 10px;
+		padding: 2px 8px 2px 2px;
+		margin: 1px 0;
+		cursor: pointer;
+
+		.icon-plus-circled {
+			opacity: 0.5;
+			font-size: 0.8rem;
+		}
+	}
+}
+
+.agent-info {
+	input[type='text'] {
+		width: auto;
+		line-height: 24px;
+		height: 24px;
+	}
+}
diff --git a/packages/rocketchat-livechat/client/views/app/livechatDepartmentForm.html b/packages/rocketchat-livechat/client/views/app/livechatDepartmentForm.html
index 5a82ac77c719601b0ec0dbcb7df3d79463661222..fccbaa7f071818e87b02d36fd87981cd83680d6a 100644
--- a/packages/rocketchat-livechat/client/views/app/livechatDepartmentForm.html
+++ b/packages/rocketchat-livechat/client/views/app/livechatDepartmentForm.html
@@ -24,34 +24,51 @@
 					</div>
 					<hr />
 					<h2>{{_ "Agents"}}</h2>
-					<div class="input-line double-col">
-						<input type="text" name="agent" placeholder="{{_ "Enter_a_username"}}">
-						<button name="addAgent" type="button" class="button add-agent">{{_ "Add_agent"}}</button>
-					</div>
-					<div class="list">
-						<table>
-							<thead>
-								<tr>
-									<th width="25%">{{_ "Username"}}</th>
-									<th>{{_ "Delete"}}</th>
-								</tr>
-							</thead>
-							<tbody>
-								{{#if agents.length}}
-									{{#each agents}}
-										<tr class="agent-info" data-id="{{_id}}">
-											<td>{{username}}</td>
-											<td><a href="#remove" class="remove-agent"><i class="icon-trash"></i></a></td>
-										</tr>
-									{{/each}}
-								{{else}}
+
+					<fieldset>
+						<legend>{{_ "Available_agents"}}</legend>
+
+						<ul class="department-agents available-agents">
+							{{#each availableAgents}}
+								<li><i class="icon-plus-circled"></i>{{username}}</li>
+							{{/each}}
+						</ul>
+					</fieldset>
+
+					<fieldset>
+						<legend>{{_ "Selected_agents"}}</legend>
+
+						<div class="list">
+							<table>
+								<thead>
 									<tr>
-										<td colspan="2">{{_ "There_are_no_agents_added_to_this_department_yet"}}</td>
+										<th width="25%">{{_ "Username"}}</th>
+										<th>{{_ "Count"}}</th>
+										<th>{{_ "Order"}}</th>
+										<th>&nbsp;</th>
 									</tr>
-								{{/if}}
-							</tbody>
-						</table>
-					</div>
+								</thead>
+								<tbody>
+									{{#if selectedAgents}}
+										{{#each selectedAgents}}
+											<tr class="agent-info">
+												<td>{{username}}</td>
+												<td><input type="text" class="count-{{agentId}}" name="count" value="{{count}}" size="3"></td>
+												<td><input type="text" class="order-{{agentId}}" name="order" value="{{order}}" size="3"></td>
+												<td><a href="#remove" class="remove-agent"><i class="icon-trash"></i></a></td>
+											</tr>
+										{{/each}}
+									{{else}}
+										<tr>
+											<td colspan="4">{{_ "There_are_no_agents_added_to_this_department_yet"}}</td>
+										</tr>
+									{{/if}}
+								</tbody>
+							</table>
+						</div>
+
+					</fieldset>
+
 				</fieldset>
 				<div class="submit">
 					<button type="button" class="button secondary back"><i class="icon-left-big"></i><span>{{_ "Back"}}</span></button>
diff --git a/packages/rocketchat-livechat/client/views/app/livechatDepartmentForm.js b/packages/rocketchat-livechat/client/views/app/livechatDepartmentForm.js
index d4ff6d0fcac65b7cd1ed2d59538d947dd2d37e8a..6f5017e0ca2efb8234d0696c6b4339f001cd23d4 100644
--- a/packages/rocketchat-livechat/client/views/app/livechatDepartmentForm.js
+++ b/packages/rocketchat-livechat/client/views/app/livechatDepartmentForm.js
@@ -1,10 +1,16 @@
 Template.livechatDepartmentForm.helpers({
 	department() {
-		// return Template.instance().department && !_.isEmpty(Template.instance().department.get()) ? Template.instance().department.get() : { enabled: true };
 		return Template.instance().department.get();
 	},
 	agents() {
 		return Template.instance().department && !_.isEmpty(Template.instance().department.get()) ? Template.instance().department.get().agents : []
+	},
+	selectedAgents() {
+		return _.sortBy(Template.instance().selectedAgents.get(), 'username');
+	},
+	availableAgents() {
+		var selected = _.pluck(Template.instance().selectedAgents.get(), 'username');
+		return AgentUsers.find({ username: { $nin: selected }}, { sort: { username: 1 } });
 	}
 });
 
@@ -29,16 +35,22 @@ Template.livechatDepartmentForm.events({
 		var oldBtnValue = $btn.html();
 		$btn.html(t('Saving'));
 
-		agents = instance.department && !_.isEmpty(instance.department.get()) ? instance.department.get().agents : [];
-
-		departmentData = {
+		var departmentData = {
 			enabled: enabled === "1" ? true : false,
 			name: name.trim(),
-			description: description.trim(),
-			agents: agents
-		}
+			description: description.trim()
+		};
+
+		var departmentAgents = [];
+
+		instance.selectedAgents.get().forEach((agent) => {
+			agent.count = instance.$('.count-' + agent.agentId).val();
+			agent.order = instance.$('.order-' + agent.agentId).val();
+
+			departmentAgents.push(agent);
+		});
 
-		Meteor.call('livechat:saveDepartment', _id, departmentData, function(error, result) {
+		Meteor.call('livechat:saveDepartment', _id, departmentData, departmentAgents, function(error, result) {
 			$btn.html(oldBtnValue);
 			if (error) {
 				return toastr.error(t(error.reason || error.error));
@@ -54,59 +66,44 @@ Template.livechatDepartmentForm.events({
 		FlowRouter.go('livechat-departments');
 	},
 
-	'click button.add-agent' (e, instance) {
+	'click .remove-agent' (e, instance) {
 		e.preventDefault();
-		var $btn = $(e.currentTarget);
-
-		var $agent = instance.$('input[name=agent]')
-
-		if ($agent.val().trim() === '') {
-			return toastr.error(t('Please_fill_a_username'));
-		}
-
-		var oldBtnValue = $btn.html();
-		$btn.html(t('Saving'));
 
-		Meteor.call('livechat:searchAgent', $agent.val(), function(error, user) {
-			$btn.html(oldBtnValue);
-			if (error) {
-				return toastr.error(t(error.reason || error.error));
-			}
-			department = instance.department.get() || {};
-			if (department.agents === undefined || !_.isArray(department.agents)) {
-				department.agents = [];
-			}
-			if (!_.findWhere(department.agents, { _id: user._id })) {
-				department.agents.push(user);
-			}
-			instance.department.set(department);
-			$agent.val('');
-		});
+		var selectedAgents = instance.selectedAgents.get();
+		selectedAgents = _.reject(selectedAgents, (agent) => { return agent._id === this._id });
+		instance.selectedAgents.set(selectedAgents);
 	},
 
-	'click a.remove-agent' (e, instance) {
-		e.preventDefault();
-		department = instance.department.get();
-		department.agents = _.reject(department.agents, (agent) => { return agent._id === this._id });
-		instance.department.set(department);
-	},
-
-	'keydown input[name=agent]' (e, instance) {
-		if (e.keyCode === 13) {
-			e.preventDefault();
-			$("button.add-agent").click();
-		}
+	'click .available-agents li' (e, instance) {
+		var selectedAgents = instance.selectedAgents.get();
+		var agent = _.clone(this);
+		agent.agentId = this._id;
+		delete agent._id;
+		selectedAgents.push(agent);
+		instance.selectedAgents.set(selectedAgents);
 	}
 });
 
 Template.livechatDepartmentForm.onCreated(function() {
 	this.department = new ReactiveVar({ enabled: true });
+	this.selectedAgents = new ReactiveVar([]);
+
+	this.subscribe('livechat:agents');
+
 	this.autorun(() => {
 		var sub = this.subscribe('livechat:departments', FlowRouter.getParam('_id'));
 		if (sub.ready()) {
 			department = LivechatDepartment.findOne({ _id: FlowRouter.getParam('_id') });
 			if (department) {
 				this.department.set(department);
+
+				this.subscribe('livechat:departmentAgents', department._id, () => {
+					var newSelectedAgents = [];
+					LivechatDepartmentAgents.find({ departmentId: department._id }).forEach((agent) => {
+						newSelectedAgents.push(agent);
+					});
+					this.selectedAgents.set(newSelectedAgents);
+				});
 			}
 		}
 	});
diff --git a/packages/rocketchat-livechat/client/views/app/livechatDepartments.js b/packages/rocketchat-livechat/client/views/app/livechatDepartments.js
index eba12b82bc14bdec7d16bca2d36465b25c14f4f0..e5d0746485dc5ca44f2183e639372807151d4e8e 100644
--- a/packages/rocketchat-livechat/client/views/app/livechatDepartments.js
+++ b/packages/rocketchat-livechat/client/views/app/livechatDepartments.js
@@ -1,11 +1,6 @@
 Template.livechatDepartments.helpers({
 	"departments": () => {
 		return LivechatDepartment.find();
-	},
-	"numAgents"() {
-		if (Array.isArray(this.agents)) {
-			return this.agents.length;
-		}
 	}
 });
 
diff --git a/packages/rocketchat-livechat/client/views/app/livechatUsers.js b/packages/rocketchat-livechat/client/views/app/livechatUsers.js
index 5e29f332b938847d31fba73dcb20fde1d8c545f8..eeb2d1dfa783871db0ac7e895ea3ec79d40ff31a 100644
--- a/packages/rocketchat-livechat/client/views/app/livechatUsers.js
+++ b/packages/rocketchat-livechat/client/views/app/livechatUsers.js
@@ -1,8 +1,6 @@
-var AgentUsers;
 var ManagerUsers;
 
 Meteor.startup(function() {
-	AgentUsers = new Mongo.Collection('agentUsers');
 	ManagerUsers = new Mongo.Collection('managerUsers');
 });
 
diff --git a/packages/rocketchat-livechat/client/views/sideNav/livechatFlex.html b/packages/rocketchat-livechat/client/views/sideNav/livechatFlex.html
index a859f5385a506e35d7a26bc9766037254c8fdff7..15d3ed86810d5ea9900b2019a5a1e405bcaf0040 100644
--- a/packages/rocketchat-livechat/client/views/sideNav/livechatFlex.html
+++ b/packages/rocketchat-livechat/client/views/sideNav/livechatFlex.html
@@ -10,7 +10,7 @@
 				<li>
 					<!-- <a href="{{pathFor 'livechat-dashboard'}}" class="{{active 'livechat-dashboard'}}">{{_ "Dashboard"}}</a> -->
 					<a href="{{pathFor 'livechat-users'}}" class="{{active 'livechat-users'}}">{{_ "User_management"}}</a>
-					<a href="{{pathFor 'livechat-departments'}}" class="{{active 'livechat-departments'}}">{{_ "Departments"}}</a>
+					<a href="{{pathFor 'livechat-departments'}}" class="{{active 'livechat-departments' 'livechat-department-edit'}}">{{_ "Departments"}}</a>
 					<a href="{{pathFor 'livechat-triggers'}}" class="{{active 'livechat-triggers'}}">{{_ "Triggers"}}</a>
 					<a href="{{pathFor 'livechat-installation'}}" class="{{active 'livechat-installation'}}">{{_ "Installation"}}</a>
 					<a href="{{pathFor 'livechat-appearance'}}" class="{{active 'livechat-appearance'}}">{{_ "Appearance"}}</a>
diff --git a/packages/rocketchat-livechat/client/views/sideNav/livechatFlex.js b/packages/rocketchat-livechat/client/views/sideNav/livechatFlex.js
index 4e2578cea84e482ae48969d0c515713f126c3d4d..f7a8f2f0accfa20b5f6c2ac43157e25744ef432b 100644
--- a/packages/rocketchat-livechat/client/views/sideNav/livechatFlex.js
+++ b/packages/rocketchat-livechat/client/views/sideNav/livechatFlex.js
@@ -1,7 +1,7 @@
 Template.livechatFlex.helpers({
-	active (route) {
+	active (...routes) {
 		FlowRouter.watchPathChange();
-		if (FlowRouter.current().route.name === route) {
+		if (routes.indexOf(FlowRouter.current().route.name) !== -1) {
 			return 'active';
 		}
 	}
diff --git a/packages/rocketchat-livechat/i18n/en.i18n.json b/packages/rocketchat-livechat/i18n/en.i18n.json
index 072aeddc3204eab22611987f8b9da8c5a5469d2c..754decc3449151c2131a047e0d8f0fab4c8b9bc0 100644
--- a/packages/rocketchat-livechat/i18n/en.i18n.json
+++ b/packages/rocketchat-livechat/i18n/en.i18n.json
@@ -4,9 +4,11 @@
   "Add_manager" : "Add manager",
   "Agent_added" : "Agent added",
   "Agent_removed" : "Agent removed",
+  "Available_agents" : "Available agents",
   "Back" : "Back",
   "Closed" : "Closed",
   "Copy_to_clipboard" : "Copy to clipboard",
+  "Count" : "Count",
   "Dashboard" : "Dashboard",
   "Department_not_found" : "Department not found",
   "Department_removed" : "Department removed",
@@ -32,10 +34,12 @@
   "New_Department" : "New Department",
   "Num_Agents" : "# Agents",
   "Opened" : "Opened",
+  "Order" : "Order",
   "Please_fill_a_name" : "Please fill a name",
   "Please_fill_a_username" : "Please fill a username",
   "Please_select_enabled_yes_or_no" : "Please select an option for Enabled",
   "Saved" : "Saved",
+  "Selected_agents" : "Selected agents",
   "Send_a_message" : "Send a message",
   "Theme" : "Theme",
   "There_are_no_agents_added_to_this_department_yet" : "There are no agents added to this department yet.",
@@ -48,4 +52,4 @@
   "Username_not_found" : "Username not found",
   "Visitor_page_URL" : "Visitor page URL",
   "Visitor_time_on_site" : "Visitor time on site"
-}
\ No newline at end of file
+}
diff --git a/packages/rocketchat-livechat/package.js b/packages/rocketchat-livechat/package.js
index b692038ae8d6f929d7b09cb48c743afdf3414b9c..f6b14d25635b5704926377669406c7b63bcd597e 100644
--- a/packages/rocketchat-livechat/package.js
+++ b/packages/rocketchat-livechat/package.js
@@ -38,6 +38,12 @@ Package.onUse(function(api) {
 
 	api.addFiles('client/stylesheets/livechat.less', 'client');
 
+	// collections
+	api.addFiles('client/collections/AgentUsers.js', 'client');
+	api.addFiles('client/collections/LivechatDepartment.js', 'client');
+	api.addFiles('client/collections/LivechatDepartmentAgents.js', 'client');
+	api.addFiles('client/collections/LivechatTrigger.js', 'client');
+
 	// client views
 	api.addFiles('client/views/app/livechatAppearance.html', 'client');
 	api.addFiles('client/views/app/livechatAppearance.js', 'client');
@@ -80,13 +86,14 @@ Package.onUse(function(api) {
 	api.addFiles('server/models/Users.js', 'server');
 	api.addFiles('server/models/Rooms.js', 'server');
 	api.addFiles('server/models/LivechatDepartment.js', 'server');
+	api.addFiles('server/models/LivechatDepartmentAgents.js', 'server');
 	api.addFiles('server/models/LivechatTrigger.js', 'server');
 
-	// collections
-	api.addFiles('client/lib/LivechatDepartment.js', 'client');
-	api.addFiles('client/lib/LivechatTrigger.js', 'client');
+	// server lib
+	api.addFiles('server/lib/getNextAgent.js', 'server');
 
 	// publications
+	api.addFiles('server/publications/departmentAgents.js', 'server');
 	api.addFiles('server/publications/livechatAgents.js', 'server');
 	api.addFiles('server/publications/livechatManagers.js', 'server');
 	api.addFiles('server/publications/livechatDepartments.js', 'server');
diff --git a/packages/rocketchat-livechat/server/lib/getNextAgent.js b/packages/rocketchat-livechat/server/lib/getNextAgent.js
index 1e9aba08673c6f860d2f00c818f0ac0edbbeaa3c..3259ab642d93af8edf58f88aed3855b42bb3a3d2 100644
--- a/packages/rocketchat-livechat/server/lib/getNextAgent.js
+++ b/packages/rocketchat-livechat/server/lib/getNextAgent.js
@@ -1,27 +1,8 @@
 this.getNextAgent = function(department) {
 	var agentFilter = {};
 
-	// find agents from that department
 	if (department) {
-		var agents = RocketChat.models.LivechatDepartment.getNextAgent(department);
-
-		if (!agents) {
-			return;
-		}
-
-		// sort = {
-		// 	count: 1,
-		// 	order: 1,
-		// 	'user.name': 1
-		// }
-
-		// update = {
-		// 	$inc: {
-		// 		count: 1
-		// 	}
-		// }
-
-		// queueUser = findAndModify query, sort, update
+		return RocketChat.models.LivechatDepartment.getNextAgent(department);
 	} else {
 		return RocketChat.models.Users.getNextAgent();
 	}
diff --git a/packages/rocketchat-livechat/server/methods/saveDepartment.js b/packages/rocketchat-livechat/server/methods/saveDepartment.js
index de3f656817bc755167fc25da10687862a884758d..2f626c395720add0dfd8b8e533a5363c955b21ea 100644
--- a/packages/rocketchat-livechat/server/methods/saveDepartment.js
+++ b/packages/rocketchat-livechat/server/methods/saveDepartment.js
@@ -1,5 +1,5 @@
 Meteor.methods({
-	'livechat:saveDepartment' (_id, departmentData) {
+	'livechat:saveDepartment' (_id, departmentData, departmentAgents) {
 		if (!Meteor.userId() || !RocketChat.authz.hasPermission(Meteor.userId(), 'view-livechat-manager')) {
 			throw new Meteor.Error("not-authorized");
 		}
@@ -17,6 +17,6 @@ Meteor.methods({
 			}
 		}
 
-		return RocketChat.models.LivechatDepartment.createOrUpdateDepartment(_id, departmentData.enabled, departmentData.name, departmentData.description, departmentData.agents);
+		return RocketChat.models.LivechatDepartment.createOrUpdateDepartment(_id, departmentData.enabled, departmentData.name, departmentData.description, departmentAgents);
 	}
 });
diff --git a/packages/rocketchat-livechat/server/models/LivechatDepartment.js b/packages/rocketchat-livechat/server/models/LivechatDepartment.js
index 41141b8d68ef4943ed85dfe3b10ec25c8058b010..d474415ea9638d0e08ee60f2134c6ddb5fc5810c 100644
--- a/packages/rocketchat-livechat/server/models/LivechatDepartment.js
+++ b/packages/rocketchat-livechat/server/models/LivechatDepartment.js
@@ -19,23 +19,42 @@ class LivechatDepartment extends RocketChat.models._Base {
 		return this.find(query, options);
 	}
 
-	// UPSERT
 	createOrUpdateDepartment(_id, enabled, name, description, agents, extraData) {
-		record = {
+		var agents = [].concat(agents);
+
+		var record = {
 			enabled: enabled,
 			name: name,
 			description: description,
-			agents: []
-		}
+			numAgents: agents.length
+		};
+
+		_.extend(record, extraData);
 
-		if (!_.isEmpty(agents)) {
-			for (agent of agents) {
-				record.agents.push({ _id: agent._id, username: agent.username });
-			}
+		if (_id) {
+			this.update({ _id: _id }, { $set: record });
+		} else {
+			_id = this.insert(record);
 		}
 
-		_.extend(record, extraData);
-		this.upsert({ _id: _id }, { $set: record });
+		var savedAgents = _.pluck(RocketChat.models.LivechatDepartmentAgents.findByDepartmentId(_id).fetch(), 'agentId');
+		var agentsToSave = _.pluck(agents, 'agentId');
+
+		// remove other agents
+		_.difference(savedAgents, agentsToSave).forEach((agentId) => {
+			RocketChat.models.LivechatDepartmentAgents.removeByDepartmentIdAndAgentId(_id, agentId);
+		});
+
+		agents.forEach((agent) => {
+			RocketChat.models.LivechatDepartmentAgents.saveAgent({
+				agentId: agent.agentId,
+				departmentId: _id,
+				username: agent.username,
+				count: parseInt(agent.count),
+				order: parseInt(agent.order)
+			});
+		});
+
 		return _.extend(record, { _id: _id });
 	}
 
diff --git a/packages/rocketchat-livechat/server/models/LivechatDepartmentAgents.js b/packages/rocketchat-livechat/server/models/LivechatDepartmentAgents.js
new file mode 100644
index 0000000000000000000000000000000000000000..a4d56fa7ba825bd433ef79164403bab624fb0b3b
--- /dev/null
+++ b/packages/rocketchat-livechat/server/models/LivechatDepartmentAgents.js
@@ -0,0 +1,71 @@
+/**
+ * Livechat Department model
+ */
+class LivechatDepartmentAgents extends RocketChat.models._Base {
+	constructor() {
+		super();
+		this._initModel('livechat_department_agents');
+	}
+
+	findByDepartmentId(departmentId) {
+		return this.find({ departmentId: departmentId });
+	}
+
+	saveAgent(agent) {
+		if (agent._id) {
+			return this.update({ _id: _id }, { $set: agent });
+		} else {
+			return this.upsert({
+				agentId: agent.agentId,
+				departmentId: agent.departmentId
+			}, {
+				$set: {
+					username: agent.username,
+					count: parseInt(agent.count),
+					order: parseInt(agent.order)
+				}
+			});
+		}
+	}
+
+	removeByDepartmentIdAndAgentId(departmentId, agentId) {
+		this.remove({ departmentId: departmentId, agentId: agentId });
+	}
+
+	getNextAgentForDepartment(departmentId) {
+		var agents = this.findByDepartmentId(departmentId).fetch();
+
+		if (agents.length === 0) {
+			return;
+		}
+
+		var onlineUsers = RocketChat.models.Users.findOnlineUserFromList(_.pluck(agents, 'username'));
+
+		var onlineUsernames = _.pluck(onlineUsers.fetch(), 'username');
+
+		var query = {
+			departmentId: departmentId,
+			username: {
+				$in: onlineUsernames
+			}
+		};
+
+		var sort = {
+			count: 1,
+			sort: 1,
+			username: 1
+		};
+		var update = {
+			$inc: {
+				count: 1
+			}
+		};
+
+		var collectionObj = this.model.rawCollection();
+		var findAndModify = Meteor.wrapAsync(collectionObj.findAndModify, collectionObj);
+
+		return findAndModify(query, sort, update);
+	}
+}
+
+RocketChat.models.LivechatDepartmentAgents = new LivechatDepartmentAgents();
diff --git a/packages/rocketchat-livechat/server/publications/departmentAgents.js b/packages/rocketchat-livechat/server/publications/departmentAgents.js
new file mode 100644
index 0000000000000000000000000000000000000000..b09f4fe3dd9c7f604544f97b557308f78a727dbf
--- /dev/null
+++ b/packages/rocketchat-livechat/server/publications/departmentAgents.js
@@ -0,0 +1,11 @@
+Meteor.publish('livechat:departmentAgents', function(departmentId) {
+	if (!this.userId) {
+		throw new Meteor.Error('not-authorized');
+	}
+
+	if (!RocketChat.authz.hasPermission(this.userId, 'view-livechat-manager')) {
+		throw new Meteor.Error('not-authorized');
+	}
+
+	return RocketChat.models.LivechatDepartmentAgents.find({ departmentId: departmentId });
+});
diff --git a/packages/rocketchat-message-attachments/client/messageAttachment.html b/packages/rocketchat-message-attachments/client/messageAttachment.html
index a4abddf40450aa55b08a05e5e09421fda2ecadba..dc02f0c03c968e20e0079ac796f64ee67e9cb910 100644
--- a/packages/rocketchat-message-attachments/client/messageAttachment.html
+++ b/packages/rocketchat-message-attachments/client/messageAttachment.html
@@ -9,7 +9,7 @@
 				{{#if author_link}}
 					<div class="attachment-author">
 						{{#if author_icon}}
-							<img src="{{author_icon}}">
+							<img src="{{fixCordova author_icon}}">
 						{{/if}}
 						<a href="{{fixCordova author_link}}" target="_blank">{{author_name}}</a>
 					</div>
@@ -49,7 +49,7 @@
 				<div class="attachment-image">
 					{{#if showImage}}
 						<a href="{{fixCordova image_url}}" class="swipebox" target="_blank">
-							<div class="inline-image" style="background-image: url({{fixCordova image_url}});">
+							<div class="inline-image" style="background-image: url('{{fixCordova image_url}}');">
 								<img src="{{fixCordova image_url}}" height="{{getImageHeight image_dimensions.height}}">
 							</div>
 						</a>
diff --git a/packages/rocketchat-oembed/client/oembedImageWidget.html b/packages/rocketchat-oembed/client/oembedImageWidget.html
index d17ed9ff03a361714fc5637525a921418a07270c..144dd7665215be92aefe9b16c2d9d8c8584e22a8 100644
--- a/packages/rocketchat-oembed/client/oembedImageWidget.html
+++ b/packages/rocketchat-oembed/client/oembedImageWidget.html
@@ -3,7 +3,7 @@
 		{{#if parsedUrl}}
 			<div>
 				<a href="{{url}}" class="swipebox" target="_blank">
-					<div class="inline-image" style="background-image: url({{url}});">
+					<div class="inline-image" style="background-image: url('{{url}}');">
 						<img src="{{url}}" height="200">
 					</div>
 				</a>
diff --git a/packages/rocketchat-theme/assets/stylesheets/base.less b/packages/rocketchat-theme/assets/stylesheets/base.less
index 34b5de48abc488a8ff71e69f61ea24d483ef0da7..471f876ec525bebd4f8ab1c4ce04a7cf5759273c 100644
--- a/packages/rocketchat-theme/assets/stylesheets/base.less
+++ b/packages/rocketchat-theme/assets/stylesheets/base.less
@@ -1583,7 +1583,7 @@ a.github-fork {
 		}
 	}
 	h2 {
-		max-width: 90%;
+		width: 100%;
 		overflow: hidden;
 		white-space: nowrap;
 		text-overflow: ellipsis;
@@ -2475,6 +2475,12 @@ a.github-fork {
 			border-radius: 4px;
 		}
 	}
+	&.selectable .message {
+		cursor: pointer;
+		&.selected {
+			background-color: #FFD;
+		}
+	}
 }
 
 .ticks-bar {
@@ -2493,7 +2499,7 @@ a.github-fork {
 }
 
 .message {
-	padding: 11px 20px 11px 70px;
+	padding: 8px 20px 4px 70px;
 	position: relative;
 	line-height: 20px;
 	min-height: 40px;
@@ -2635,7 +2641,6 @@ a.github-fork {
 	.thumb {
 		position: absolute;
 		left: 20px;
-		top: 11px;
 		display: block;
 		width: 40px;
 		height: 40px;
@@ -2671,6 +2676,7 @@ a.github-fork {
 		min-height: 20px;
 		padding-top: 4px;
 		padding-bottom: 4px;
+		margin-top: 0px;
 		.user {
 			display: none;
 		}
@@ -2699,6 +2705,9 @@ a.github-fork {
 				margin-left: 1px;
 			}
 		}
+		.body {
+			margin-top: 0px;
+		}
 
 		// .message-dropdown {
 		// 	top: 100%;
@@ -2735,6 +2744,7 @@ a.github-fork {
 	.body {
 		opacity: 1;
 		.transition(opacity 1s linear);
+		margin-top: 2px;
 
 		.inline-image {
 			background-size: contain;
@@ -2765,9 +2775,9 @@ a.github-fork {
 
 .compact {
 	.message {
-		padding: 5px 20px 5px 70px;
-		.thumb {
-			top: 5px;
+		padding: 4px 20px 4px 70px;
+		.body {
+			margin-top: 0px;
 		}
 	}
 }
diff --git a/packages/rocketchat-theme/assets/stylesheets/rtl.less b/packages/rocketchat-theme/assets/stylesheets/rtl.less
index 9f4d66fcd297e795c2343024855f88efe793687c..2ad79e63b2e44c0235c390d8688a0a13eed94c36 100644
--- a/packages/rocketchat-theme/assets/stylesheets/rtl.less
+++ b/packages/rocketchat-theme/assets/stylesheets/rtl.less
@@ -109,6 +109,7 @@
 		ul .opt {
 			.left(0px);
 			.padding-left(10px);
+			text-align: left;
 		}
 		.flex-nav {
 			.right(0px);
diff --git a/packages/rocketchat-ui-admin/admin/users/adminUserEdit.coffee b/packages/rocketchat-ui-admin/admin/users/adminUserEdit.coffee
index f089dff3bed1190176132eeb2e9bea31b5b9da2a..aeb9352b1558b88b9733e57184d6fcfdcc410f76 100644
--- a/packages/rocketchat-ui-admin/admin/users/adminUserEdit.coffee
+++ b/packages/rocketchat-ui-admin/admin/users/adminUserEdit.coffee
@@ -23,6 +23,7 @@ Template.adminUserEdit.onCreated ->
 		userData = { _id: Template.currentData()._id }
 		userData.name = $("#name", ".edit-form").val()
 		userData.username = $("#username", ".edit-form").val()
+		userData.password = $("#password", ".edit-form").val()
 
 		unless userData._id and userData.name
 			toastr.error TAPi18n.__('The_field_is_required'), TAPi18n.__('Name')
@@ -32,4 +33,4 @@ Template.adminUserEdit.onCreated ->
 					toastr.success t('User_updated_successfully')
 					instance.cancel()
 				if error
-					toastr.error error.reason
\ No newline at end of file
+					toastr.error error.reason
diff --git a/packages/rocketchat-ui-admin/admin/users/adminUserEdit.html b/packages/rocketchat-ui-admin/admin/users/adminUserEdit.html
index 686f999ffdba88b0c4db402a401fba8d0247fbf8..f1e620f95f96097c3dc9e0066633a6be064e5e37 100644
--- a/packages/rocketchat-ui-admin/admin/users/adminUserEdit.html
+++ b/packages/rocketchat-ui-admin/admin/users/adminUserEdit.html
@@ -13,6 +13,12 @@
 					<label for="username">{{_ "Username"}}</label>
 					<input type="text" id="username" autocomplete="off" value="{{username}}">
 				</div>
+				{{#if hasPermission 'edit-other-user-password'}}
+				<div class="input-line">
+					<label for="password">{{_ "Password"}}</label>
+					<input type="password" id="password" autocomplete="off" value="">
+				</div>
+				{{/if}}
 			</form>
 		</div>
 		<nav>
@@ -20,4 +26,4 @@
 			<button class='button button-block blue save'><span>{{_ "Save"}}</span></button>
 		</nav>
 	{{/unless}}
-</template>
\ No newline at end of file
+</template>
diff --git a/packages/rocketchat-ui-sidenav/side-nav/createChannelFlex.coffee b/packages/rocketchat-ui-sidenav/side-nav/createChannelFlex.coffee
index 7d5448acdb925e9d3ef806ce7acb198e5dbf9919..a6abfa19958ea9006224cad14569b3b2c0ecb2a3 100644
--- a/packages/rocketchat-ui-sidenav/side-nav/createChannelFlex.coffee
+++ b/packages/rocketchat-ui-sidenav/side-nav/createChannelFlex.coffee
@@ -90,6 +90,9 @@ Template.createChannelFlex.events
 					if err.error is 'duplicate-name'
 						instance.error.set({ duplicate: true })
 						return
+					if err.error is 'archived-duplicate-name'
+						instance.error.set({ archivedduplicate: true })
+						return
 					else
 						return toastr.error err.reason
 
diff --git a/packages/rocketchat-ui-sidenav/side-nav/createChannelFlex.html b/packages/rocketchat-ui-sidenav/side-nav/createChannelFlex.html
index 2f5e30431261b80a07e7c46c10ffa6f4489419b3..32f223608d24a7db70f8057a24cd895393877b1c 100644
--- a/packages/rocketchat-ui-sidenav/side-nav/createChannelFlex.html
+++ b/packages/rocketchat-ui-sidenav/side-nav/createChannelFlex.html
@@ -40,6 +40,12 @@
 					{{{_ "Duplicate_channel_name" roomName}}}
 				</div>
 			{{/if}}
+			{{#if error.archivedduplicate}}
+				<div class="input-error">
+					<strong>{{_ "Oops!"}}</strong>
+					{{{_ "Duplicate_archived_channel_name" roomName}}}
+				</div>
+			{{/if}}
 			<div class="input-submit">
 				<button class="button clean primary save-channel">{{_ "Save" }}</button>
 				<button class="button clean cancel-channel">{{_ "Cancel" }}</button>
diff --git a/packages/rocketchat-ui-sidenav/side-nav/listPrivateGroupsFlex.coffee b/packages/rocketchat-ui-sidenav/side-nav/listPrivateGroupsFlex.coffee
index 6b15e8505425b34915df3dbfc4069c6c66f02c80..b542942819e06e1307a21719e8dac2415e925ce1 100644
--- a/packages/rocketchat-ui-sidenav/side-nav/listPrivateGroupsFlex.coffee
+++ b/packages/rocketchat-ui-sidenav/side-nav/listPrivateGroupsFlex.coffee
@@ -1,6 +1,6 @@
 Template.listPrivateGroupsFlex.helpers
 	groups: ->
-    return ChatSubscription.find { t: { $in: ['p']}, f: { $ne: true } }, { sort: 't': 1, 'name': 1 }
+    return ChatSubscription.find { t: { $in: ['p']}, f: { $ne: true }, archived: { $ne: true } }, { sort: 't': 1, 'name': 1 }
 
 Template.listPrivateGroupsFlex.events
 	'click header': ->
diff --git a/packages/rocketchat-ui-sidenav/side-nav/privateGroupsFlex.coffee b/packages/rocketchat-ui-sidenav/side-nav/privateGroupsFlex.coffee
index 2b8db2c1bd674a2a20d6cccd869cce013d9e0b55..260dec67a5caac176621354b0a0fcc7a4e0f5ec7 100644
--- a/packages/rocketchat-ui-sidenav/side-nav/privateGroupsFlex.coffee
+++ b/packages/rocketchat-ui-sidenav/side-nav/privateGroupsFlex.coffee
@@ -85,6 +85,9 @@ Template.privateGroupsFlex.events
 					if err.error is 'duplicate-name'
 						instance.error.set({ duplicate: true })
 						return
+					if err.error is 'archived-duplicate-name'
+						instance.error.set({ archivedduplicate: true })
+						return
 					return toastr.error err.reason
 				SideNav.closeFlex()
 				instance.clearForm()
diff --git a/packages/rocketchat-ui-sidenav/side-nav/privateGroupsFlex.html b/packages/rocketchat-ui-sidenav/side-nav/privateGroupsFlex.html
index 24e9050283e27813df21f4a69c9df52371dcb6d1..821a4361efa441be9540cea27067762e3d33c850 100644
--- a/packages/rocketchat-ui-sidenav/side-nav/privateGroupsFlex.html
+++ b/packages/rocketchat-ui-sidenav/side-nav/privateGroupsFlex.html
@@ -40,6 +40,12 @@
 					{{{_ "Duplicate_private_group_name" groupName}}}
 				</div>
 			{{/if}}	
+			{{#if error.archivedduplicate}}
+				<div class="input-error">
+					<strong>{{_ "Oops!"}}</strong>
+					{{{_ "Duplicate_archived_private_group_name" groupName}}}
+				</div>
+			{{/if}}	
 			<div class="input-submit">
 				<button class="button clean primary save-pvt-group">{{_ "Save" }}</button>
 				<button class="button clean cancel-pvt-group">{{_ "Cancel" }}</button>
diff --git a/packages/rocketchat-ui/views/app/privateHistory.coffee b/packages/rocketchat-ui/views/app/privateHistory.coffee
index b04ecd4f8037f91a75c05d9bb8c0e097e9a363a3..97a45d9aca7b7af95cb98de037015edd53392fb1 100644
--- a/packages/rocketchat-ui/views/app/privateHistory.coffee
+++ b/packages/rocketchat-ui/views/app/privateHistory.coffee
@@ -1,6 +1,13 @@
 Template.privateHistory.helpers
 	history: ->
-		items = ChatSubscription.find { name: { $regex: Session.get('historyFilter'), $options: 'i' }, t: { $in: ['d', 'c', 'p'] } }, {'sort': { 'ts': -1 } }
+		items = ChatSubscription.find { name: { $regex: Session.get('historyFilter'), $options: 'i' }, t: { $in: ['d', 'c', 'p'] }, archived: { $ne: true } }, {'sort': { 'ts': -1 } }
+		return {
+			items: items
+			length: items.count()
+		}
+
+	archivedHistory: ->
+		items = ChatSubscription.find { name: { $regex: Session.get('historyFilter'), $options: 'i' }, t: { $in: ['d', 'c', 'p'] }, archived: true }, {'sort': { 'ts': -1 } }
 		return {
 			items: items
 			length: items.count()
diff --git a/packages/rocketchat-ui/views/app/privateHistory.html b/packages/rocketchat-ui/views/app/privateHistory.html
index 7b51de5161cd0af6e14acd06109220772742101b..fd8d6caa3a4644aad0f692f0ec0e7c551cc74e90 100644
--- a/packages/rocketchat-ui/views/app/privateHistory.html
+++ b/packages/rocketchat-ui/views/app/privateHistory.html
@@ -35,6 +35,29 @@
 					</a>
 				{{/each}}
 			</div>
+			<div class="results">
+				{{{_ "Showing_archived_results" archivedHistory.length}}}
+			</div>
+			<div class="list">
+				{{#each archivedHistory.items}}
+					<a href="{{path}}">
+						<div class="info">
+							<h3><i class="{{type}}"></i><span class="enter-room">{{name}}</span></h3>
+							<ul>
+								{{#with roomOf rid}}
+									<li>{{_ "n_messages" msgs}}</li>
+									<li>{{_ "since_creation" creation}}</li>
+								{{/with}}
+							</ul>
+						</div>
+						<div class="status">
+							{{#with roomOf rid}}
+								<strong>{{lastMessage}}</strong>
+							{{/with}}
+						</div>
+					</a>
+				{{/each}}
+			</div>
 		</div>
 	</section>
 </template>
diff --git a/packages/rocketchat-ui/views/app/room.coffee b/packages/rocketchat-ui/views/app/room.coffee
index f2b898cb3bbc725ef9616758bd61f4ce8032dd80..2127c7662af4519475c6aa461ad8a0ef2a9c6f70 100644
--- a/packages/rocketchat-ui/views/app/room.coffee
+++ b/packages/rocketchat-ui/views/app/room.coffee
@@ -201,6 +201,8 @@ Template.room.helpers
 	compactView: ->
 		return 'compact' if Meteor.user()?.settings?.preferences?.compactView
 
+	selectable: ->
+		return Template.instance().selectable.get()
 
 Template.room.events
 	"click, touchend": (e, t) ->
@@ -408,6 +410,31 @@ Template.room.events
 		template.atBottom = true
 		RoomHistoryManager.clear(template?.data?._id)
 
+	'click .message': (e, template) ->
+		if template.selectable.get()
+			document.selection?.empty() or window.getSelection?().removeAllRanges()
+			data = Blaze.getData(e.currentTarget)
+			_id = data?._arguments?[1]?._id
+
+			if !template.selectablePointer
+				template.selectablePointer = _id
+
+			if !e.shiftKey
+				template.selectedMessages = template.getSelectedMessages()
+				template.selectedRange = []
+				template.selectablePointer = _id
+
+			template.selectMessages _id
+
+			selectedMessages = $('.messages-box .message.selected').map((i, message) -> message.id)
+			removeClass = _.difference selectedMessages, template.getSelectedMessages()
+			addClass = _.difference template.getSelectedMessages(), selectedMessages
+			for message in removeClass
+				$(".messages-box ##{message}").removeClass('selected')
+			for message in addClass
+				$(".messages-box ##{message}").addClass('selected')
+
+
 Template.room.onCreated ->
 	# this.scrollOnBottom = true
 	# this.typing = new msgTyping this.data._id
@@ -415,10 +442,47 @@ Template.room.onCreated ->
 	this.atBottom = true
 	this.unreadCount = new ReactiveVar 0
 
-	self = @
+	this.selectable = new ReactiveVar false
+	this.selectedMessages = []
+	this.selectedRange = []
+	this.selectablePointer = null
+
+	this.resetSelection = (enabled) =>
+		this.selectable.set(enabled)
+		$('.messages-box .message.selected').removeClass 'selected'
+		this.selectedMessages = []
+		this.selectedRange = []
+		this.selectablePointer = null
+
+	this.selectMessages = (to) =>
+		if this.selectablePointer is to and this.selectedRange.length > 0
+			this.selectedRange = []
+		else
+			message1 = ChatMessage.findOne this.selectablePointer
+			message2 = ChatMessage.findOne to
+
+			minTs = _.min([message1.ts, message2.ts])
+			maxTs = _.max([message1.ts, message2.ts])
+
+			this.selectedRange = _.pluck(ChatMessage.find({ rid: message1.rid, ts: { $gte: minTs, $lte: maxTs } }).fetch(), '_id')
+
+	this.getSelectedMessages = =>
+		messages = this.selectedMessages
+		addMessages = false
+		for message in this.selectedRange
+			if messages.indexOf(message) is -1
+				addMessages = true
+				break
+
+		if addMessages
+			previewMessages = _.compact(_.uniq(this.selectedMessages.concat(this.selectedRange)))
+		else
+			previewMessages = _.compact(_.difference(this.selectedMessages, this.selectedRange))
+
+		return previewMessages
 
-	@autorun ->
-		self.subscribe 'fullUserData', Session.get('showUserInfo'), 1
+	@autorun =>
+		@subscribe 'fullUserData', Session.get('showUserInfo'), 1
 
 
 Template.room.onDestroyed ->
diff --git a/packages/rocketchat-ui/views/app/room.html b/packages/rocketchat-ui/views/app/room.html
index d63dcc7dd97e786eb00b6599084e8141d29f717b..9f7f7f0fd91438341962908f07ebba6fb01ee597 100644
--- a/packages/rocketchat-ui/views/app/room.html
+++ b/packages/rocketchat-ui/views/app/room.html
@@ -13,11 +13,8 @@
 						<a href="#favorite" class="toggle-favorite"><i class="{{favorite}}" aria-label="{{_ favoriteLabel}}"></i></a>
 					{{/if}}
 					<i class="{{roomIcon}} status-{{userStatus}}"></i>
-					<span class="room-title {{editingTitle}}">{{roomName}}</span>
-					{{#if canEditName}}
-					<input type="text" id="room-title-field" class="{{showEditingTitle}}" value="{{roomNameEdit}}" dir="auto">
-					<a href="#edit" class="edit-room-title"><i class="icon-pencil" aria-label="{{_ "Edit"}}"></i></a>
-					{{/if}}
+					<span class="room-title">{{roomName}}</span>
+					<span class="room-topic">{{roomTopic}}</span>
 				</h2>
 			</header>
 			<div class="container-bars">
@@ -50,7 +47,7 @@
 					{{/if}}
 				{{/if}}
 			</div>
-			<div class="messages-box {{compactView}}">
+			<div class="messages-box {{#if selectable}}selectable{{/if}} {{compactView}}">
 				<div class="ticks-bar"></div>
 				<div class="wrapper {{#if hasMoreNext}}has-more-next{{/if}}">
 					<ul aria-live="polite">
diff --git a/server/methods/channelsList.coffee b/server/methods/channelsList.coffee
index 7aa42ff6351877a870f922e7286bfd9481a32fba..c57d66e3a5474f281e819d7d0c7535559ba27811 100644
--- a/server/methods/channelsList.coffee
+++ b/server/methods/channelsList.coffee
@@ -1,3 +1,3 @@
 Meteor.methods
 	channelsList: ->
-		return { channels: RocketChat.models.Rooms.findByType('c', { sort: { msgs:-1 } }).fetch() }
+		return { channels: RocketChat.models.Rooms.findByTypeAndArchivationState('c', false, { sort: { msgs:-1 } }).fetch() }
diff --git a/server/methods/createChannel.coffee b/server/methods/createChannel.coffee
index 47f97d22d407347fa10c852b774cb5c5d5f6a1bd..c2e8db8ce1da0be0424ea718f7bef65eaed48468 100644
--- a/server/methods/createChannel.coffee
+++ b/server/methods/createChannel.coffee
@@ -21,7 +21,10 @@ Meteor.methods
 
 		# avoid duplicate names
 		if RocketChat.models.Rooms.findOneByName name
-			throw new Meteor.Error 'duplicate-name'
+			if RocketChat.models.Rooms.findOneByName(name).archived
+				throw new Meteor.Error 'archived-duplicate-name'
+			else
+				throw new Meteor.Error 'duplicate-name'
 
 		# name = s.slugify name
 
diff --git a/server/methods/createPrivateGroup.coffee b/server/methods/createPrivateGroup.coffee
index d308e1e7ae9b039988e50ba67543d9108ebf5352..8bfa8304d98b5ba14b8c2d45a376e478f3cf6147 100644
--- a/server/methods/createPrivateGroup.coffee
+++ b/server/methods/createPrivateGroup.coffee
@@ -24,7 +24,10 @@ Meteor.methods
 
 		# avoid duplicate names
 		if RocketChat.models.Rooms.findOneByName name
-			throw new Meteor.Error 'duplicate-name'
+			if RocketChat.models.Rooms.findOneByName(name).archived
+				throw new Meteor.Error 'archived-duplicate-name'
+			else
+				throw new Meteor.Error 'duplicate-name'
 
 		# create new room
 		room = RocketChat.models.Rooms.createWithTypeNameUserAndUsernames 'p', name, me, members,
diff --git a/server/methods/unarchiveRoom.coffee b/server/methods/unarchiveRoom.coffee
index 7b0ae819bf4b465567f1224cc4c653e67faed912..b78a843b8e598437042609c128a7d7f586494407 100644
--- a/server/methods/unarchiveRoom.coffee
+++ b/server/methods/unarchiveRoom.coffee
@@ -1,7 +1,7 @@
 Meteor.methods
-	unArchiveRoom: (rid) ->
+	unarchiveRoom: (rid) ->
 		if not Meteor.userId()
-			throw new Meteor.Error 'invalid-user', '[methods] unArchiveRoom -> Invalid user'
+			throw new Meteor.Error 'invalid-user', '[methods] unarchiveRoom -> Invalid user'
 
 		room = RocketChat.models.Rooms.findOneById rid
 
diff --git a/server/publications/subscription.coffee b/server/publications/subscription.coffee
index dc3245e213592ee833945a8a0d45a2429f34a782..2aca0e8f1579cfcabc1dd58be47b601abe3e2ca6 100644
--- a/server/publications/subscription.coffee
+++ b/server/publications/subscription.coffee
@@ -13,3 +13,4 @@ Meteor.publish 'subscription', ->
 			open: 1
 			alert: 1
 			unread: 1
+			archived: 1
diff --git a/server/startup/roomPublishes.coffee b/server/startup/roomPublishes.coffee
index 962fc7be3789cf9f6dd0ac45b09d5b89b675960a..e8a7ab2ad9493a7aa9c78534bef1ede169c188d8 100644
--- a/server/startup/roomPublishes.coffee
+++ b/server/startup/roomPublishes.coffee
@@ -9,6 +9,7 @@ Meteor.startup ->
 				usernames: 1
 				topic: 1
 				muted: 1
+				archived: 1
 
 		return RocketChat.models.Rooms.findByTypeAndName 'c', identifier, options
 
@@ -22,6 +23,7 @@ Meteor.startup ->
 				usernames: 1
 				topic: 1
 				muted: 1
+				archived: 1
 
 		user = RocketChat.models.Users.findOneById this.userId, fields: username: 1
 		return RocketChat.models.Rooms.findByTypeAndNameContainigUsername 'p', identifier, user.username, options