diff --git a/.docker/dockerfiles/develop/Dockerfile b/.docker/dockerfiles/develop/Dockerfile
index cbb9a7bfe1246cccb971b2f421803afa17e99f09..14e23628e9916b26e23cc5ffd0035fd4856af245 100644
--- a/.docker/dockerfiles/develop/Dockerfile
+++ b/.docker/dockerfiles/develop/Dockerfile
@@ -1,30 +1,30 @@
 FROM node:0.10
 
+# IMPORTANT - FOR TESTING ONLY - DO NOT USE THIS FOR DEVELOPMENT OR PRODUCTION!
 MAINTAINER buildmaster@rocket.chat
 
-RUN apt-get update \
-&&  apt-get install -y graphicsmagick \
-&&  rm -rf /var/lib/apt/lists/*
-
 RUN groupadd -r rocketchat \
-&&  useradd -r -g rocketchat rocketchat \
-&&  mkdir /app  \
-&&  mkdir /app/uploads
+&&  useradd -r -g rocketchat rocketchat
+
+VOLUME /app/uploads
 
 # gpg: key 4FD08014: public key "Rocket.Chat Buildmaster <buildmaster@rocket.chat>" imported
 RUN gpg --keyserver ha.pool.sks-keyservers.net --recv-keys 0E163286C20D07B9787EBE9FD7F9D0414FD08104
 
+ENV RC_VERSION develop
+
 WORKDIR /app
 
-RUN curl -fSL "https://s3.amazonaws.com/rocketchatbuild/rocket.chat-develop.tgz" -o rocket.chat.tgz \
-&&  tar zxvf ./rocket.chat.tgz \
-&&  rm ./rocket.chat.tgz  \
-&&  cd /app/bundle/programs/server \
+RUN curl -fSL "https://rocket.chat/releases/${RC_VERSION}/download" -o rocket.chat.tgz \
+&&  curl -fSL "https://rocket.chat/releases/${RC_VERSION}/asc" -o rocket.chat.tgz.asc \
+&&  gpg --verify rocket.chat.tgz.asc \
+&&  tar zxvf rocket.chat.tgz \
+&&  rm rocket.chat.tgz  \
+&&  cd bundle/programs/server \
 &&  npm install
 
 USER rocketchat
 
-VOLUME /app/uploads
 WORKDIR /app/bundle
 
 # needs a mongoinstance - defaults to container linking with alias 'mongo'
@@ -34,4 +34,5 @@ ENV MONGO_URL=mongodb://mongo:27017/rocketchat \
     Accounts_AvatarStorePath=/app/uploads
 
 EXPOSE 3000
+
 CMD ["node", "main.js"]
diff --git a/.docker/dockerfiles/latest/Dockerfile b/.docker/dockerfiles/latest/Dockerfile
index 6e52e7fdf7f528327350fb75e00cff2827de207b..286962d174d6f4683e8b8e170a8d4e0539539299 100644
--- a/.docker/dockerfiles/latest/Dockerfile
+++ b/.docker/dockerfiles/latest/Dockerfile
@@ -1,33 +1,30 @@
 FROM node:0.10
 
+# crafted and tuned by pierre@ozoux.net and sing.li@rocket.chat
 MAINTAINER buildmaster@rocket.chat
 
-RUN apt-get update \
-&&  apt-get install -y graphicsmagick \
-&&  rm -rf /var/lib/apt/lists/*
-
 RUN groupadd -r rocketchat \
-&&  useradd -r -g rocketchat rocketchat \
-&&  mkdir /app  \
-&&  mkdir /app/uploads
+&&  useradd -r -g rocketchat rocketchat
+
+VOLUME /app/uploads
 
 # gpg: key 4FD08014: public key "Rocket.Chat Buildmaster <buildmaster@rocket.chat>" imported
 RUN gpg --keyserver ha.pool.sks-keyservers.net --recv-keys 0E163286C20D07B9787EBE9FD7F9D0414FD08104
 
+ENV RC_VERSION latest
+
 WORKDIR /app
 
-RUN URL="https://github.com/RocketChat/Rocket.Chat/releases/latest" \
-&&  FILE="/rocket.chat.tgz" \
-&&  HEADER=$(curl -I -s "$URL" | grep -Fi Location: | sed -En 's/.*(https?:\/\/[a-zA-Z0-9\/.-_]*).*$/\1/p') \
-&&  curl -fSL "$HEADER$FILE" -o rocket.chat.tgz \
-&&  tar zxvf ./rocket.chat.tgz \
-&&  rm ./rocket.chat.tgz  \
-&&  cd /app/bundle/programs/server \
+RUN curl -fSL "https://rocket.chat/releases/${RC_VERSION}/download" -o rocket.chat.tgz \
+&&  curl -fSL "https://rocket.chat/releases/${RC_VERSION}/asc" -o rocket.chat.tgz.asc \
+&&  gpg --verify rocket.chat.tgz.asc \
+&&  tar zxvf rocket.chat.tgz \
+&&  rm rocket.chat.tgz  \
+&&  cd bundle/programs/server \
 &&  npm install
 
 USER rocketchat
 
-VOLUME /app/uploads
 WORKDIR /app/bundle
 
 # needs a mongoinstance - defaults to container linking with alias 'mongo'
@@ -37,4 +34,5 @@ ENV MONGO_URL=mongodb://mongo:27017/rocketchat \
     Accounts_AvatarStorePath=/app/uploads
 
 EXPOSE 3000
+
 CMD ["node", "main.js"]
diff --git a/.docker/dockerfiles/master/Dockerfile b/.docker/dockerfiles/master/Dockerfile
deleted file mode 100644
index dd62d8cc71e23f6eb1f74ca660a2f4de1b54e664..0000000000000000000000000000000000000000
--- a/.docker/dockerfiles/master/Dockerfile
+++ /dev/null
@@ -1,37 +0,0 @@
-FROM node:0.10
-
-MAINTAINER buildmaster@rocket.chat
-
-RUN apt-get update \
-&&  apt-get install -y graphicsmagick \
-&&  rm -rf /var/lib/apt/lists/*
-
-RUN groupadd -r rocketchat \
-&&  useradd -r -g rocketchat rocketchat \
-&&  mkdir /app  \
-&&  mkdir /app/uploads
-
-# gpg: key 4FD08014: public key "Rocket.Chat Buildmaster <buildmaster@rocket.chat>" imported
-RUN gpg --keyserver ha.pool.sks-keyservers.net --recv-keys 0E163286C20D07B9787EBE9FD7F9D0414FD08104
-
-WORKDIR /app
-
-RUN curl -fSL "https://s3.amazonaws.com/rocketchatbuild/rocket.chat-master.tgz" -o rocket.chat.tgz \
-&&  tar zxvf ./rocket.chat.tgz \
-&&  rm ./rocket.chat.tgz  \
-&&  cd /app/bundle/programs/server \
-&&  npm install
-
-USER rocketchat
-
-VOLUME /app/uploads
-WORKDIR /app/bundle
-
-# needs a mongoinstance - defaults to container linking with alias 'mongo'
-ENV MONGO_URL=mongodb://mongo:27017/rocketchat \
-    PORT=3000 \
-    ROOT_URL=http://localhost:3000 \
-    Accounts_AvatarStorePath=/app/uploads
-
-EXPOSE 3000
-CMD ["node", "main.js"]
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/.lgtm b/.lgtm
new file mode 100644
index 0000000000000000000000000000000000000000..3db37707374a90cac9e0b8a309a3ceabbb534278
--- /dev/null
+++ b/.lgtm
@@ -0,0 +1,2 @@
+approvals = 2
+pattern = "(?i)LGTM"
diff --git a/.meteor/packages b/.meteor/packages
index b48661e4c0da6bd376d568a9ae6560d78588fca4..d75f1e099a6400eb8ab3697c328363177baba76c 100644
--- a/.meteor/packages
+++ b/.meteor/packages
@@ -34,6 +34,7 @@ session
 spacebars
 standard-minifiers
 tracker
+rocketchat:oauth2-server-config
 
 arunoda:streams
 rocketchat:lib
@@ -41,6 +42,7 @@ rocketchat:lib
 rocketchat:authorization
 rocketchat:autolinker
 rocketchat:channel-settings
+rocketchat:channel-settings-mail-messages
 rocketchat:colors
 rocketchat:custom-oauth
 rocketchat:emojione
@@ -50,17 +52,21 @@ rocketchat:github-enterprise
 rocketchat:gitlab
 rocketchat:highlight
 rocketchat:ldap
+rocketchat:livechat
 rocketchat:logger
 rocketchat:mailer
 rocketchat:markdown
 rocketchat:me
 rocketchat:mentions
+rocketchat:mentions-flextab
 rocketchat:message-pin
 rocketchat:message-star
 rocketchat:oembed
 rocketchat:slashcommands-invite
 rocketchat:slashcommands-join
+rocketchat:slashcommands-kick
 rocketchat:slashcommands-leave
+rocketchat:slashcommands-mute
 rocketchat:spotify
 rocketchat:statistics
 rocketchat:theme
@@ -79,7 +85,6 @@ rocketchat:wordpress
 #rocketchat:chatops
 #rocketchat:hubot
 #rocketchat:irc
-#rocketchat:livechat
 
 konecty:change-case
 konecty:delayed-task
@@ -98,7 +103,6 @@ kadira:blaze-layout
 kadira:flow-router
 kenton:accounts-sandstorm
 kevohagan:sweetalert
-meteorhacks:kadira
 mizzao:autocomplete
 mizzao:timesync
 momentjs:moment
@@ -107,6 +111,7 @@ mrt:reactive-store
 mystor:device-detection
 nimble:restivus
 nooitaf:colors
+ostrio:cookies@2.0.1
 pauli:accounts-linkedin
 perak:codemirror
 percolate:migrations
@@ -127,3 +132,4 @@ yasinuslu:blaze-meta
 rocketchat:assets
 rocketchat:integrations
 rocketchat:message-attachments
+rocketchat:api
diff --git a/.meteor/versions b/.meteor/versions
index 8aed6ee4dd1b8e2619240418cca63e98f1c82635..ff8301b12be4a23023887f392366928e4f2cd500 100644
--- a/.meteor/versions
+++ b/.meteor/versions
@@ -6,8 +6,7 @@ accounts-meteor-developer@1.0.6
 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.0
+aldeed:simple-schema@1.5.3
 arunoda:streams@0.1.17
 autoupdate@1.2.4
 babel-compiler@5.8.24_1
@@ -25,7 +24,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 +38,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.1
 facebook@1.2.2
 fastclick@1.0.7
 francocatena:status@1.5.0
@@ -52,7 +51,7 @@ htmljs@1.0.5
 http@1.1.1
 id-map@1.0.4
 idorecall:email-normalize@1.0.0
-jalik:ufs@0.3.3
+jalik:ufs@0.3.5
 jalik:ufs-gridfs@0.1.1
 jparker:crypto-core@0.1.0
 jparker:crypto-md5@0.1.1
@@ -75,12 +74,10 @@ 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.3.0
 meteor@1.1.10
 meteor-base@1.0.1
 meteor-developer@1.1.5
-meteorhacks:kadira@2.26.3
-meteorhacks:meteorx@1.4.1
 meteorspark:util@0.2.0
 minifiers@1.1.7
 minimongo@1.0.10
@@ -88,7 +85,7 @@ mizzao:autocomplete@0.5.1
 mizzao:timesync@0.3.4
 mobile-experience@1.0.1
 mobile-status-bar@1.0.6
-momentjs:moment@2.10.6
+momentjs:moment@2.11.1
 monbro:mongodb-mapreduce-aggregation@1.0.1
 mongo@1.1.3
 mongo-id@1.0.1
@@ -104,10 +101,11 @@ oauth1@1.1.5
 oauth2@1.1.5
 observe-sequence@1.0.7
 ordered-dict@1.0.4
+ostrio:cookies@2.0.1
 pauli:accounts-linkedin@1.2.0
 pauli:linkedin@1.2.0
 perak:codemirror@1.2.8
-percolate:migrations@0.9.7
+percolate:migrations@0.9.8
 percolate:synced-cron@1.3.0
 pntbr:js-yaml-client@0.0.1
 promise@0.5.1
@@ -122,10 +120,12 @@ reactive-dict@1.1.3
 reactive-var@1.0.6
 reload@1.1.4
 retry@1.0.4
+rocketchat:api@0.0.1
 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
@@ -138,18 +138,24 @@ rocketchat:highlight@0.0.1
 rocketchat:integrations@0.0.1
 rocketchat:ldap@0.0.1
 rocketchat:lib@0.0.1
+rocketchat:livechat@0.0.1
 rocketchat:logger@0.0.1
 rocketchat:mailer@0.0.1
 rocketchat:markdown@0.0.1
 rocketchat:me@0.0.1
 rocketchat:mentions@0.0.1
+rocketchat:mentions-flextab@0.0.1
 rocketchat:message-attachments@0.0.1
 rocketchat:message-pin@0.0.1
 rocketchat:message-star@0.0.1
+rocketchat:oauth2-server@1.4.0
+rocketchat:oauth2-server-config@1.0.0
 rocketchat:oembed@0.0.1
 rocketchat:slashcommands-invite@0.0.1
 rocketchat:slashcommands-join@0.0.1
+rocketchat:slashcommands-kick@0.0.1
 rocketchat:slashcommands-leave@0.0.1
+rocketchat:slashcommands-mute@0.0.1
 rocketchat:spotify@0.0.1
 rocketchat:statistics@0.0.1
 rocketchat:theme@0.0.1
diff --git a/.sandstorm/sandstorm-pkgdef.capnp b/.sandstorm/sandstorm-pkgdef.capnp
index 908e6daf7f9d70d8f46b41f82eb12b716a4b9b4e..8efc4b1b3b2fe5711975778cfa49d225e8113f9d 100644
--- a/.sandstorm/sandstorm-pkgdef.capnp
+++ b/.sandstorm/sandstorm-pkgdef.capnp
@@ -19,9 +19,9 @@ const pkgdef :Spk.PackageDefinition = (
 
     appTitle = (defaultText = "Rocket.Chat"),
 
-    appVersion = 5,  # Increment this for every release.
+    appVersion = 10,  # Increment this for every release.
 
-    appMarketingVersion = (defaultText = "0.9.0"),
+    appMarketingVersion = (defaultText = "0.14.0"),
     # Human-readable representation of appVersion. Should match the way you
     # identify versions of your app in documentation and marketing.
 
diff --git a/.travis.yml b/.travis.yml
index 6d5742f1429bfd65447025ee77e062400aa4d78a..9c514e8bd3eee082a0687e13f489b0060c51a14c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,12 +3,14 @@ language: node_js
 branches:
   only:
   - develop
-  - master
+  - "/^(\\d+\\.)?(\\d+\\.)?(\\*|\\d+)$/"
+git:
+  depth: 1
 node_js:
 - '0.12'
 cache:
   directories:
-    - ~/.meteor
+  - "~/.meteor"
 before_install:
 - npm install -g npm@'>=2.13.5'
 - mkdir -p node_modules
@@ -19,19 +21,25 @@ before_script:
 script:
 - meteor build /tmp/build
 before_deploy:
-- mkdir /tmp/deploy
-- .travis/namefiles.sh
-- .travis/sandstorm.sh
+- source ".travis/setartname.sh"
+- source ".travis/setdeploydir.sh"
+- ".travis/setupsig.sh"
+- ".travis/namefiles.sh"
+- ".travis/sandstorm.sh"
 deploy:
-  - provider: s3
-    access_key_id: "AKIAIKIA7H7D47KUHYCA"
-    secret_access_key: $ACCESSKEY
-    bucket: "rocketchatbuild"
-    skip_cleanup: true
-    local_dir: /tmp/deploy
-    on:
-      branch:
-      - master
-      - develop
+  provider: s3
+  access_key_id: "AKIAIKIA7H7D47KUHYCA"
+  secret_access_key: $ACCESSKEY
+  bucket: "rocketchat"
+  skip_cleanup: true
+  upload_dir: build
+  local_dir: $ROCKET_DEPLOY_DIR
+  on:
+    condition: "$TRAVIS_PULL_REQUEST=false"
+    all_branches: true
 after_deploy:
-- .travis/docker.sh
+- ".travis/docker.sh"
+- ".travis/update-releases.sh"
+env:
+  global:
+    secure: HrPOM5sBibYkMcf9aeQThYPCDiXeLkg0Xgv0HvH88/ku/gphDpNEjHNReHZM3cyfm9y3RhHpVdD+Zzy38S2goKyewRzpXJsuyerOYkjND0v3tivhs9CAX8PAUxj1U5zllTyH4bgW2ZwRtNnwnmtIM/JJlnySMpKVDqIZBpbhn3ph9bJ2J+BW3D3Jw8meQ1vCX8szIibyJK/5QX6HG2RBFXJGYoQ8DmR8jQv0aJQvT1Az5DO4yImk8tX4NP95qOc19Jywr1DsbaSBZeJ8lFJAmBpIGx7KAmUVCcxSxfbXGRhs2K4iEYb3rJ/dU6KiyPsKGUG4aYNGgbvcX0ZxX/BZ6ZU9ff0E4IIf43IxoN3ElrOqOFk5msJAXbrJEreINSzDqKOy8NFYtCQ49E2gwzfage4ZXkhFyx3wMPa5bzpr3ncsTceMjMVz03uL781X6NLuCkUmXv+n8K2MNhJU9Xinpdx1GRJm+0lXJspNNJ1ruHeJtls4epj4bmCwKmmZbFKPXqa5e8xVcMIkwt1LMiHduhE+WgKNHdOMhXrCcTxF62ybLlsHXmyLLJeNjTeKS8QG2XSoonClDAz/1R41I1DsMPblcgz9uvYCf7UtyftbhJ83bnJeEmOYQiwijLG0+QMq+B2+mmZan3Z7Hl7O53dnwuLxz7EO7EhQhY+CqHVgc6s=
diff --git a/.travis/docker.sh b/.travis/docker.sh
index 255601ef0f580d569e9d3ef57d6406b8c3c64d02..66a9189c50c2ecdd671daff24ea74da3dc01fec3 100755
--- a/.travis/docker.sh
+++ b/.travis/docker.sh
@@ -4,15 +4,11 @@ IFS=$'\n\t'
 
 CURL_URL="https://registry.hub.docker.com/u/rocketchat/rocket.chat/trigger/$PUSHTOKEN/"
 
-if ["$TRAVIS_TAG" ]; then
-  CURL_DATA='{"source_type":"Tag","source_name":"'"$TRAVIS_TAG"'","docker_tag":"'"$TRAVIS_TAG"'"}';
+if [[ $TRAVIS_TAG ]]
+ then
+  CURL_DATA='{"source_type":"Tag","source_name":"'"$TRAVIS_TAG"'"}';
 else
-  if [ "$TRAVIS_BRANCH" == "master" ]; then
-    CURL_DATA='{"source_type":"Branch","source_name":"master","docker_tag":"latest"}';
-  else
-    CURL_DATA='{"source_type":"Branch","source_name":"'"$TRAVIS_BRANCH"'","docker_tag":"'"$TRAVIS_BRANCH"'"}';
-  fi
+  CURL_DATA='{"source_type":"Branch","source_name":"develop"}';
 fi
 
 curl -H "Content-Type: application/json" --data "$CURL_DATA" -X POST "$CURL_URL"
-echo -H "Content-Type: application/json" --data "$CURL_DATA" -X POST "CURL_URL"
diff --git a/.travis/namefiles.sh b/.travis/namefiles.sh
index 4848dea2b11da637db450d990744dd1d89ad1db6..6bc9fe1c0aa186d91693b83a8403390278fe4987 100755
--- a/.travis/namefiles.sh
+++ b/.travis/namefiles.sh
@@ -1,7 +1,11 @@
 #!/bin/bash
-set -euo pipefail
+set -euvo pipefail
 IFS=$'\n\t'
 
-#cd $TRAVIS_BUILD_DIR
-#export TAG=$(git describe --abbrev=0 --tags)
-ln -s /tmp/build/Rocket.Chat.tar.gz "/tmp/deploy/rocket.chat-$TRAVIS_BRANCH.tgz"
+# ROCKET_DEPLOY_DIR="/tmp/deploy"
+#TRAVIS_TAG=0.1.0
+
+FILENAME="$ROCKET_DEPLOY_DIR/rocket.chat-$ARTIFACT_NAME.tgz";
+
+ln -s /tmp/build/Rocket.Chat.tar.gz "$FILENAME"
+gpg --armor --detach-sign "$FILENAME"
diff --git a/.travis/sandstorm.sh b/.travis/sandstorm.sh
index 43250534b7ef70100fd331a32320b8a74d68f9fc..ae9b43854b64cc662f9c63b22212992224606686 100755
--- a/.travis/sandstorm.sh
+++ b/.travis/sandstorm.sh
@@ -35,4 +35,4 @@ sed -i "s/\sid = .*/$SANDSTORM_ID/" sandstorm-pkgdef.capnp
 mkdir -p /home/vagrant/bundle/opt/app/.sandstorm/
 cp /opt/app/.sandstorm/launcher.sh /home/vagrant/bundle/opt/app/.sandstorm/
 sed -i "s/\spgp/#pgp/g" sandstorm-pkgdef.capnp
-spk pack /tmp/deploy/rocket.chat-$TRAVIS_BRANCH.spk
+spk pack $ROCKET_DEPLOY_DIR/rocket.chat-$ARTIFACT_NAME.spk
diff --git a/.travis/setartname.sh b/.travis/setartname.sh
new file mode 100755
index 0000000000000000000000000000000000000000..5d5839b6a5e0abb95ad3a18ab0660dc59e6b97d4
--- /dev/null
+++ b/.travis/setartname.sh
@@ -0,0 +1,6 @@
+if [[ $TRAVIS_TAG ]]
+ then
+  export ARTIFACT_NAME="$TRAVIS_TAG";
+else
+  export ARTIFACT_NAME="develop";
+fi
diff --git a/.travis/setdeploydir.sh b/.travis/setdeploydir.sh
new file mode 100755
index 0000000000000000000000000000000000000000..2c49e4a7027ae32d142e6c13f68d95d18b23ff81
--- /dev/null
+++ b/.travis/setdeploydir.sh
@@ -0,0 +1,2 @@
+export ROCKET_DEPLOY_DIR="/tmp/deploy"
+mkdir -p $ROCKET_DEPLOY_DIR
diff --git a/.travis/setupsig.sh b/.travis/setupsig.sh
new file mode 100755
index 0000000000000000000000000000000000000000..72bcd8ade0468e8777dbce86c626d460a06bbbba
--- /dev/null
+++ b/.travis/setupsig.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+set -euo pipefail
+
+cp .travis/sign.key.gpg  /tmp
+gpg --yes --batch --passphrase=$mypass /tmp/sign.key.gpg
+gpg --allow-secret-key-import --import /tmp/sign.key
+rm /tmp/sign.key
diff --git a/.travis/sign.key.gpg b/.travis/sign.key.gpg
new file mode 100644
index 0000000000000000000000000000000000000000..488e275998d505474fd6a93c263b4931885d7d00
Binary files /dev/null and b/.travis/sign.key.gpg differ
diff --git a/.travis/update-releases.sh b/.travis/update-releases.sh
new file mode 100755
index 0000000000000000000000000000000000000000..2bb8f11c564c3d0a398e00d010e988928cd4b436
--- /dev/null
+++ b/.travis/update-releases.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+set -euo pipefail
+IFS=$'\n\t'
+
+CURL_URL="https://rocket.chat/releases/update"
+
+curl -X POST "$CURL_URL"
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index d43c1d2cd2cdd8c25bbe3b801c2886ca459c4ff0..0000000000000000000000000000000000000000
--- a/Dockerfile
+++ /dev/null
@@ -1,37 +0,0 @@
-FROM node:0.10
-
-MAINTAINER buildmaster@rocket.chat
-
-RUN apt-get update \
-&&  apt-get install -y graphicsmagick \
-&&  rm -rf /var/lib/apt/lists/*
-
-RUN groupadd -r rocketchat \
-&&  useradd -r -g rocketchat rocketchat \
-&&  mkdir /app  \
-&&  mkdir /app/uploads
-
-# gpg: key 4FD08014: public key "Rocket.Chat Buildmaster <buildmaster@rocket.chat>" imported
-RUN gpg --keyserver ha.pool.sks-keyservers.net --recv-keys 0E163286C20D07B9787EBE9FD7F9D0414FD08104
-
-WORKDIR /app
-
-RUN curl -fSL "https://s3.amazonaws.com/rocketchatbuild/develop.rocket.chat-v.latest.tgz" -o rocket.chat.tgz \
-&&  tar zxvf ./rocket.chat.tgz \
-&&  rm ./rocket.chat.tgz  \
-&&  cd /app/bundle/programs/server \
-&&  npm install
-
-USER rocketchat
-
-VOLUME /app/uploads
-WORKDIR /app/bundle
-
-# needs a mongoinstance - defaults to container linking with alias 'mongo'
-ENV MONGO_URL=mongodb://mongo:27017/rocketchat \
-    PORT=3000 \
-    ROOT_URL=http://localhost:3000 \
-    Accounts_AvatarStorePath=/app/uploads
-
-EXPOSE 3000
-CMD ["node", "main.js"]
diff --git a/HISTORY.md b/HISTORY.md
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9264452677d5af0f4c515014d755fd3fcc1c3f30 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -0,0 +1,344 @@
+## NEXT
+
+-
+
+## 0.14.0, 2016-Jan-18
+
+- Added admin setting to Force SSL
+- Added connections status bar to login page
+- Added options to enable TLS on LDAP
+- Added package dependecy because of RoomModerators collection
+- Added Raspberry Pi support announcement
+- Added UI to Add/Remove Room Moderators and Owners
+- Adds aria-label to button with icons only
+- Allow multi-line title on oembed
+- Allow SMTP server with no login
+- Display burger icon on History page
+- Display time based on locale instead of using fixed 24h format
+- Do not close Desktop Notifications to keep them in notification center
+- Escape dollar before message token replacement
+- Fallback LDAP login to local account if LDAP fails
+- Fixed audio-recorder not stoping
+- Fixed confusing text labels on video/audio call buttons
+- Fixed overlapping windows
+- Fixed unset moderator test
+- Fixed Warning: Site URL configuration for Sandstorm.io
+- Fixes a bug with search results, where sometimes cog wasn't displayed.
+- Fixes adding/removing owners and moderators
+- Fixes Domain whitelist not restricting
+- Get the correct language when senging messages via email
+- Implement logging out of other logged-in clients
+- Improved code execution on open room computation
+- Improved processWebhookMessage return
+- Improved room moderator subscription and tests
+- Improved the layout and info of the oauth popup
+- Make oembed parse title in ungreedy form
+- Moved collection definition to a better place
+- Moved logic to create a message from webhooks to a new file
+- Moved response logic outside of processWebhookMessage
+- Parse urls with fragments correctly
+- Prevent browsers from trying to validate the input field
+- Prevent erros update outgoing webhooks with empty channel
+- Prevent multiple listeners on message stream per room
+- Process outgoing webhook response as a new message
+- Remove toUpperCase from emojione popup config
+- Send correct content-type for livechat
+- Set/Unset moderator via streams
+- Sort room files by uploadedAt
+- Update oembedVideoWidget removing static height
+- Update strings with localized strings in en
+- Use 'mim-types' ty check content type and compare to extension
+- Using default values instead of integration data
+- Using processWebhookMessage on V1 APIs
+
+## 0.13.0, 2016-Jan-11
+
+- Add api `chat.messageExample`
+- Add apis 'integrations.create' and 'integrations.remove'
+- Add group to tabbar buttons
+- Add helper methods to return data as success, failure, etc
+- Add method to athenticate api via oauth
+- Add more logs on integrations
+- Add oauth2-server and oauth2-server-config
+- Add option to disable oauth apps, default is enabled
+- Add visitor info into tabbar
+- Add visitor status colors
+- Adding livechat package as default
+- Adds a link in the unread bar to jump to first unread message
+- Changed icon for visitor information tabbar
+- Create package rocketchat:api
+- Create routes `channels.setTopic` and `channels.create`
+- Create template to show errors from oauth login
+- Fix LDAP
+- Fix livechat error message position
+- Fix min-height on link oembed.
+- Fix open links for Android
+- Fix problem with middleware that tries to parse json body
+- Fix the wrong language display in the view of accountProfile
+- Gix pinned tabbar button not showing sometimes
+- Highlight messages when jump-to is used Allow selecting user info text
+- Implement an interface to manage oauth apps
+- Implement api chat.postMessage
+- Improved closeFlex logic when switching tabbars
+- Insert the zapier default server
+- Parse bodyParams.payload as json if it exists
+- Permissions rework
+- Remove docker dependency on graphicsmagick
+- Remove restivus package version
+- Removed byte array for debug statements for ufsWrite
+- Save visitor's page navigation history
+- Set current app language to user's language after user login
+- Show the auth and token urls in oauth admin page
+- Shows visitor's navigation history
+- Update log.coffee
+- Use different ids for members info and user info tabbars
+
+## 0.12.1, 2016-Jan-05
+
+- Fix problem with middleware that tries to parse json body
+
+## 0.12.0, 2016-Jan-04
+
+- Add a setting to disable form-based login
+- Add request debug messages
+- Button to test SMTP settings
+- Fix guest users default role
+- Fix livechat trigger by url
+- Hide registration and forgot password links when hidding login form
+- Improved clean button color
+- Increase the delay to render color fields
+- New password reset screen
+- No need to reload server for SMTP settings to take effect
+- Settings: unset section if none is given on update
+- Support named color for message attachments
+- Trim integration messages
+- Try to parse all request bodies as JSON
+- Upload build artifacts to GitHub and sign tgz for docker images
+
+## 0.11.0, 2015-Dec-28
+
+- Add role bot to users of integrations in scope bot
+- Add route to cadastre new integrations via API
+- Add "Jump to" and infinite scroll to message search results
+- Add infinite scroll to files list
+- Add livechat branding
+- Add new color variables to the theme editor
+- Adjust tgz filename in Dockerfile
+- Allow bot call deleteOutgoingIntegration
+- Allow creation of outgoing integrations from bots
+- Allow searching for logged in user in userAutocomplete
+- Always use a department if there is only one active
+- Better message positioning
+- Change /invite to use addUserToRoom instead joinRoom
+- Create direct rooms correctly in incoming hook
+- Only join user in public channels via integrations
+- Fix ungroup of messages after join message
+- Do not load all settings to process.env
+- Enable triggers in messages to users
+- Enable/disable livechat pre registration form pick a department at livechat pre registration
+- Enforce data in body params
+- Execute outgoing triggers
+- Fix error on roomExit callback
+- Fix livechat agent subscription creation
+- Fix livechat triggers not triggering
+- Fix preview of images in mobile
+- Fix triggers with defined channels
+- Fix update of permissions
+- Get integration name from body
+- If no channel in trigger listen all public channels
+- Make sample data into array
+- Move set of integration type to server side
+- Re order settings
+- Remove integration if trigger response is 410
+- Remove unecessary logs
+- Removed livechat duplicated route definition
+- Rename integration api routes, add apis remove, info and sample
+- Set user role in integration update too
+- Tokenize message on message render to prevent re processing
+- Turn channel and triggerWords optional in triggers
+- Using branding image from main APP
+
+## 0.10.2, 2015-Dec-22
+
+- Fixes image preview bugs with filenames containing spaces
+
+## 0.10.1, 2015-Dec-21
+
+- Fix upload permissions introduced in raik:ufs 0.3.4
+
+## 0.10.0, 2015-Dec-21
+
+- Accept property *msg* as text in attachments
+- Add "Room has been deleted" entry
+- Add /kick command and button for kicking users from room
+- Add an not-authorized exception instead of a console.log
+- Add an option to show warning in a setting
+- Add copy to clipboard button on installation
+- Add examples of curl and json in integrations
+- Add field to display the integration token
+- Add hover background color for messages
+- Add msg property as an alternative for text
+- Add option to disable setting based in other setting and another impr…
+- Add setting to turn on/off debug messages from methods and publishes
+- Add some docs about Settings API
+- Adding setting for protected uploads; updating jail:us to 0.3.3
+- Adjust layout direction based on user's language
+- Allow cascade methods in settings creation
+- Allow emoji as avatar for webhooks/integrations
+- Allow OEmbed to bypass file protection
+- Allow pass an array of roles to user in Acctouns.createUser
+- Allow to set messages as ungroupable
+- Appearance settings
+- Attachments: Concerning the mobile settings to save badwidth and fix …
+- Bump version to 0.10.0
+- Centralize message better
+- Centralize messages
+- Change order of loading variables
+- Change the rate limit of method setAvatarFromService from 1m to 5s
+- Changes to layout and add infinite scroll to mentions bar
+- Check if file is empty before upload
+- Closes #1691; Fiz a grouping error in messages from history
+- Code cleanup
+- Configure LGTM approvals
+- Create method in settings to update options of one setting
+- Detect file dimensions in uploads and set height of image in attachments
+- Detect if system is runing GM or IM, add info to RocketChat.Info and …
+- Disable ldap settings when ldap is disabled
+- Explain the available docker images
+- Fix a PT translation
+- Fix avatar position on compact view
+- Fix checking if message is command
+- Fix crash when connection reset from LDAP server
+- Fix deleting a message not deleting it's attachments
+- Fix error "Cannot read property 'replace' of undefined"
+- Fix guest permissions
+- Fix language loading from cordova
+- Fix merge mess =P
+- Fix mute by setting mute on room instead of subscription
+- Fix pin and star
+- Fix some ldap problems and set reconnect to true
+- Fix sort of settings
+- Fix URL
+- Fixed pin and star
+- Fixed several english issues.
+- Get next agent on queue
+- Group message by time, default 5min
+- Improve avatar resize function to use GM detection and allow change s…
+- Improve error when closing window
+- Improved triggers settings
+- Initial trigger support
+- Livechat appearance preview
+- Livechat hooks
+- Livechat manager fix and improvements
+- Livechat sidenav active item
+- Livechat widget preview
+- LoadSurroundingMessages
+- Mentions sidenav;
+- Missing language entries
+- More improvements in message grouping
+- Mover rocketchat.info into rocketchat:lib
+- Mute/Unmute commands and button
+- New icon for unpin
+- New MAINTERRS
+- Pass role to user created via SAML integration
+- Protecting uploaded files
+- Removed all console.logs from publishes and methods
+- Removed ES code
+- Removed kadira package
+- Removed logs
+- Removed unused code
+- Render a player for audio files
+- Return the correct error for unauthorized upload access
+- Revert "Allow OEmbed to bypass file protection"
+- Saving livechat trigger config
+- Set avatar resize enabled by default
+- Setting only one, either emoji or avatar, but never both
+- Show warning and allow admins to fix the Site URL
+- Support calls from client / browsers
+- Ui fix for livechat survey
+- Undo wrongly commited file
+- Unsubscribe e-mails from CSV
+- Update aldeed:simple-schema to 1.5.1
+- Update Ansible link to beginners friendly deployment guide
+- Update jalik:ufs to 0.3.4
+- Updated aldeed:simple-schema to 1.5.0
+- Updated muted usernames on setUsername
+- Use attachments to render preview of uploads and use relative paths
+- Using flow-router group routes
+
+## 0.9.0, 2015-Dec-14
+
+- Fix broken image-link when og:image contains "&amp;" (e.g. Google Maps)
+- Error message when file upload media type it not accepted
+- Add setting Accounts_LoginExpiration
+- Fix 'create new' in private group list opening 'create channel' flex
+- Moved RocketMailer to Mailer
+- Move avatars on username change
+- Livechat Survey
+- Livechat popout support
+- New integrations panel on the admin
+- Many fixes on rtl.less
+- Avatars for Unicode usernames
+- Fix for mentioning RTL names
+- Force file names to always be in LTR
+- Add query operator for mailer
+- Departments support
+- Fixes issue #1619 persistent custom oauth.
+- Add a new setting type "action" to call server methods
+- Add lib clipboard.js
+- Add new page container type, settings
+- Add new role, manage-integrations
+- Add settings/action to allow admins restart the server
+- Allow arrays of keys in RocketChat.settings.onload
+- Allow avatar and alias customization
+- Allow packages to register files for theming
+- Allow use Markdown to render a single stringn and register a helper
+- Change layout of attachments
+- Create a setting/action to test push notifications
+- Create a user rocket.cat and set avatar on system initialization
+- Do not alert admins about wrong url if accessing from cordova
+- Encode url and token
+- Implement package for message attachments
+- Inform user to refresh page after extension install
+- Pass success message to settings/actions
+- Prepare code to reconfigure push plugin in runtime
+- Prevent parse message urls if option parseUrls is false in message
+- Prompt users to install extentions to enable screen sharing
+- Shos if message is from bot and never render compact message version
+- Fixed blockquote non-continous border
+- Moved accountBox HTML to new separated template
+
+## 0.8.0, 2015-Dec-8
+
+- Fixed error: when allow change username was set to false, registration
+- Improve message rendering removing MessageAction from render time
+- Textarea theme fix for RTL
+- Update the flex-nav hidden element for RTL
+- Refresh the count of unread messages on scroll
+- Reset correctly all counters of unread marks
+- Force deletion and stop computations of templates when closing room
+- Close rooms when more than 10 is open instead of closing rooms
+- Reset avatar before uploading to prevent caching
+- Create page to manage assets and change favicons
+- Add option to disable "Forgot Password" link on login page
+- New RocketChat.RateLimiter
+- Favico.js update
+- Better RTL support
+- Remove custom oAuth record when removed from settings
+- Improve Settings layout
+- Collapse sub groups of settings
+- Change translations in PT for False and True
+- Add Secret URL
+- Fix push notification for android
+- Enable push bay default and improve settings organization
+- Alert admin if configured url is different from current
+- Translate section of settings
+- Add "Meiryo UI" to font-family
+- Fix livechat visitor can't chat after refresh
+- Fix can't send msgs to new livechat rooms
+- Clear iOS app badge on app startup
+- Fix for image swipebox to show in RTL interface
+
+## 0.1.0, 2015-May-19
+
+- Initial public launch
diff --git a/MAINTAINERS b/MAINTAINERS
new file mode 100644
index 0000000000000000000000000000000000000000..2f212b17aa1f9586530393a8a1f558dc033650fa
--- /dev/null
+++ b/MAINTAINERS
@@ -0,0 +1,10 @@
+engelgabriel
+geekgonecrazy
+gmsecrieru
+graywolf336
+marceloschmidt
+rcaferati
+rodrigok
+rwakida
+sampaiodiego
+Sing-Li
diff --git a/README.md b/README.md
index 6f5ff72f957de43f5325fa4b2b234a0c12b95efb..731063addc34b7434251d6a4db64bf025ab24c44 100644
--- a/README.md
+++ b/README.md
@@ -7,11 +7,13 @@ The Ultimate Open Source WebChat Platform
 * [Desktop apps](#desktop-apps)
 * [Deployment](#deployment)
   * [Heroku](#heroku)
+  * [Scalingo](#scalingo)
   * [Sandstorm.io](#sandstormio)
   * [Sloppy.io](#sloppyio)
   * [Docker](#docker)
   * [FreeBSD](#freebsd)
   * [Ansible](#ansible)
+  * [Raspberry Pi 2](#raspberry-pi-2)
   * [Ubuntu VPS](#ubuntu-vps)
   * [Ubuntu Software Center](#ubuntu-software-center)
 * [About Rocket.Chat](#about-rocketchat)
@@ -23,7 +25,7 @@ The Ultimate Open Source WebChat Platform
   * [Documentation](#documentation)
   * [License](#license)
 * [Development](#development)
- * [Installation](#installation)
+ * [Quick Start](#quick-start-for-code-developers)
   * [Branching Model](#branching-model)
   * [Translations](#translations)
   * [Community](#community)
@@ -60,18 +62,17 @@ Now compatible with all Android devices as old as version 4.0.x - [download here
 ## Heroku
 Host your own Rocket.Chat server for **FREE** with [One-Click Deploy](https://heroku.com/deploy?template=https://github.com/RocketChat/Rocket.Chat/tree/master)
 
-Branch **master** (Latest stable version):
-
-[![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy?template=https://github.com/RocketChat/Rocket.Chat/tree/master)
+[![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy?template=https://github.com/RocketChat/Rocket.Chat/tree/develop)
 
-Branch **develop** (Newer but unstable):
+## Scalingo
+Deploy your own Rocket.Chat server instantly on [Scalingo](https://scalingo.com)
 
-[![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy?template=https://github.com/RocketChat/Rocket.Chat/tree/develop)
+[![Deploy on Scalingo](https://cdn.scalingo.com/deploy/button.svg)](https://my.scalingo.com/deploy?source=https://github.com/RocketChat/Rocket.Chat#develop)
 
 ## Sandstorm.io
 [![Rocket.Chat on Sandstorm.io](https://raw.githubusercontent.com/Sing-Li/bbug/master/images/sandstorm.jpg)](https://apps.sandstorm.io/app/vfnwptfn02ty21w715snyyczw0nqxkv3jvawcah10c6z7hj1hnu0)
 
-_*Grab*_ the latest [Sandstorm SPK](https://s3.amazonaws.com/rocketchatbuild/rocket.chat-develop.spk) for testing on your own server.
+_*Grab*_ the [Sandstorm SPK for the latest Rocket.Chat release](https://rocket.chat/releases/latest/spk) for testing on your own server.
 
 ## Sloppy.io
 Host your docker container at [sloppy.io](http://sloppy.io). Get an account and use the [quickstarter](https://github.com/sloppyio/quickstarters/tree/master/rocketchat)
@@ -81,12 +82,23 @@ Host your docker container at [sloppy.io](http://sloppy.io). Get an account and
 
 or
 
-Use the automated build at our [Official Docker Registry](https://hub.docker.com/r/rocketchat/rocket.chat/)
+Use the automated build image of our [most recent release](https://hub.docker.com/r/rocketchat/rocket.chat/)
 
 [![Rocket.Chat logo](https://d207aa93qlcgug.cloudfront.net/1.95.5.qa/img/nav/docker-logo-loggedout.png)](https://hub.docker.com/r/rocketchat/rocket.chat/)
 
 ```
-docker pull rocketchat/rocket.chat
+docker pull rocketchat/rocket.chat:latest
+```
+
+OR select a specific release ([details of releases available](https://github.com/RocketChat/Rocket.Chat/releases)):
+```
+docker pull rocketchat/rocket.chat:vX.X.X
+```
+
+OR our [official docker registry image](https://hub.docker.com/_/rocket.chat/), containing recent stable release build approved by Docker:
+
+```
+docker pull rocket.chat
 ```
 
 ## FreeBSD
@@ -97,7 +109,12 @@ Run solid five-nines deployment on industry workhorse FreeBSD server:
 ## Ansible
 Automated production-grade deployment in minutes, for RHEL / CentOS 7 or Ubuntu 14.04 LTS / 15.04:
 
-[![Ansible deployment](https://raw.githubusercontent.com/Sing-Li/bbug/master/images/ansible.png)](https://galaxy.ansible.com/detail#/role/6478)
+[![Ansible deployment](https://raw.githubusercontent.com/Sing-Li/bbug/master/images/ansible.png)](https://github.com/RocketChat/Rocket.Chat/wiki/Easy,-hands-off-deployment-with-Ansible)
+
+## Raspberry Pi 2
+Run Rocket.Chat on this world famous $30 quad core server:
+
+[![Raspberry Pi 2](https://raw.githubusercontent.com/Sing-Li/bbug/master/images/pitiny.png)](https://github.com/RocketChat/Rocket.Chat.RaspberryPi)
 
 ## Ubuntu VPS
 Follow these [deployment instructions](https://github.com/RocketChat/Rocket.Chat/wiki/Deploy-Rocket.Chat-without-docker)
@@ -241,7 +258,7 @@ Note that Rocket.Chat is distributed under the [MIT License](http://opensource.o
 
 # Development
 
-## Installation
+## Quick start for code developers
 Prerequisites:
 
 * [Git](http://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
@@ -255,13 +272,7 @@ cd Rocket.Chat
 meteor
 ```
 
-or use docker:
-
-```
-git clone https://github.com/RocketChat/Rocket.Chat.git
-cd Rocket.Chat
-docker run -it -p 3000:3000 -v "$(pwd)":/app danieldent/meteor
-```
+If you are not a developer and just want to run the server - see [deployment methods](https://github.com/RocketChat/Rocket.Chat/wiki#deployment).
 
 ## Branching Model
 
diff --git a/client/helpers/log.coffee b/client/helpers/log.coffee
index f00b503c8d363db42c15cc969e5c9efe4eca41ed..bc6666749306cd453967c769bdcc405499b14105 100644
--- a/client/helpers/log.coffee
+++ b/client/helpers/log.coffee
@@ -1,2 +1,2 @@
-Blaze.registerHelper 'log', ->
-	console.log.apply console, arguments
\ No newline at end of file
+Template.registerHelper 'log', ->
+	console.log.apply console, arguments
diff --git a/client/methods/pinMessage.coffee b/client/methods/pinMessage.coffee
deleted file mode 100644
index a46e6bdde718526144240141037d1b4c65306330..0000000000000000000000000000000000000000
--- a/client/methods/pinMessage.coffee
+++ /dev/null
@@ -1,21 +0,0 @@
-Meteor.methods
-	pinMessage: (message) ->
-		if not Meteor.userId()
-			throw new Meteor.Error 203, t('User_logged_out')
-
-		if not RocketChat.settings.get 'Message_AllowPinning'
-			throw new Meteor.Error 'message-pinning-not-allowed', t('Message_pinning_not_allowed')
-
-		Tracker.nonreactive ->
-
-			message.pts = new Date(Date.now() + TimeSync.serverOffset())
-			message.pinned = true
-			message = RocketChat.callbacks.run 'beforeSaveMessage', message
-
-			ChatMessage.update
-				_id: message.id
-				'u._id': Meteor.userId()
-			,
-				$set:
-					pinned: message.pinned
-					pts: message.pts
diff --git a/client/methods/saveRoomName.coffee b/client/methods/saveRoomName.coffee
deleted file mode 100644
index 0885fe433cebcb704f96b0316ba538333f559dc3..0000000000000000000000000000000000000000
--- a/client/methods/saveRoomName.coffee
+++ /dev/null
@@ -1,27 +0,0 @@
-Meteor.methods
-	saveRoomName: (rid, name) ->
-		if not Meteor.userId()
-			throw new Meteor.Error 203, t('User_logged_out')
-
-		room = ChatRoom.findOne rid
-
-		if room.u._id isnt Meteor.userId() or room.t not in ['c', 'p']
-			throw new Meteor.Error 403, t('Not allowed')
-
-		if RocketChat.settings.get 'UTF8_Names_Slugify'
-			name = _.slugify name
-
-		if name is room.name
-			return
-
-		ChatRoom.update rid,
-			$set:
-				name: name
-
-		ChatSubscription.update
-			rid: rid
-		,
-			$set:
-				name: name
-
-		return name
diff --git a/client/methods/unpinMessage.coffee b/client/methods/unpinMessage.coffee
deleted file mode 100644
index a60e28960e3b6f36793a57b9fe1213295c469888..0000000000000000000000000000000000000000
--- a/client/methods/unpinMessage.coffee
+++ /dev/null
@@ -1,21 +0,0 @@
-Meteor.methods
-	unpinMessage: (message) ->
-		if not Meteor.userId()
-			throw new Meteor.Error 203, t('User_logged_out')
-
-		if not RocketChat.settings.get 'Message_AllowPinning'
-			throw new Meteor.Error 'message-pinning-not-allowed', t('Message_pinning_not_allowed')
-
-		Tracker.nonreactive ->
-
-			message.pts = new Date(Date.now() + TimeSync.serverOffset())
-			message.pinned = false
-			message = RocketChat.callbacks.run 'beforeSaveMessage', message
-
-			ChatMessage.update
-				_id: message.id
-				'u._id': Meteor.userId()
-			,
-				$set:
-					pinned: message.pinned
-					pts: message.pts
diff --git a/client/routes/adminRouter.coffee b/client/routes/adminRouter.coffee
index ee8a4ed0e1e21f8a21bded8deff5534ded57d675..c226715e635bbfa28d5ed925973e749f31a506b1 100644
--- a/client/routes/adminRouter.coffee
+++ b/client/routes/adminRouter.coffee
@@ -1,33 +1,27 @@
-tabReset = ->
-	RocketChat.TabBar.reset()
-
 FlowRouter.route '/admin/users',
 	name: 'admin-users'
-	triggersEnter: [tabReset]
-	triggersExit: [tabReset]
+	triggersExit: [ ->
+		Session.set 'adminSelectedUser'
+	]
 	action: ->
+		Session.set 'adminSelectedUser'
+		RocketChat.TabBar.showGroup 'adminusers'
 		BlazeLayout.render 'main', {center: 'adminUsers'}
 
-
 FlowRouter.route '/admin/rooms',
 	name: 'admin-rooms'
-	triggersEnter: [tabReset]
-	triggersExit: [tabReset]
 	action: ->
+		RocketChat.TabBar.showGroup 'adminrooms'
 		BlazeLayout.render 'main', {center: 'adminRooms'}
 
-
 FlowRouter.route '/admin/statistics',
 	name: 'admin-statistics'
-	triggersEnter: [tabReset]
-	triggersExit: [tabReset]
 	action: ->
+		RocketChat.TabBar.showGroup 'adminstatistics'
 		BlazeLayout.render 'main', {center: 'adminStatistics'}
 
-
 FlowRouter.route '/admin/:group?',
 	name: 'admin'
-	triggersEnter: [tabReset]
-	triggersExit: [tabReset]
 	action: ->
+		RocketChat.TabBar.showGroup 'admin'
 		BlazeLayout.render 'main', {center: 'admin'}
diff --git a/client/routes/router.coffee b/client/routes/router.coffee
index 74873c70a05da43cee2975de3037d0c17c6c917c..9757366bfa568cead9c054fbb511b8dae0a073c1 100644
--- a/client/routes/router.coffee
+++ b/client/routes/router.coffee
@@ -3,7 +3,6 @@ Blaze.registerHelper 'pathFor', (path, kw) ->
 
 BlazeLayout.setRoot 'body'
 
-
 FlowRouter.subscriptions = ->
 	Tracker.autorun =>
 		RoomManager.init()
@@ -42,7 +41,7 @@ FlowRouter.route '/home',
 	name: 'home'
 
 	action: ->
-		RocketChat.TabBar.reset()
+		RocketChat.TabBar.showGroup 'home'
 		BlazeLayout.render 'main', {center: 'home'}
 		KonchatNotification.getDesktopPermission()
 
@@ -51,18 +50,17 @@ FlowRouter.route '/changeavatar',
 	name: 'changeAvatar'
 
 	action: ->
+		RocketChat.TabBar.showGroup 'changeavatar'
 		BlazeLayout.render 'main', {center: 'avatarPrompt'}
 
 FlowRouter.route '/account/:group?',
 	name: 'account'
 
 	action: (params) ->
-		RocketChat.TabBar.closeFlex()
-		RocketChat.TabBar.resetButtons()
-
 		unless params.group
 			params.group = 'Preferences'
 		params.group = _.capitalize params.group, true
+		RocketChat.TabBar.showGroup 'account'
 		BlazeLayout.render 'main', { center: "account#{params.group}" }
 
 
@@ -74,6 +72,7 @@ FlowRouter.route '/history/private',
 
 	action: ->
 		Session.setDefault('historyFilter', '')
+		RocketChat.TabBar.showGroup 'private-history'
 		BlazeLayout.render 'main', {center: 'privateHistory'}
 
 
diff --git a/client/startup/defaultRoomTypes.coffee b/client/startup/defaultRoomTypes.coffee
index 832cbd2f21cef3b3e95290b6ebd417426f404411..ee2f83261e49ac3d6bcdb1b6298f895b739b8ebb 100644
--- a/client/startup/defaultRoomTypes.coffee
+++ b/client/startup/defaultRoomTypes.coffee
@@ -11,9 +11,11 @@ RocketChat.roomTypes.add 'c', 10,
 		action: (params, queryParams) ->
 			Session.set 'showUserInfo'
 			openRoom 'c', params.name
+			RocketChat.TabBar.showGroup 'channel'
 		link: (sub) ->
 			return { name: sub.name }
-	permissions: [ 'view-c-room' ]
+	condition: ->
+		return RocketChat.authz.hasAllPermission 'view-c-room'
 
 RocketChat.roomTypes.add 'd', 20,
 	template: 'directMessages'
@@ -24,9 +26,11 @@ RocketChat.roomTypes.add 'd', 20,
 		action: (params, queryParams) ->
 			Session.set 'showUserInfo', params.username
 			openRoom 'd', params.username
+			RocketChat.TabBar.showGroup 'directmessage'
 		link: (sub) ->
 			return { username: sub.name }
-	permissions: [ 'view-d-room' ]
+	condition: ->
+		return RocketChat.authz.hasAllPermission 'view-d-room'
 
 RocketChat.roomTypes.add 'p', 30,
 	template: 'privateGroups'
@@ -37,6 +41,8 @@ RocketChat.roomTypes.add 'p', 30,
 		action: (params, queryParams) ->
 			Session.set 'showUserInfo'
 			openRoom 'p', params.name
+			RocketChat.TabBar.showGroup 'privategroup'
 		link: (sub) ->
 			return { name: sub.name }
-	permissions: [ 'view-p-room' ]
+	condition: ->
+		return RocketChat.authz.hasAllPermission 'view-p-room'
diff --git a/client/startup/startup.coffee b/client/startup/startup.coffee
index c42fb6200e01edf4347b8e774e9a7eacf2932447..ed209ee71b3bc758fac84fb479c923fe394c2a1e 100644
--- a/client/startup/startup.coffee
+++ b/client/startup/startup.coffee
@@ -10,7 +10,7 @@ Meteor.startup ->
 	window.lastMessageWindow = {}
 	window.lastMessageWindowHistory = {}
 
-	@defaultUserLanguage = ->
+	@defaultAppLanguage = ->
 		lng = window.navigator.userLanguage || window.navigator.language || 'en'
 		# Fix browsers having all-lowercase language settings eg. pt-br, en-us
 		re = /([a-z]{2}-)([a-z]{2})/
@@ -18,14 +18,25 @@ Meteor.startup ->
 			lng = lng.replace re, (match, parts...) -> return parts[0] + parts[1].toUpperCase()
 		return lng
 
+	@defaultUserLanguage = ->
+		return RocketChat.settings.get('Language') || defaultAppLanguage()
+
 	loadedLaguages = []
 
-	setLanguage = (language) ->
+	@setLanguage = (language) ->
+		if !language
+			return
+
 		if loadedLaguages.indexOf(language) > -1
 			return
 
 		loadedLaguages.push language
 
+		if isRtl language
+			$('html').addClass "rtl"
+		else
+			$('html').removeClass "rtl"
+
 		language = language.split('-').shift()
 		TAPi18n.setLanguage(language)
 
@@ -35,14 +46,12 @@ Meteor.startup ->
 				Function(localeFn)()
 				moment.locale(language)
 
-	Tracker.autorun (c) ->
-		if Meteor.user()?.language?
-			c.stop()
-
-			localStorage.setItem("userLanguage", Meteor.user().language)
-			setLanguage Meteor.user().language
+	Meteor.subscribe("userData", () ->
+		userLanguage = Meteor.user()?.language
+		userLanguage ?= defaultUserLanguage()
 
-	userLanguage = localStorage.getItem("userLanguage")
-	userLanguage ?= defaultUserLanguage()
+		if localStorage.getItem('userLanguage') isnt userLanguage
+			localStorage.setItem('userLanguage', userLanguage)
 
-	setLanguage userLanguage
+		setLanguage userLanguage
+	)
diff --git a/docker-compose.yml b/docker-compose.yml
index 7fc1a9f81e0551979bb7691724b523b74f1a9049..2637c3c86a24cae08c2ba61cee9b63c0a86d2d5b 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -6,15 +6,13 @@ mongo:
   command: mongod --smallfiles --oplogSize 128
 
 rocketchat:
-  image: rocketchat/rocket.chat:develop
+  image: rocketchat/rocket.chat:latest
 # volumes:
 #    - ./uploads:/app/uploads
   environment:
     - PORT=3000
     - ROOT_URL=http://yourhost:3000
     - MONGO_URL=mongodb://mongo:27017/rocketchat
-# uncomment and set the line below if you need to support mobile apps
-#   - DDP_DEFAULT_CONNECTION_URL=http://yourhost:3000
   links:
     - mongo:mongo
   ports:
@@ -24,7 +22,7 @@ rocketchat:
 hubot:
   image: rocketchat/hubot-rocketchat
   environment:
-    - ROCKETCHAT_URL=yourhost:3000
+    - ROCKETCHAT_URL=rocketchat:3000
     - ROCKETCHAT_ROOM=GENERAL
     - ROCKETCHAT_USER=bot
     - ROCKETCHAT_PASSWORD=botpassword
@@ -35,4 +33,4 @@ hubot:
     - rocketchat:rocketchat
 # this is used to expose the hubot port for notifications on the host on port 3001, e.g. for hubot-jenkins-notifier
   ports:
-    - 3001:8080
\ No newline at end of file
+    - 3001:8080
diff --git a/build.sh b/example-build.sh
similarity index 85%
rename from build.sh
rename to example-build.sh
index f60192ddad78c55bf611f69661a02061976dde35..579353a01a320a213e1ab3fa5babf412cd6e1081 100755
--- a/build.sh
+++ b/example-build.sh
@@ -1,6 +1,6 @@
 #!/bin/bash
 export METEOR_SETTINGS=$(cat settings.json)
-meteor add rocketchat:livechat rocketchat:hubot
+meteor add rocketchat:hubot meteorhacks:kadira
 meteor build --server https://demo.rocket.chat --directory /var/www/rocket.chat
 cd /var/www/rocket.chat/bundle/programs/server
 npm install
diff --git a/i18n/ar.i18n.json b/i18n/ar.i18n.json
index d2e04cbfc219366a5fe3caa7fe7568922e058a74..bc196b60c391b347e6f08a25cdd6dd186d32244f 100644
--- a/i18n/ar.i18n.json
+++ b/i18n/ar.i18n.json
@@ -3,16 +3,36 @@
   "Access_Online_Demo" : "الدخول إلى العرض التجريبي",
   "Accounts" : "الحسابات",
   "Accounts_AllowPasswordChange" : "السماح بتغيير كلمة السر",
+  "Accounts_AllowUsernameChange" : "السماح بتغيير اسم المستخدم",
   "Accounts_AllowUserProfileChange" : "السماح بتعديل الملف الشخصي للعضو",
+  "Accounts_AvatarResize" : "تغيير حجم الصور الرمزية",
+  "Accounts_AvatarSize" : "حجم الصورة الرمزية",
+  "Accounts_AvatarStorePath" : "مسار تخزين الصورة الرمزية",
+  "Accounts_AvatarStoreType" : "نوع تخزين الصورة الرمزية",
+  "Accounts_EmailVerification" : "التحقق من البريد الإلكتروني",
+  "Accounts_ManuallyApproveNewUsers" : "الموافقة على المستخدمين الجدد يدويا",
+  "Accounts_OAuth_Custom_Enable" : "تمكين",
+  "Accounts_OAuth_Custom_URL" : "الرابط",
   "Accounts_PasswordReset" : "إعادة تعيين كلمة السر",
+  "Accounts_RegistrationForm" : "استمارة التسجيل",
+  "Accounts_RegistrationForm_Disabled" : "معطل",
+  "Accounts_RegistrationForm_Public" : "عام",
+  "Accounts_RegistrationForm_Secret_URL" : "رابط سري",
+  "Accounts_RegistrationForm_SecretURL" : "رابط استمارة التسجيل السري",
+  "Accounts_RegistrationRequired" : "التسجيل مطلوب",
+  "Activate" : "تفعيل",
   "Add_Members" : "إضافة الأعضاء",
   "Add_users" : "إضافة مستخدمين",
   "Administration" : "الإدارة",
   "All_channels" : "جميع القنوات",
   "and" : "Ùˆ",
+  "API_Analytics" : "التحليلات",
+  "Archive" : "الأرشيف",
   "are_also_typing" : "هم أيضا يكتبون",
   "are_typing" : "يكتبون",
   "Are_you_sure" : "هل أنت متأكد؟",
+  "Auto_Load_Images" : "تحميل تلقائي للصور",
+  "Avatar_changed_successfully" : "تم تغيير الصورة الرمزية بنجاح",
   "away" : "بعيد",
   "Away" : "بعيد",
   "away_female" : "بعيدة",
@@ -32,34 +52,60 @@
   "Channels" : "القنوات",
   "Channels_list" : "قائمة القنوات العامة",
   "Chat_Rooms" : "غرف المحادثة",
-  "close" : "أغلق",
+  "Clear_all_unreads_question" : "مسح كافة الغير مقروءة؟",
+  "close" : "غلق",
   "coming_soon" : "قريبا",
+  "Commands" : "الأوامر",
+  "Compact_View" : "عرض متراص",
   "Confirm_password" : "تأكيد كلمة السر",
   "Conversation" : "محادثة",
+  "Convert_Ascii_Emojis" : "حول محارف الأسكي إلى اموجي",
+  "COPY_TO_CLIPBOARD" : "نسخ",
   "Create_new" : "إنشاء جديد",
+  "Create_new_direct_message_room" : "إنشاء غرفة رسالة مباشرة جديدة",
   "Create_new_private_group" : "إنشاء مجموعة خاصة جديدة",
   "Create_new_public_channel" : "إنشاء قناة عامة جديدة",
   "Created_at" : "أنشئت في",
+  "days" : "أيام",
+  "Deactivate" : "تعطيل",
+  "Delete_Room_Warning" : "حذف الغرفة، يحذف جميع الرسائل المرسلة داخل الغرفة.، هذا لا يمكن التراجع عنه.",
+  "Deleted" : "تم الحذف!",
   "Desktop_Notifications" : "تنبيهات سطح المكتب",
   "Desktop_Notifications_Disabled" : "تنبيهات سطح المكتب معطلة. قم بتغيير إعدادات المتصفح إذا أردت تفعيلها.",
   "Desktop_Notifications_Enabled" : "تنبيهات سطح المكتب مفعلة",
   "Direct_Messages" : "الرسائل المباشرة",
   "Disable_Favorite_Rooms" : "تعطيل المفضلة",
   "Disable_New_Message_Notification" : "تعطيل التنبيه عن رسالة جديدة",
-  "Disable_New_Room_Notification" : "تعطيل التنبيه عن غرفة جديدة",
-  "edited" : "عدلت",
+  "Disable_New_Room_Notification" : "تعطيل التنبيهات الجديدة في الغرفة",
+  "Drop_to_upload_file" : "إسقاط لتحميل الملف",
+  "E-mail" : "البريد اﻹلكتروني",
+  "edited" : "تم العديل",
+  "Email_already_exists" : "البريد الالكتروني موجود مسبقا",
   "Email_or_username" : "البريد الإلكتروني أو اسم المستخدم",
   "Email_verified" : "تم التحقق من البريد الإلكتروني",
+  "Emoji" : "رمز تعبيري (اموجي)",
   "Enable_Desktop_Notifications" : "تفعيل تنبيهات سطح المكتب",
   "Enter_info" : "ادخل المعلومات الخاصة بك",
+  "Enter_to" : "ادخل الى",
+  "Error" : "خطأ",
   "Error_changing_password" : "خطأ في تغيير كلمة السر",
-  "False" : "لا",
+  "Error_too_many_requests" : "خطأ، الكثير من الطلبات. من فضلك أبطء السرعة. عليك الانتظار٪ s ثانية قبل المحاولة مرة أخرى",
+  "False" : "خاطئة",
   "Favorites" : "المفضلة",
+  "FileUpload" : "تحميل الملف",
+  "FileUpload_Enabled" : "تحميل الملفات مفعلة",
+  "FileUpload_MaxFileSize" : "الحد الأقصى لتحميل الملف الحجم (بايت)",
+  "FileUpload_MediaTypeWhiteList" : "أنواع الوسائط المقبولة",
+  "FileUpload_ProtectFiles" : "حماية الملفات المحملة",
   "Forgot_password" : "نسيت كلمة السر",
+  "From_Email" : "من البريد الإلكتروني",
+  "General" : "العامة",
   "Get_to_know_the_team" : "تعرف على Rocket.Team",
   "github_no_public_email" : "ليس لديك أي بريد الإلكتروني عام في حسابك على Github",
+  "Has_more" : "يوجد المزيد",
   "Hide_room" : "إخفاء الغرفة",
   "History" : "تاريخ",
+  "hours" : "ساعة",
   "Incorrect_Password" : "كلمة السر غير صحيحة",
   "inline_code" : "نص_برمجي",
   "Invalid_confirm_pass" : "تأكيد كلمة السر لا تطابق كلمة السر",
@@ -68,34 +114,73 @@
   "Invalid_pass" : "لا يجب أن تكون كلمة السر فارغة",
   "invisible" : "خفي",
   "Invisible" : "خفي",
+  "Invitation_Subject" : "موضوع الدعوة",
   "Invite_Users" : "دعوة المستخدمين",
   "is_also_typing" : "هو أيضا يكتب",
+  "is_also_typing_female" : "هي أيضا تكتب",
+  "is_also_typing_male" : "هو أيضا يكتب",
   "is_typing" : "يكتب",
+  "is_typing_female" : "تكتب",
+  "is_typing_male" : "يكتب",
   "italics" : "مائل",
   "join" : "انضم",
   "Join_the_Community" : "إنظم للمجتمع",
-  "Language" : "لغة",
+  "Jump_to_message" : "القفز إلى الرسالة",
+  "Jump_to_recent_messages" : "اذهب إلى الرسائل الأخيرة",
+  "Language" : "اللغة",
   "Language_Version" : "النسخة الإنجليزية",
+  "Last_login" : "آخر تسجيل دخول",
   "Last_message" : "آخر رسالة",
+  "Layout" : "التصميم",
+  "Layout_Home_Title" : "عنوان الصفحة الرئيسية",
+  "Layout_Login_Terms" : "شروط الدخول",
+  "Layout_Privacy_Policy" : "سياسة الخصوصية",
+  "Layout_Terms_of_Service" : "شروط الخدمة",
   "Leave_room" : "مغادرة الغرفة",
   "line" : "خط",
   "Load_more" : "اعرض أكثر",
+  "Loading..." : "تحميل ...",
+  "Loading_more_from_history" : "تحميل المزيد من التاريخ",
   "Loading_suggestion" : "تحميل الاقتراحات ...",
   "Login" : "تسجيل الدخول",
   "Login_with" : "تسجيل الدخول بـ %s",
-  "login_with" : "أو الدخول مباشرة مع",
+  "login_with" : "أو الدخول مباشرة بـ",
   "Logout" : "تسجيل خروج",
+  "Logout_Others" : "تسجيل الخروج من الأجهزة الأخرى",
+  "Make_Admin" : "جعل مدير",
+  "Mark_as_read" : "تعليم كمقروء",
   "Members" : "الأعضاء",
   "Members_List" : "قائمة الأعضاء",
   "Members_placeholder" : "الأعضاء",
-  "Message_removed" : "مسحت الرسالة",
-  "Messages" : "رسائل",
+  "Message" : "رسالة",
+  "Message_AllowDeleting" : "السماح بحذف الرسائل",
+  "Message_AllowEditing" : "السماح بتعديل الرسائل",
+  "Message_AllowEditing_BlockEditInMinutesDescription" : "أدخل 0 لتعطيل الحظر.",
+  "Message_deleting_not_allowed" : "حذف الرسائل غير مسموح",
+  "Message_editing_blocked" : "لا يمكن تعديل هذه الرسالة بعد الآن",
+  "Message_editing_not_allowed" : "تعديل الرسائل غير مسموح",
+  "Message_KeepHistory" : "إبقاء محفوظات الرسائل",
+  "Message_pinned" : "تم تثبيث الرسالة",
+  "Message_pinning_not_allowed" : "تثبيث الرسائل غير مسموح",
+  "Message_removed" : "تم حذف الرسالة",
+  "Message_ShowDeletedStatus" : "عرض حالة التعديل",
+  "Message_ShowEditedStatus" : "عرض حالة الحذف",
+  "Message_ShowFormattingTips" : "اظهار نصائح التنسيق",
+  "Messages" : "الرسائل",
+  "Meta_fb_app_id" : "معرف تطبيق الفيسبوك",
+  "Meta_language" : "اللغة",
+  "Meta_robots" : "الروبوتات",
+  "minutes" : "دقيقة",
   "More_channels" : "المزيد من القنوات",
+  "More_groups" : "المزيد من المجموعات الخاصة",
+  "More_unreads" : "المزيد غير مقروءة",
   "Msgs" : "رسائل",
   "multi" : "متعدد",
+  "Mute_user" : "اسكات المستخدم",
   "My_Account" : "حسابي",
   "n_messages" : "%s رسائل",
-  "Name" : "اسم",
+  "Name" : "الإسم",
+  "Name_cant_be_empty" : "اﻹسم لا يمكن أن يكون فارغا",
   "New_messages" : "رسائل جديدة",
   "New_password" : "كلمة سر جديدة",
   "No_channels_yet" : "لست جزء من أي قناة حتى الآن.",
@@ -103,58 +188,123 @@
   "No_favorites_yet" : "لم تقم بإضافة مفضلات بعد.",
   "No_groups_yet" : "لا يوجد لديك مجموعات خاصة حتى الآن.",
   "No_permission_to_view_room" : "ليس لديك صلاحية لرؤية هذه الغرفة",
+  "No_results_found" : "لا توجد نتائج",
   "Not_allowed" : "غير مسموح",
+  "Not_authorized" : "غير مصرح",
   "Not_found_or_not_allowed" : "غير موجود أو غير مسموح",
   "Nothing_found" : "لا يوجد شيء",
+  "Notify_all_in_this_room" : "إخطار جميع من في هذه الغرفة",
   "Old_and_new_password_required" : "تحتاج إلى كتابة كلمة السر القديمة والجديدة لتغيير كلمة السر الخاصة بك.",
   "Old_Password" : "كلمة السر القديمة",
   "Online" : "متواجد",
-  "Oops!" : "عفوا",
+  "Only_you_can_see_this_message" : "يمكنك أنت فقط رؤية هذه الرسالة",
+  "Oops!" : "عذرا",
+  "Opt_out_statistics" : "لا ترسل إحصاءات الموقع لRocket.Chat",
+  "optional" : "اختياري",
+  "others" : "آخرون",
   "Password" : "كلمة السر",
+  "Password_Change_Disabled" : "مدير الموقع منع تغيير كلمة السر",
   "Password_changed_successfully" : "تم تغيير كلمة السر بنجاح",
+  "People" : "الناس",
+  "Please_enter_your_new_password_below" : "الرجاء إدخال كلمة المرور الجديدة أدناه:",
   "Please_wait" : "يرجى الانتظار",
+  "Please_wait_activation" : "يرجى الانتظار، قد يستغرق بعض الوقت.",
   "Please_wait_statistics" : "يرجى الانتظار إلى أن يتم حساب الإحصائيات",
-  "Preferences" : "الإعدادات",
-  "Preferences_saved" : "تم حفظ الإعدادات",
-  "Privacy" : "خصوصية",
+  "Preferences" : "التفضيلات",
+  "Preferences_saved" : "تم حفظ التفضيلات",
+  "Privacy" : "الخصوصية",
   "Private_Groups" : "مجموعات خاصة",
+  "Private_Groups_list" : "قائمة المجموعات الخاصة",
   "Profile" : "الملف الشخصي",
   "Profile_saved_successfully" : "تم حفظ الملف الشخصي بنجاح",
+  "Push_enable" : "تمكين",
+  "Push_test_push" : "تجربة",
   "Quick_Search" : "بحث سريع",
   "quote" : "اقتباس",
+  "Record" : "سجل",
   "Register" : "تسجيل حساب جديد",
+  "Registration_Succeeded" : "تم التسجيل بنجاح",
   "Remember_me" : "تذكرني",
   "Remove" : "إزالة",
   "Remove_Admin" : "إزالة مدير",
+  "Remove_from_room" : "إزالة من الغرفة",
+  "Removed" : "تمت اﻹزالة",
+  "Reset" : "إعادة التعيين",
   "Reset_password" : "إعادة تعيين كلمة السر",
+  "Restart" : "إعادة التشغيل",
+  "Restart_the_server" : "إعادة تشغيل السيرفر",
   "Room" : "غرفة",
+  "Room_has_been_deleted" : "تم حذف الغرفة",
   "Room_name_changed" : "تم تغيير اسم الغرفة إلى: <em>__room_name__</em> بواسطة <em>__user_by__</em>",
   "Room_name_changed_successfully" : "تم تغيير اسم الغرفة بنجاح",
+  "Room_not_found" : "لم يتم العثور على الغرفة",
+  "Room_uploaded_file_list" : "قائمة الملفات",
+  "Room_uploaded_file_list_empty" : "لا يوجد ملفات.",
+  "room_user_count" : "% مستخدم",
   "Rooms" : "الغرف",
+  "S_new_messages_since_s" : "% رسالة جديدة منذ %",
+  "Save_changes" : "حفظ التغيرات",
+  "Save_Mobile_Bandwidth" : "توفير استهلاك الانترنت",
   "Search" : "بحث",
   "Search_Messages" : "بحث الرسائل",
+  "Search_settings" : "إعدادات البحث",
+  "seconds" : "ثواني",
+  "See_all" : "عرض الكل",
+  "See_only_online" : "المتصلون فقط",
   "Select_an_avatar" : "اختر صورة",
   "Select_file" : "اختر ملفا",
   "Select_service_to_login" : "اختر خدمة للدخول إليها لتحميل صورتك أو قم بالتحميل مباشرة من جهازك",
   "Selected_users" : "أعضاء مختارين",
+  "Send" : "إرسال",
   "Send_confirmation_email" : "إرسال رسالة تأكيد",
   "Send_Message" : "أرسل رسالة",
-  "Settings" : "إعدادات",
+  "Settings" : "اﻹعدادات",
+  "Settings_updated" : "تم تحديث الإعدادات",
+  "Showing_online_users" : "عرض <b>__total_online__</b>من __total__ عضو",
   "Showing_results" : "<p>يعرض <b>%s</b> نتائج</p>",
   "Silence" : "الصمت",
   "since_creation" : "منذ %s",
-  "Sound" : "صوت",
+  "Site_Name" : "اسم الموقع",
+  "Site_Url" : "رابط الموقع",
+  "Site_Url_Description" : "مثال: https://chat.domain.com/",
+  "Sound" : "الصوت",
   "Start_of_conversation" : "بداية المحادثة",
-  "Statistics" : "إحصائيات",
+  "Statistics" : "الإحصائيات",
+  "Stats_Active_Users" : "الأعضاء النشيطين",
+  "Stats_Avg_Channel_Users" : "متوسط مستخدمي القناة",
+  "Stats_Avg_Private_Group_Users" : "متوسط مستخدمي المجموعات الخاصة",
   "Stats_Away_Users" : "المستخدمين البعيدين",
   "Stats_Max_Room_Users" : "أقصى عدد للمستخدمين في الغرف",
+  "Stats_Non_Active_Users" : "المستخدمين الغير نشطين",
+  "Stats_Offline_Users" : "المستخدمون الغير متصلون",
+  "Stats_Online_Users" : "المستخدمون المتصلون",
+  "Stats_OS_Arch" : "بنية النظام",
+  "Stats_OS_Cpus" : "عدد أنوية النظام",
+  "Stats_OS_Freemem" : "الذاكرة الحرة",
+  "Stats_OS_Loadavg" : "متوسط التحميل",
+  "Stats_OS_Platform" : "منصة النظام",
+  "Stats_OS_Release" : "إصدار النظام",
+  "Stats_OS_Type" : "نوع النظام",
+  "Stats_Total_Channels" : "مجموع القنوات",
   "Stats_Total_Direct_Messages" : "إجمالي عدد غرف الرسالة المباشرة",
   "Stats_Total_Messages" : "مجموع الرسائل",
-  "Stats_Total_Rooms" : "إجمالي عدد الغرف",
+  "Stats_Total_Private_Groups" : "عدد المجموعات الخاصة",
+  "Stats_Total_Rooms" : "عدد الغرف",
+  "Stats_Total_Users" : "عدد الأعضاء",
+  "Stop_Recording" : "إيقاف التسجيل",
   "strike" : "شطب",
+  "Submit" : "تقديم",
+  "The_channel_name_is_required" : "اسم القناة مطلوب",
+  "The_field_is_required" : "هذا الحقل %s مطلوب.",
+  "The_server_will_restart_in_s_seconds" : "سيتم إعادة تشغيل الخادم في %s ثانية",
   "True" : "نعم",
-  "Unread_Rooms" : "غرف غير مقروءة",
+  "Type_your_new_password" : "اكتب كلمة المرور الجديدة",
+  "Unmute_user" : "إلغاء اسكات المستخدم",
+  "Unread_Rooms" : "الغرف غير مقروءة",
   "Unread_Rooms_Mode" : "وضع الغرف الغير مقروءة",
+  "Upload_file_question" : "تحميل الملف؟",
+  "Uploading_file" : "تحميل الملف ...",
+  "Use_Emojis" : "استخدم الرموز التعبيرية (ايموجي)",
   "Use_initials_avatar" : "استخدم الأحرف الأولى من اسم المستخدم",
   "use_menu" : "استخدم القائمة الجانبية للوصول إلى الغرف الخاصة بك والمحادثات",
   "Use_service_avatar" : "استخدام %s الرمزية",
@@ -162,24 +312,50 @@
   "Use_uploaded_avatar" : "استخدم الصورة المحملة",
   "Use_url_for_avatar" : "استخدم رابط للصورة الرمزية",
   "User_added_by" : "تم إضافة <em>__user_added__</em> بواسطة <em>__user_by__</em>.",
+  "User_Channels" : "قنوات المستخدم",
+  "User_has_been_activated" : "تم تفعيل المستخدم",
+  "User_has_been_deactivated" : "تم إلغاء تنشيط المستخدم",
+  "User_has_been_deleted" : "تم حذف العضو",
+  "User_Info" : "معلومات المستخدم",
   "User_is_no_longer_an_admin" : "المستخدم لم يعد مديرا",
+  "User_is_not_activated" : "العضو غير مفعل",
   "User_is_now_an_admin" : "المستخدم الآن مدير",
   "User_joined_channel" : "انضم للقناة.",
+  "User_joined_channel_female" : "انضمت للقناة",
+  "User_joined_channel_male" : "انضم للقناة.",
   "User_left" : "غادر القناة.",
+  "User_left_female" : "غادرت القناة.",
+  "User_left_male" : "غادر القناة.",
   "User_logged_out" : "المستخدم سجل الخروج",
-  "User_not_found_or_incorrect_password" : "اسم المستخدم غير موجود أو كلمة السر غير صحيحة",
+  "User_muted_by" : "تم اسكات <em>__user_muted__</em> بواسطة <em>__user_by__</em>.",
+  "User_not_found_or_incorrect_password" : "لم يتم العثور على المستخدم أو كلمة المرور غير صحيحة",
   "User_removed_by" : "تم حذف <em>__user_removed__</em> بواسطة <em>__user_by__</em>.",
+  "User_removed_from_room" : "تم إزالة المستخدم من الغرفة",
+  "User_Settings" : "إعدادات المستخدم",
+  "User_unmuted_by" : "تم إلغاء اسكات <em>__user_unmuted__</em> بواسطة <em>__user_by__</em>.",
+  "User_updated_successfully" : "تم تحديث العضو بنجاح",
   "Username" : "اسم المستخدم",
   "Username_cant_be_empty" : "اسم المستخدم لا يمكن أن يكون فارغا",
+  "Username_Change_Disabled" : "مدير الموقع منع تغيير اسم المستخدم",
   "Username_description" : "يتم استخدام اسم المستخدم للسماح للآخرين بذكرك في الرسائل.",
   "Username_invalid" : "<strong>%s</strong> لا يصلح كإسم مستخدم،<br/> استخدم فقط حروفا وأرقاما وشرطات",
   "Username_title" : "تسجيل اسم المستخدم",
   "Username_unavaliable" : "<strong>%s</strong> مستخدم مسبقا :(",
+  "Users" : "المستخدمين",
+  "UTF8_Names_Validation_Description" : "لا تسمح باستخدام رموز خاصة و مسافات. يمكنك استخدام العلامات التالية - _  . لكن لا تسمح بهن في نهاية الاسم.",
   "View_All" : "مشاهدة الكل",
   "We_have_sent_password_email" : "لقد قمنا بإرسال رسالة بريد إلكتروني مع إرشادات إعادة تعيين كلمة السر. إذا لم يصلك البريد الإلكتروني قريبا، يرجى العودة والمحاولة مرة أخرى.",
   "We_have_sent_registration_email" : "لقد قمنا بإرسال رسالة بريد إلكتروني لتأكيد تسجيلك. إذا لم يصلك البريد الإلكتروني قريبا، يرجى العودة والمحاولة مرة أخرى.",
   "Welcome" : "مرحبا بك يا <em>%s</em>.",
   "Welcome_to_the" : "أهلا بك في",
+  "With_whom" : "مع من",
+  "Yes" : "نعم",
+  "Yes_clear_all" : "نعم، حذف الكل!",
+  "Yes_delete_it" : "نعم، أحذف!",
+  "You_can_use_an_emoji_as_avatar" : "تستطيع استخدام ايموجي كصورة رمزية",
+  "You_have_been_muted" : "لقد تم اسكاتك ولا يمكنك التحدث في هذه الغرفة",
   "You_need_confirm_email" : "تحتاج إلى تأكيد بريدك الإلكتروني لتسجيل الدخول!",
+  "You_will_not_be_able_to_recover" : "لن تستطيع استرداد هذه الرسالة!",
+  "Your_entry_has_been_deleted" : "لقد تم حذف رسالتك",
   "Your_Open_Source_solution" : "تطبيق المحادثة الخاص بك المفتوح المصدر"
 }
\ No newline at end of file
diff --git a/i18n/de.i18n.json b/i18n/de.i18n.json
index 22c80008b852fd18551099c3ea54ecb4bc27ea25..ebca809b478681c98b56a2d264214f3861b66a6d 100644
--- a/i18n/de.i18n.json
+++ b/i18n/de.i18n.json
@@ -1,73 +1,106 @@
 {
-  "Access_online_demo" : "Öffne die online demo",
+  "Access_not_authorized" : "Der Zugriff ist nicht gestattet.",
+  "Access_online_demo" : "Öffne die Online-Demo",
   "Access_Online_Demo" : "Öffne die Online Demo",
-  "Accounts" : "Kontos",
-  "Accounts_AllowedDomainsList" : "Erlaubt Domains Liste",
-  "Accounts_AllowPasswordChange" : "Passwort ändern erlauben",
-  "Accounts_AllowUsernameChange" : "Änderung von Benutzernamen erlauben",
-  "Accounts_AvatarResize" : "Größe des Avatars anpassen",
-  "Accounts_AvatarSize" : "Avatar Größe",
-  "Accounts_AvatarStorePath" : "Avatar Speicherpfad",
-  "Accounts_AvatarStoreType" : "Avatar Speichertyp",
-  "Accounts_denyUnverifiedEmail" : "Nicht verifizierte E-Mails ablehnen",
+  "Access_Token_URL" : "URL des Access-Token",
+  "Accounts" : "Konten",
+  "Accounts_AllowedDomainsList" : "Liste von erlaubten Domains",
+  "Accounts_AllowedDomainsList_Description" : "Durch Kommata getrennte Liste von erlaubten Domains",
+  "Accounts_AllowPasswordChange" : "Ändern des Passworts zulassen",
+  "Accounts_AllowUserAvatarChange" : "Benutzern das Ändern des Profilbilds erlauben",
+  "Accounts_AllowUsernameChange" : "Ändern von Benutzernamen erlauben",
+  "Accounts_AllowUserProfileChange" : "Benutzern das Ändern des Profils erlauben",
+  "Accounts_AvatarResize" : "Größe des Profilbilds anpassen",
+  "Accounts_AvatarSize" : "Größe des Profilbilds",
+  "Accounts_AvatarStorePath" : "Speicherpfad des Profilbilds",
+  "Accounts_AvatarStoreType" : "Speichertyp des Profilbilds",
+  "Accounts_denyUnverifiedEmail" : "Nicht verifizierte E-Mail-Adressen ablehnen",
   "Accounts_EmailVerification" : "E-Mail-Verifizierung",
+  "Accounts_Enrollment_Email" : "Registrierungsmail",
+  "Accounts_Enrollment_Email_Description" : "Sie können [name] für den Vor- und Nachnamen, [fname] für den Vornamen oder [lname] für den Nachnamen des Benutzers verwenden. <br />Ebenfalls können Sie [email] verwenden, um die E-Mail-Adresse des Benutzers anzugeben.",
+  "Accounts_LoginExpiration" : "Ablauffrist der Anmeldung",
   "Accounts_ManuallyApproveNewUsers" : "Neue Benutzer manuell aktivieren",
   "Accounts_OAuth_Custom_Authorize_Path" : "Autorisierungspfad",
   "Accounts_OAuth_Custom_Button_Color" : "Buttonfarbe",
-  "Accounts_OAuth_Custom_Button_Label_Color" : "Button-Text-Farbe",
-  "Accounts_OAuth_Custom_Button_Label_Text" : "Button-Text",
+  "Accounts_OAuth_Custom_Button_Label_Color" : "Farbe des Buttontexts",
+  "Accounts_OAuth_Custom_Button_Label_Text" : "Text des Buttons",
   "Accounts_OAuth_Custom_Enable" : "Aktivieren",
-  "Accounts_OAuth_Custom_id" : "Id",
-  "Accounts_OAuth_Custom_Identity_Path" : "Identitäts Pfad",
+  "Accounts_OAuth_Custom_id" : "ID",
+  "Accounts_OAuth_Custom_Identity_Path" : "Identitätspfad",
+  "Accounts_OAuth_Custom_Login_Style" : "Anmeldungsart",
   "Accounts_OAuth_Custom_Secret" : "Secret",
-  "Accounts_OAuth_Custom_Token_Path" : "Token Pfad",
+  "Accounts_OAuth_Custom_Token_Path" : "Pfad des Token",
   "Accounts_OAuth_Custom_URL" : "URL",
-  "Accounts_OAuth_Facebook" : "Facebook Login",
+  "Accounts_OAuth_Facebook" : "Anmeldung über Facebook erlauben",
   "Accounts_OAuth_Facebook_id" : "Facebook-App-ID",
-  "Accounts_OAuth_Facebook_secret" : "Facebook Secret",
-  "Accounts_OAuth_Github" : "OAuth Enabled",
-  "Accounts_OAuth_Github_id" : "Client ID",
-  "Accounts_OAuth_Github_secret" : "Client Secret",
-  "Accounts_OAuth_Gitlab" : "OAuth aktiviert",
-  "Accounts_OAuth_Gitlab_id" : "Gitlab Id",
-  "Accounts_OAuth_Gitlab_secret" : "Client Secret",
-  "Accounts_OAuth_Google" : "Google Login",
-  "Accounts_OAuth_Google_id" : "Google Id",
-  "Accounts_OAuth_Google_secret" : "Google Secret",
-  "Accounts_OAuth_Linkedin" : "LinkedIn Login",
-  "Accounts_OAuth_Linkedin_id" : "LinkedIn Id",
-  "Accounts_OAuth_Linkedin_secret" : "Linkeding Secret",
-  "Accounts_OAuth_Meteor" : "Meteor Login",
-  "Accounts_OAuth_Meteor_id" : "Meteor Id",
-  "Accounts_OAuth_Meteor_secret" : "Meteor Secret",
-  "Accounts_OAuth_Twitter" : "Twitter Login",
-  "Accounts_OAuth_Twitter_id" : "Twitter Id",
-  "Accounts_OAuth_Twitter_secret" : "Twitter Secret",
+  "Accounts_OAuth_Facebook_secret" : "Facebook-Secret",
+  "Accounts_OAuth_Github" : "OAuth aktivieren",
+  "Accounts_OAuth_Github_id" : "Client-ID",
+  "Accounts_OAuth_Github_secret" : "Client-Secret",
+  "Accounts_OAuth_Gitlab" : "OAuth aktivieren",
+  "Accounts_OAuth_Gitlab_id" : "GitLab-ID",
+  "Accounts_OAuth_Gitlab_secret" : "Client-Secret",
+  "Accounts_OAuth_Google" : "Google-Anmeldung erlauben",
+  "Accounts_OAuth_Google_id" : "Google-ID",
+  "Accounts_OAuth_Google_secret" : "Google-Secret",
+  "Accounts_OAuth_Linkedin" : "Anmeldung über LinkedIn erlauben",
+  "Accounts_OAuth_Linkedin_id" : "LinkedIn-ID",
+  "Accounts_OAuth_Linkedin_secret" : "Linkeding-Secret",
+  "Accounts_OAuth_Meteor" : "Anmeldung über Meteor erlauben",
+  "Accounts_OAuth_Meteor_id" : "Meteor-ID",
+  "Accounts_OAuth_Meteor_secret" : "Meteor-Secret",
+  "Accounts_OAuth_Twitter" : "Anmeldung über Twitter erlauben",
+  "Accounts_OAuth_Twitter_id" : "Twitter-ID",
+  "Accounts_OAuth_Twitter_secret" : "Twitter-Secret",
+  "Accounts_PasswordReset" : "Passwort zurücksetzen",
+  "Accounts_Registration_AuthenticationServices_Enabled" : "Anmeldung mit Authentifizierungsdiensten",
+  "Accounts_RegistrationForm" : "Anmeldeformular",
+  "Accounts_RegistrationForm_Disabled" : "Deaktiviert",
+  "Accounts_RegistrationForm_LinkReplacementText" : "Ersatztext für den Registrierungsformularlink",
+  "Accounts_RegistrationForm_Public" : "Öffentlich",
+  "Accounts_RegistrationForm_Secret_URL" : "Geheime URL",
+  "Accounts_RegistrationForm_SecretURL" : "Geheime URL für die Registrierungsseite",
+  "Accounts_RegistrationForm_SecretURL_Description" : "Sie müssen eine zufällige Zeichenfolge, die der Registrierungs-URL hinzugefügt wird, verwenden. Beispiel: https://demo.rocket.chat/registrieren/[geheimer_schluessel]",
   "Accounts_RegistrationRequired" : "Anmeldung erforderlich",
+  "Accounts_RequireNameForSignUp" : "Ein Name ist für die Anmeldung erforderlich.",
+  "Accounts_ShowFormLogin" : "Anmeldeformular zeigen",
   "Activate" : "Aktivieren",
-  "Add_custom_oauth" : "Benutzerdefinierte oauth hinzufügen",
+  "Add_custom_oauth" : "Benutzerdefiniertes OAuth-Konto hinzufügen",
   "Add_Members" : "Mitglieder hinzufügen",
   "Add_users" : "Benutzer hinzufügen",
   "Administration" : "Administration",
+  "After_OAuth2_authentication_users_will_be_redirected_to_this_URL" : "Nach der OAuth2-Authentifizierung werden die Benutzer auf diese URL weitergeleitet.",
+  "Alias" : "Alias",
   "All_channels" : "Alle Kanäle",
-  "Allow_Invalid_SelfSigned_Certs" : "Selbstsignierte SSL-Zertifikate für die Link-Validierung und die Vorschau zulassen",
+  "Allow_Invalid_SelfSigned_Certs" : "Ungültige und selbstsignierte SSL-Zertifikate erlauben",
+  "Allow_Invalid_SelfSigned_Certs_Description" : "Ungültige und selbstsignierte SSL-Zertifikate für die Link-Validierung und die Vorschau zulassen",
   "and" : "und",
   "API" : "API",
   "API_Analytics" : "Analytics",
   "API_Embed" : "Einbetten",
-  "API_EmbedDisabledFor" : "Deaktiviere Embed für User",
+  "API_EmbedDisabledFor" : "Einbettungen für Benutzer deaktivieren",
   "API_EmbedDisabledFor_Description" : "Durch Kommata getrennte Liste von Benutzernamen",
+  "Application_added" : "Die Anwendung wurde hinzugefügt.",
+  "Application_Name" : "Name der Anwendung",
+  "Application_updated" : "Die Anwendung wurde aktualisiert.",
+  "Archive" : "Archivieren",
   "are_also_typing" : "schreiben auch",
   "are_typing" : "schreiben",
   "Are_you_sure" : "Sind Sie sicher?",
+  "Authorization_URL" : "Autorisierungs-URL",
+  "Authorize" : "Berechtigen",
   "Auto_Load_Images" : "Automatisches Laden der Bilder",
-  "Avatar_changed_successfully" : "Avatar erfolgreich geändert",
+  "Avatar_changed_successfully" : "Das Profilbild wurde erfolgreich geändert.",
+  "Avatar_URL" : "URL des Profilbilds",
+  "Avatar_url_invalid_or_error" : "Die angegebene Internetadresse ist ungültig oder nicht verfügbar. Bitte versuchen Sie es mit einer anderen Internetadresse erneut.",
   "away" : "abwesend",
   "Away" : "Abwesend",
   "away_female" : "abwesend",
   "Away_female" : "Abwesend",
   "away_male" : "abwesend",
   "Away_male" : "Abwesend",
+  "Back_to_applications" : "Zurück zu den Anwendungen",
+  "Back_to_integrations" : "Zurück zu Integrationen",
   "Back_to_login" : "Zurück zum Login",
   "bold" : "fett",
   "busy" : "beschäftigt",
@@ -77,89 +110,119 @@
   "busy_male" : "beschäftigt",
   "Busy_male" : "Beschäftigt",
   "Cancel" : "Abbrechen",
-  "CDN_PREFIX" : "CDN Präfix",
-  "Change_avatar" : "Ändere dein Avatar",
+  "CDN_PREFIX" : "CDN-Präfix",
+  "Certificates_and_Keys" : "Zertifikate und Schlüssel",
+  "Change_avatar" : "Profilbild",
   "Channels" : "Kanäle",
-  "Channels_list" : "Liste der öffentlichen Channels",
+  "Channels_list" : "Liste der öffentlichen Kanäle",
   "Chat_Rooms" : "Chaträume",
-  "Clear_all_unreads_question" : "Alle ungelesenen löschen?",
-  "close" : "schließen",
+  "Choose_the_alias_that_will_appear_before_the_username_in_messages" : "Wählen Sie den Alias, der vor dem Benutzernamen in den Nachrichten angezeigt wird.",
+  "Choose_the_username_that_this_integration_will_post_as" : "Wählen Sie den Benutzernamen, der die Integration veröffentlicht.",
+  "Clear_all_unreads_question" : "Möchten Sie alle ungelesenen Nachrichten löschen?",
+  "Client_ID" : "Client-ID",
+  "Client_Secret" : "Client-Secret",
+  "close" : "Schließen",
   "coming_soon" : "kommt bald",
   "Commands" : "Befehle",
-  "Compact_View" : "Kompakte Ansicht",
-  "Confirm_password" : "Bestätigen Sie Ihr Passwort",
+  "Compact_View" : "Kompaktansicht",
+  "Confirm_password" : "Bestätigen Sie Ihr Passwort.",
   "Contact" : "Kontakt",
   "Conversation" : "Konversation",
-  "Convert_Ascii_Emojis" : "Konvertiere ASCII zu Emoji",
+  "Convert_Ascii_Emojis" : "ASCII zu Emoji konvertieren",
+  "COPY_TO_CLIPBOARD" : "IN DIE ZWISCHENABLAGE KOPIEREN",
   "Create_new" : "Neu erstellen",
-  "Create_new_direct_message_room" : "Erstellen Sie einen neuen Direktnachrichten-Raum",
-  "Create_new_private_group" : "Erstellen Sie eine neue private Gruppe",
-  "Create_new_public_channel" : "Erstelle einen neuen öffentlichen Channel",
+  "Create_new_direct_message_room" : "Neuen privaten Nachrichtenraum erstellen",
+  "Create_new_private_group" : "Neue private Gruppe erstellen",
+  "Create_new_public_channel" : "Einen neuen öffentlichen Kanal erstellen",
   "Created_at" : "Erstellt am",
-  "Custom_oauth_helper" : "Bei der Einrichtung von OAuth, muss eine Callback-URL angegeben werden. Benutze <pre>%s</pre>",
-  "Custom_oauth_unique_name" : "Eindeutigen Namen von benutzerdefinierte oauth",
+  "Created_at_s_by_s" : "Erstellt am <strong>%s</strong> von <strong>%s</strong>",
+  "Custom_oauth_helper" : "Bei der Einrichtung muss eine Rückruf-URL angegeben werden. Benutze dafür folgende URL: <pre>%s</pre>",
+  "Custom_oauth_unique_name" : "Name des OAuth-Kontos",
   "days" : "Tage",
   "Deactivate" : "Deaktivieren",
-  "Delete_Room_Warning" : "Beim Löschen eines Raumes, werden seine Nachrichten ebenfalls gelöscht. Dies kann nicht rückgängig gemacht werden.",
-  "Delete_User_Warning" : "Beim Löschen eines Benutzers, werden alle seine Nachrichten ebenfalls gelöscht. Dies kann nicht rückgängig gemacht werden.",
+  "Delete_Room_Warning" : "Beim Löschen eines Raums werden alle Nachrichten in diesem Raum unwiderruflich gelöscht.",
+  "Delete_User_Warning" : "Beim Löschen eines Benutzers werden alle Nachrichten des Benutzers unwiderruflich gelöscht.",
   "Deleted" : "Gelöscht!",
   "Desktop_Notifications" : "Desktop-Benachrichtigungen",
   "Desktop_Notifications_Disabled" : "Desktop-Benachrichtigungen sind deaktiviert. Ändern Sie Ihre Browsereinstellungen, wenn Sie Benachrichtigungen erhalten wollen.",
-  "Desktop_Notifications_Enabled" : "Desktop-Benachrichtigungen sind aktiviert",
+  "Desktop_Notifications_Enabled" : "Desktop-Benachrichtigungen sind bereits aktiviert.",
   "Direct_Messages" : "Private Nachrichten",
   "Disable_Favorite_Rooms" : "Favoriten deaktivieren",
-  "Disable_New_Message_Notification" : "Deaktiviere Benachrichtigung bei neuen Nachrichten",
-  "Disable_New_Room_Notification" : "Deaktiviere Benachrichtigung bei neuen Raum Nachrichten",
-  "Drop_to_upload_file" : "Ablegen um Datei zu uploaden",
-  "Duplicate_channel_name" : "Ein Kanal mit dem Namen, '%s', existiert",
-  "Duplicate_private_group_name" : "Eine private Gruppe mit dem Namen, '%s', existiert",
+  "Disable_New_Message_Notification" : "Benachrichtigungen bei neuen Nachrichten deaktivieren",
+  "Disable_New_Room_Notification" : "Benachrichtigungen bei neuen Nachrichten in einem Raum deaktivieren",
+  "Do_you_want_to_change_to_s_question" : "Möchten Sie dies zu <strong>%s</strong> ändern?",
+  "Drop_to_upload_file" : "Ablegen, um Datei hochzuladen",
+  "Duplicate_archived_channel_name" : "Ein archivierter Kanal mit dem Namen '%s' existiert bereits.",
+  "Duplicate_archived_private_group_name" : "Eine archivierte private Gruppe mit dem Namen '%s' existiert bereits.",
+  "Duplicate_channel_name" : "Ein Kanal mit dem Namen '%s' existiert bereits.",
+  "Duplicate_private_group_name" : "Eine private Gruppe mit dem Namen '%s' existiert bereits.",
   "E-mail" : "E-Mail",
   "edited" : "bearbeitet",
-  "Email_already_exists" : "E-Mail existiert bereits",
-  "Email_or_username" : "Email oder Username",
-  "Email_verified" : "Email bestätigt",
+  "Email_already_exists" : "Die E-Mail-Adresse existiert bereits.",
+  "Email_or_username" : "E-Mail-Adresse oder Nutzername",
+  "Email_verified" : "Die E-Mail-Adresse wurde bestätigt.",
   "Emoji" : "Emoji",
-  "Enable_Desktop_Notifications" : "Aktiviere Desktop-Benachrichtigungen",
-  "Enter_info" : "Geben Sie Ihre Anmeldedaten an",
-  "Enter_to" : "Enter um",
+  "Enable_Desktop_Notifications" : "Aktivieren",
+  "Enter_info" : "Geben Sie Ihre Anmeldedaten an.",
+  "Enter_to" : "Betreten, um",
+  "Error" : "Fehler",
   "Error_changing_password" : "Fehler beim Ändern des Passwortes",
-  "Error_too_many_requests" : "Fehler, zu viele Anfragen. Slow down ;) Warte %s Sekunden vor einem erneuten Versuch",
-  "Esc_to" : "Esc um",
-  "False" : "Falsch",
+  "Error_too_many_requests" : "Fehler, zu viele Anfragen. Warte %s Sekunden, bevor du es erneut probierst.",
+  "Esc_to" : "Verlassen, um",
+  "Example_s" : "Beispiel: <code class=\"inline\">%s</code>",
+  "False" : "Nein",
   "Favorites" : "Favoriten",
-  "FileUpload" : "Datei-Upload",
-  "FileUpload_Enabled" : "Datei-Upload aktivieren",
+  "FileUpload" : "Dateien hochladen",
+  "FileUpload_Enabled" : "Hochladen von Dateien aktivieren",
+  "FileUpload_File_Empty" : "Datei ist leer",
   "FileUpload_MaxFileSize" : "Max. Größe für hochgeladene Dateien (in Bytes)",
-  "FileUpload_MediaTypeWhiteList" : "Durch Kommata getrennte Liste von Medientypen",
+  "FileUpload_MediaType_NotAccepted" : "Medientypen werden nicht akzeptiert",
+  "FileUpload_MediaTypeWhiteList" : "Erlaubte Medientypen",
   "FileUpload_MediaTypeWhiteListDescription" : "Durch Kommata getrennte Liste von Medientypen",
-  "Follow_social_profiles" : "Folge uns in sozialen Netzen, fork uns auf github und teile deine Gedanken über die rocket.chat app auf unserem trello board.",
+  "FileUpload_ProtectFiles" : "Hochgeladene Dateien schützen",
+  "FileUpload_ProtectFilesDescription" : "Nur bestätigte Benutzer dürfen Dateien hochladen.",
+  "Follow_social_profiles" : "Folge uns in sozialen Netzwerken, fork uns auf GitHub und teile deine Gedanken über die Rocket.Chat-App auf unserem Trello-Board.",
   "Forgot_password" : "Passwort vergessen?",
   "Fork_it_on_github" : "Fork es auf GitHub",
-  "From_Email" : "E-Mail von",
-  "General" : "Allgemein",
-  "Get_to_know_the_team" : "Lernen Sie das Rocket.Team kennen",
-  "github_no_public_email" : "Sie haben keine öffentliche Email-Adresse in Ihrem Github Account",
-  "Give_a_unique_name_for_the_custom_oauth" : "Geben Sie einen eindeutigen Namen für das benutzerdefinierte oauth",
+  "From_Email" : "Absender",
+  "General" : "Allgemeines",
+  "Get_to_know_the_team" : "Lernen Sie das Rocket.Team kennen.",
+  "github_no_public_email" : "Sie haben keine öffentliche E-Mail-Adresse in Ihrem GitHub-Account.",
+  "Give_a_unique_name_for_the_custom_oauth" : "Geben Sie dem benutzerdefinierten OAuth-Konto einen eindeutigen Namen.",
+  "Give_the_application_a_name_This_will_be_seen_by_your_users" : "Geben Sie der Anwendung einen Namen. Die Nutzer können den Namen sehen.",
   "Has_more" : "Mehr",
-  "Have_your_own_chat" : "Erstelle deinen eigenen web chat. Entwickelt mit Meteor.com, der Rocket.Chat ist eine tolle Lösung für Entwickler, die schnell und einfach einen eigene Chat Plattform aufbauen wollen.",
+  "Have_your_own_chat" : "Starte deinen eigenen Internet-Chat. Entwickelt mit Meteor.com. Rocket.Chat ist eine tolle Lösung für Entwickler, die schnell und einfach eine eigene Chat-Plattform aufbauen möchten.",
   "Hide_room" : "Raum verstecken",
   "History" : "Chronik",
   "hours" : "Stunden",
-  "Incorrect_Password" : "Falsches Passwort",
-  "inline_code" : "inline_code",
-  "Install_FxOs" : "Installiere Rocket.Chat auf deinem Firefox",
+  "Incorrect_Password" : "Das angegebene Passwort ist falsch.",
+  "inline_code" : "Code",
+  "Install_Extension" : "Erweiterung installieren",
+  "Install_FxOs" : "Rocket.Chat in deinem Firefox-Browser aktivieren",
   "Install_FxOs_done" : "Super! Du kannst Rocket.Chat nun über das Icon auf deinem Startbildschirm nutzen. Viel Spaß mit Rocket.Chat!",
   "Install_FxOs_error" : "Schade, das hat leider nicht geklappt! Der folgende Fehler ist aufgetreten:",
-  "Install_FxOs_follow_instructions" : "Bitte bestätige die Installation der App (drücke \"Installieren\" in der Aufforderung).",
-  "Invalid_confirm_pass" : "Die Passwörter stimmen nicht überein",
-  "Invalid_email" : "Email-Adresse ungültigt",
-  "Invalid_name" : "Der Name darf nicht leer sein",
-  "Invalid_pass" : "Das Passwort darf nicht leer sein",
+  "Install_FxOs_follow_instructions" : "Bitte bestätige die Installation der App, indem du auf \"Installieren\" klickst.",
+  "Integration_added" : "Die Integration wurde hinzugefügt.",
+  "Integration_Incoming_WebHook" : "Eingehende WebHook-Integration",
+  "Integration_New" : "Neue Integration",
+  "Integration_updated" : "Die Integration wurde aktualisiert.\n",
+  "Integrations" : "Integrationen",
+  "Invalid_asset" : "Ungültiger Wert",
+  "Invalid_confirm_pass" : "Die Passwörter stimmen nicht überein.",
+  "Invalid_email" : "Die eingegebenen E-Mail-Adresse ist ungültig.",
+  "Invalid_file_height" : "Ungültige Dateihöhe",
+  "Invalid_file_type" : "Ungültiges Dateiformat.",
+  "Invalid_file_width" : "Ungültige Dateibreite",
+  "Invalid_name" : "Es muss ein Name angegeben werden.",
+  "Invalid_pass" : "Es muss ein Passwort angegeben werden.",
   "Invalid_room_name" : "<strong>%s</strong> ist kein zulässiger Raumname.<br/> Benutze nur Buchstaben, Nummern und Bindestriche.",
+  "Invalid_room_type" : "<strong>%s</strong> ist kein gültiger Raumtyp.",
+  "Invalid_Secret_URL" : "Ungültige geheime URL",
+  "Invalid_secret_URL_message" : "Die angegebene URL ist ungültig.",
   "invisible" : "unsichtbar",
   "Invisible" : "Unsichtbar",
-  "Invitation_HTML" : "Einladungs HTML",
-  "Invitation_Subject" : "Einladungs Betreff",
+  "Invitation_HTML" : "Einladungstext (HTML)",
+  "Invitation_Subject" : "Einladungsbetreff",
   "Invite_Users" : "Benutzer einladen",
   "is_also_typing" : "schreibt auch",
   "is_also_typing_female" : "schreibt auch",
@@ -169,265 +232,385 @@
   "is_typing_male" : "schreibt",
   "italics" : "kursiv",
   "join" : "Beitreten",
+  "Join_audio_call" : "Anruf beitreiten",
   "Join_the_Community" : "Trete der Community bei",
+  "Join_video_call" : "Videoanruf beitreten",
+  "Jump_to_first_unread" : "Erste ungelesene Nachricht anzeigen",
+  "Jump_to_message" : "Diese Nachricht im Chat anzeigen",
+  "Jump_to_recent_messages" : "Neue Nachricht im Chat anzeigen",
   "Language" : "Sprache",
   "Language_Version" : "Deutsche Version",
-  "Last_login" : "Letztes login",
+  "Last_login" : "Letzte Anmeldung",
   "Last_message" : "Letzte Nachricht",
   "Layout" : "Layout",
-  "Layout_Home_Body" : "Home Body",
-  "Layout_Home_Title" : "Home Title",
-  "Layout_Login_Header" : "Login Header",
-  "Layout_Login_Terms" : "Nutzungsbedingungen zu Anmeldung",
+  "Layout_Home_Body" : "Inhalt der Startseite",
+  "Layout_Home_Title" : "Titel der Startseite",
+  "Layout_Login_Header" : "Kopfzeile der Anmeldeseite",
+  "Layout_Login_Terms" : "Anmeldebedingungen",
   "Layout_Privacy_Policy" : "Datenschutzbestimmungen",
-  "Layout_Sidenav_Footer" : "Seiten Navigations Footer",
-  "Layout_Sidenav_Footer_description" : "Die Footer Größe ist 260x70",
+  "Layout_Sidenav_Footer" : "Seitenfußzeile",
+  "Layout_Sidenav_Footer_description" : "Die Größe der Fußzeile beträgt 260 x 70 Pixel.",
   "Layout_Terms_of_Service" : "Nutzungsbedingungen",
   "LDAP" : "LDAP",
-  "LDAP_Bind_Search" : "Bind Suche",
-  "LDAP_DN" : "LDAP DN",
+  "LDAP_Bind_Search" : "Bind-Suche",
+  "LDAP_Bind_Search_Description" : "Ein Stück von JSON, welches Bind und Verbindungsinformationen regelt, und folgende Form hat: {\"filter\": \"(&(objectCategory=person)(objectclass=user)(memberOf=CN=ROCKET_ACCESS,CN=Users,DC=domain,DC=com)(sAMAccountName=#{username}))\", \"scope\": \"sub\", \"userDN\": \"rocket.service@domain.com\", \"password\": \"urpass\"}",
+  "LDAP_CA_Cert" : "CA-Cert",
+  "LDAP_Description" : "LDAP ist ein  Frontend zu hierarchischen Datenbanken, die viele Unternehmen nutzen, um eine eine Einmalanmeldung (SSO) zu ermöglichen. Über SSO kann \"ein Benutzer nach einer einmaligen Authentifizierung an einem Arbeitsplatz auf alle Rechner und Dienste, für die er lokal berechtigt ist, am selben Arbeitsplatz zugreifen kann, ohne sich jedes Mal neu anmelden zu müssen\". Genauere Informationen zur Konfiguration von LDAP mit Konfigurationsbeispielen erhalten Sie unter folgendem Link: https://github.com/RocketChat/Rocket.Chat/wiki/LDAP-Authentication",
+  "LDAP_DN" : "Distinguished Name (DN)",
+  "LDAP_DN_Description" : "Suche root. Beispiel: dc=domain, dc=com",
   "LDAP_Enable" : "LDAP aktivieren",
-  "LDAP_Port" : "LDAP Port",
-  "LDAP_Url" : "LDAP URL",
+  "LDAP_Enable_Description" : "LDAP für die Authentifizierung verwenden.",
+  "LDAP_Port" : "LDAP-Port",
+  "LDAP_Port_Description" : "Port für den Zugriff auf LDAP. Beispiel: Port 389",
+  "LDAP_Reject_Unauthorized" : "Unberechtigte ablehnen",
+  "LDAP_Sync_User_Data" : "Daten synchronisieren",
+  "LDAP_Sync_User_Data_Description" : "Bei der Anmeldung die Benutzerdaten mit dem Server synchronisieren (Beispiel: Name, E-Mail).",
+  "LDAP_Sync_User_Data_FieldMap" : "Nutzerdaten-Feldkarte",
+  "LDAP_Sync_User_Data_FieldMap_Description" : "Konfigurieren Sie, wie Benutzer-Account-Felder (wie die E-Mail-Adresse) aus einem Datensatz (sobald gefunden) in LDAP besiedelt werden. Beispiel: {\"cn\": \"Name\", \"Mail\": \"E-Mail\"} nimmt einen von Menschen lesbaren Namen von dem cn-Attribut und die E-Mail-Adresse vom Mail-Attribut. Verfügbare Felder beinhalten den Namen und die E-Mail-Adresse.",
+  "LDAP_TLS" : "TLS",
+  "LDAP_Url" : "LDAP-URL",
+  "LDAP_Url_Description" : "URL des LDAP-Servers. Beispiel: ldap://company.dns.com",
   "Leave_room" : "Raum verlassen",
   "line" : "Zeilen",
   "Load_more" : "Mehr laden",
   "Loading..." : "Wird geladen ...",
-  "Loading_more_from_history" : "Lade mehr aus der Historie",
+  "Loading_more_from_history" : "Mehr Nachrichten aus dem Verlauf anzeigen",
   "Loading_suggestion" : "Vorschläge werden geladen...",
-  "Login" : "Login",
-  "Login_with" : "Login mit %s",
+  "Logged_out_of_other_clients_successfully" : "Sie wurden erfolgreich von anderen Geräten abgemeldet.",
+  "Login" : "Anmelden",
+  "Login_with" : "Anmelden mit %s",
   "login_with" : "Oder melden Sie sich direkt mit folgenden Accounts an",
   "Logout" : "Abmelden",
-  "Make_Admin" : "zum Admin machen",
+  "Logout_Others" : "Von anderen Geräten abmelden",
+  "Make_Admin" : "Benutzer zum Admin ernennen",
   "Mark_as_read" : "Als gelesen markieren",
-  "Markdown_Headers" : "Markdown-Headers",
+  "Markdown_Headers" : "Markdown-Ãœberschriften",
   "Members" : "Mitglieder",
-  "Members_List" : "Mitgliederliste",
+  "Members_List" : "Mitglieder",
   "Members_placeholder" : "Mitglieder",
   "Message" : "Nachricht",
-  "Message_AllowDeleting" : "Erlaube Nachrichten zu löschen",
-  "Message_AllowEditing" : "Erlaube Bearbeitung von Nachrichten",
-  "Message_AllowEditing_BlockEditInMinutes" : "Bearbeiten von Nachrichten blockieren nach (in Minuten - 0 zum deaktivieren)",
-  "Message_AllowEditing_BlockEditInMinutesDescription" : "Geben Sie 0 ein, um das Blocken zu deaktivieren.",
-  "Message_AudioRecorderEnabled" : "Audio Recorder Aktiviert",
-  "Message_deleting_not_allowed" : "Nachrichten löschen nicht erlaubt",
-  "Message_editing_blocked" : "Diese Nachricht kann nicht mehr bearbeitet werden",
-  "Message_editing_not_allowed" : "Nachrichten bearbeiten nicht erlaubt",
+  "Message_AllowDeleting" : "Das Löschen von Nachrichten erlauben",
+  "Message_AllowEditing" : "Die Bearbeitung von Nachrichten erlauben",
+  "Message_AllowEditing_BlockEditInMinutes" : "Bearbeiten von Nachrichten nach (in Minuten - 0 zum deaktivieren) blockieren ",
+  "Message_AllowEditing_BlockEditInMinutesDescription" : "Geben Sie eine 0 ein, um das Bearbeiten von Nachrichten jederzeit zu erlauben.",
+  "Message_AudioRecorderEnabled" : "Audioaufnahme aktivieren",
+  "Message_AudioRecorderEnabledDescription" : "'audio/wav'-Dateien sind erforderlich, damit der Medientyp in den \"Dateien-Upload\"-Einstellungen akzeptiert wird.",
+  "Message_deleting_not_allowed" : "Das Löschen von Nachrichten ist nicht erlaubt.",
+  "Message_editing_blocked" : "Diese Nachricht kann nicht mehr bearbeitet werden.",
+  "Message_editing_not_allowed" : "Das Bearbeiten von Nachrichten ist nicht erlaubt.",
+  "Message_GroupingPeriod" : "Gruppierungsdauer (in Sekunden)",
+  "Message_GroupingPeriodDescription" : "Nachrichten werden einer vorherigen Nachricht zugeordnet, wenn beide Nachrichten von dem gleichen Benutzer kommen und die abgelaufene Zeit kleiner als die mitgeteilte Zeit in Sekunden war.",
   "Message_KeepHistory" : "Nachrichtenverlauf behalten",
-  "Message_MaxAllowedSize" : "Maximale Größe der Nachricht",
-  "Message_pinned" : "Nachricht angeheftet",
-  "Message_pinning_not_allowed" : "Nachrichten anheften erlaubt",
-  "Message_removed" : "Nachricht entfernt",
-  "Message_ShowDeletedStatus" : "Zeige Löschstatus",
-  "Message_ShowEditedStatus" : "Zeige Bearbeitungsstatus",
-  "Message_ShowFormattingTips" : "Formatierungs-Tipps anzeigen",
+  "Message_MaxAllowedSize" : "Maximal zulässige Größe der Nachrichten\n",
+  "Message_pinned" : "Die Nachricht wurde fixiert.",
+  "Message_pinning_not_allowed" : "Das Fixieren von Nachrichten verbieten",
+  "Message_removed" : "Diese Nachricht wurde entfernt.",
+  "Message_ShowDeletedStatus" : "Löschstatus zeigen",
+  "Message_ShowEditedStatus" : "Bearbeitungsstatus zeigen",
+  "Message_ShowFormattingTips" : "Formatierungstipps anzeigen",
   "Messages" : "Nachrichten",
-  "Meta" : "Meta",
-  "Meta_fb_app_id" : "Facebook APP ID",
-  "Meta_google-site-verification" : "Google Seiten",
+  "Messages_that_are_sent_to_the_Incoming_WebHook_will_be_posted_here" : "Nachrichten, die an den eingehenden Webhook gesendet werden, werden hier veröffentlicht.",
+  "Meta" : "Metadaten",
+  "Meta_fb_app_id" : "Facebook-App-ID",
+  "Meta_google-site-verification" : "Google-Seiten-Verifizierung",
   "Meta_language" : "Sprache",
   "Meta_msvalidate01" : "MSValidate.01",
-  "Meta_robots" : "Robots",
+  "Meta_robots" : "Roboter",
   "minutes" : "Minuten",
-  "More_channels" : "Mehr Channels",
+  "More_channels" : "Mehr Kanäle",
   "More_groups" : "Weitere private Gruppen",
-  "More_unreads" : "Mehr ungelesene",
-  "Msgs" : "Mttl",
+  "More_unreads" : "Mehr ungelesene Nachrichten",
+  "Msgs" : "Nachrichten",
   "multi" : "mehrere",
+  "Mute_user" : "Benutzern das Chatten verbieten",
+  "Muted" : "Stumm geschaltet",
   "My_Account" : "Mein Konto",
   "n_messages" : "%s Nachrichten",
   "Name" : "Name",
-  "Name_cant_be_empty" : "Name darf nicht leer sein",
-  "Name_optional" : "Name (freiwillig)",
+  "Name_cant_be_empty" : "Es muss ein Name angegeben werden.",
+  "Name_optional" : "Name (optional)",
+  "New_Application" : "Neue Anwendung",
+  "New_integration" : "Neue Integration",
   "New_messages" : "Neue Nachrichten",
   "New_password" : "Neues Passwort",
-  "No_channel_with_name_%s_was_found" : "Es wurde keine Kanal mit dem Namen <strong>\"%s\"</strong> gefunden!",
-  "No_channels_yet" : "Sie sind kein Mitglied eines Channels.",
+  "No_channel_with_name_%s_was_found" : "Es wurde kein Kanal mit dem Namen <strong>\"%s\"</strong> gefunden!",
+  "No_channels_yet" : "Sie sind kein Mitglied eines Kanals.",
   "No_direct_messages_yet" : "Sie haben keine Konversation gestartet.",
-  "No_favorites_yet" : "Sie haben keine Favoriten hinzugefügt.",
+  "No_favorites_yet" : "Sie haben noch keine Favoriten hinzugefügt.",
   "No_group_with_name_%s_was_found" : "Es wurde keine private Gruppe mit dem Namen <strong>\"%s\"</strong> gefunden!",
   "No_groups_yet" : "Sie sind kein Mitglied einer privaten Gruppe.",
-  "No_permission_to_view_room" : "Sie haben keine Berechtigung diesen Raum zu betreten",
+  "No_livechats" : "Kein LiveChat vorhanden.",
+  "No_permission_to_view_room" : "Sie haben keine Berechtigung, diesen Raum zu betreten.",
+  "No_results_found" : "Keine Ergebnisse gefunden.",
+  "no_tokens_for_this_user" : "Es liegen keine Token für diesen Benutzer vor.",
   "No_user_with_username_%s_was_found" : "Es wurde kein Benutzer mit dem Namen <strong>\"%s\"</strong> gefunden!",
   "Not_allowed" : "Nicht erlaubt",
-  "Not_found_or_not_allowed" : "Nicht gefunden oder erlaubt",
-  "Nothing_found" : "Nichts gefunden",
-  "Notify_all_in_this_room" : "Alle in diesem Raum benachrichtigen",
-  "Old_and_new_password_required" : "Das alte und neue Passwort müssen angegeben werden um das jetzige Passwort zu ändern.",
+  "Not_authorized" : "Nicht berechtigt",
+  "Not_found_or_not_allowed" : "Nicht gefunden oder nicht erlaubt.",
+  "Nothing_found" : "Es wurde nichts gefunden.",
+  "Notify_all_in_this_room" : "Alle Benutzer in diesem Raum benachrichtigen",
+  "OAuth_Application" : "OAuth-Anwendung",
+  "OAuth_Applications" : "OAuth-Anwendungen",
+  "Old_and_new_password_required" : "Das alte und neue Passwort muss angegeben werden, um das derzeitige Passwort zu ändern.",
   "Old_Password" : "Altes Passwort",
   "Online" : "Online",
-  "Only_you_can_see_this_message" : "Nur Sie können diese Nachricht sehen",
-  "Oops!" : "Oops",
-  "Opt_out_statistics" : "Meine anonymen Statitstiken nicht an Rocke.Chat senden",
-  "Opt_out_statistics_warning" : "Durch das Absenden Ihrer anonymen Statistiken, werden Sie uns helfen, festzustellen, wie viele Instanzen von Rocket.Chat eingesetzt werden, und wie gut das System verhält, so können wir es weiter verbessern. Wenn Sie weiterhin das Senden von anonymen Statistiken möchten, deaktivieren Sie das Kontrollkästchen oben. Danke.",
+  "Only_you_can_see_this_message" : "Nur Sie können diese Nachricht sehen.",
+  "Oops!" : "Hoppla",
+  "Opt_out_statistics" : "Meine anonymen Statistiken nicht an Rocket.Chat senden",
+  "Opt_out_statistics_warning" : "Indem Sie uns Ihre anonymen Statistiken zur Verfügung stellen, können wir feststellen, wie viele Personen Rocket.Chat installiert haben und wie gut Rocket.Chat funktioniert. Das hilft uns dabei, Rocket.Chat weiterzuentwickeln. Es werden keine Benutzerinformationen gesendet und die erhaltenen Daten werden vertraulich behandelt. Wenn Sie weiterhin anonyme Statistiken an uns senden möchten, deaktivieren Sie bitte das Kontrollkästchen oben. Vielen Dank.",
+  "optional" : "optional",
   "others" : "andere",
   "Password" : "Passwort",
-  "Password_Change_Disabled" : "Der Administrator hat das Ändern des Passwortes nicht erlaubt.",
-  "Password_changed_successfully" : "Passwort erfolgreich geändert",
-  "People" : "Leute",
+  "Password_Change_Disabled" : "Der Administrator hat das Ändern des Passworts deaktiviert.",
+  "Password_changed_successfully" : "Das Passwort wurde erfolgreich geändert.",
+  "People" : "Menschen",
+  "Please_enter_value_for_url" : "Bitte geben Sie eine URL für Ihr Profilbild ein.",
+  "Please_enter_your_new_password_below" : "Bitte geben Sie Ihr neues Passwort ein:",
   "Please_wait" : "Bitte warten",
-  "Please_wait_activation" : "Bitte warten. ",
-  "Please_wait_statistics" : "Bitte warten, Statistiken werden generiert.",
+  "Please_wait_activation" : "Bitte warten, der Vorgang kann einige Zeit in Anspruch nehmen.",
+  "Please_wait_statistics" : "Bitte warten, die Statistiken werden erstellt.",
+  "Post_as" : "Verschicken als",
+  "Post_to_Channel" : "Im Kanal veröffentlichen",
+  "Post_to_s_as_s" : "Versenden an <strong>%s</strong> als <strong>%s</strong>",
   "Powered_by" : "Powered by",
   "Preferences" : "Einstellungen",
-  "Preferences_saved" : "Einstellungen gespeichert",
+  "Preferences_saved" : "Die Einstellungen wurden gespeichert.",
   "Privacy" : "Datenschutz",
   "Private_Groups" : "Private Gruppen",
-  "Private_Groups_list" : "Liste der Private Gruppen",
+  "Private_Groups_list" : "Liste aller privaten Gruppen",
   "Profile" : "Profil",
-  "Profile_saved_successfully" : "Profil erfolgreich gespeichert",
-  "Proudly_developed" : "Stolz mit Meteor entwickelt",
-  "Push" : "Push",
-  "Push_apn_cert" : "APN Cert",
-  "Push_apn_dev_cert" : "APN Dev Cert",
-  "Push_apn_dev_key" : "APN Dev Key",
-  "Push_apn_dev_passphrase" : "APN Dev Passphrase",
-  "Push_apn_key" : "APN Key",
-  "Push_apn_passphrase" : "APN Passphrase",
+  "Profile_saved_successfully" : "Das Profil wurde erfolgreich gespeichert",
+  "Proudly_developed" : "Stolz mit Meteor entwickelt.",
+  "Push" : "Push-Nachrichten",
+  "Push_apn_cert" : "APN-Cert",
+  "Push_apn_dev_cert" : "APN-Dev-Cert",
+  "Push_apn_dev_key" : "APN-Dev-Key",
+  "Push_apn_dev_passphrase" : "APN-Dev-Passphrase",
+  "Push_apn_key" : "APN-Key",
+  "Push_apn_passphrase" : "APN-Passphrase",
   "Push_debug" : "Debuggen",
+  "push_disabled" : "Push-Nachrichten deaktiviert",
   "Push_enable" : "Aktivieren",
-  "Push_gcm_api_key" : "GCM API Key",
-  "Push_gcm_project_number" : "GCM Projektnummer",
+  "Push_enable_gateway" : "Gateway aktivieren",
+  "Push_gateway" : "Gateway",
+  "Push_gcm_api_key" : "GCM-API-Key",
+  "Push_gcm_project_number" : "GCM-Projektnummer",
   "Push_production" : "Produktion",
+  "Push_test_push" : "Test",
   "Quick_Search" : "Schnellsuche",
   "quote" : "Zitat",
   "Recents" : "Aktuell",
   "Record" : "Aufnehmen",
-  "Register" : "Registriere einen neuen Account",
-  "Registration_Succeeded" : "Registrierung erfolgreich",
-  "Remember_me" : "Erinnere dich an mich",
+  "Redirect_URI" : "Weiterleitungs-URL",
+  "Refresh_your_page_after_install_to_enable_screen_sharing" : "Aktualisieren Sie die Seite nach der Installation, um die Bildschirmübertragung zu aktivieren.",
+  "Register" : "Registrieren Sie ein neues Konto",
+  "Registration_Succeeded" : "Ihre Registrierung war erfolgreich.",
+  "Remember_me" : "Erinnere mich",
   "Remove" : "Entfernen",
   "Remove_Admin" : "Admin entfernen",
-  "Remove_custom_oauth" : "Entferne benutzerdefiniertes oauth",
+  "Remove_as_moderator" : "Moderatorenrechte entfernen",
+  "Remove_as_owner" : "als Besitzer entfernen",
+  "Remove_custom_oauth" : "OAuth-Konto entfernen",
+  "Remove_from_room" : "Aus dem Raum entfernen",
+  "Removed" : "Entfernt",
+  "Reset" : "Zurücksetzen",
   "Reset_password" : "Passwort zurücksetzen",
+  "Restart" : "Neustart",
+  "Restart_the_server" : "Server neustarten",
   "Room" : "Raum",
-  "Room_name_changed" : "Raumname geändert zu: <em>__room_name__</em> von <em>__user_by__</em>",
-  "Room_name_changed_successfully" : "Raumname erfolgreich umbenannt",
-  "Room_not_found" : "Raum nicht gefunden",
-  "Room_uploaded_file_list" : "Dateiliste",
-  "Room_uploaded_file_list_empty" : "Keine Dateien zur Verfügung.",
+  "Room_archived" : "Der Raum wurde archiviert.",
+  "Room_has_been_deleted" : "Der Raum wurde gelöscht.",
+  "Room_name_changed" : "Der Raumname wurde von <em>__user_by__</em> zu  <em>__room_name__</em> geändert.",
+  "Room_name_changed_successfully" : "Der Raumname wurde erfolgreich geändert.",
+  "Room_not_found" : "Der Raum konnte nicht gefunden werden.",
+  "Room_unarchived" : "Der Raum wurde wiederhergestellt.",
+  "Room_uploaded_file_list" : "Dateien",
+  "Room_uploaded_file_list_empty" : "Es wurden noch keine Dateien hochgeladen.",
   "room_user_count" : "%s Benutzer",
   "Rooms" : "Räume",
   "S_new_messages_since_s" : "%s neue Nachrichten seit %s",
   "SAML" : "SAML",
-  "SAML_Custom_Cert" : "Benutzerdefinierte Zertifikat",
-  "SAML_Custom_Entry_point" : "Individueller Einstiegspunkt",
+  "SAML_Custom_Cert" : "Benutzerdefiniertes Zertifikat",
+  "SAML_Custom_Entry_point" : "Einsprungspunkt",
   "SAML_Custom_Generate_Username" : "Benutzernamen generieren",
+  "SAML_Custom_Issuer" : "Benutzerdefinierter Aussteller",
   "SAML_Custom_Provider" : "Benutzerdefinierter Provider",
   "Save_changes" : "Änderungen speichern",
-  "Save_Mobile_Bandwidth" : "Mobilfunkbandbreite verringern",
+  "Save_Mobile_Bandwidth" : "Mobiles Datenvolumen sparen",
+  "Screen_Share" : "Bildschirmübertragung",
   "Search" : "Suche",
-  "Search_Messages" : "Nachrichten suchen",
+  "Search_Messages" : "Nachrichten durchsuchen",
   "Search_settings" : "Sucheinstellungen",
   "seconds" : "Sekunden",
   "See_all" : "Alle anzeigen",
   "See_only_online" : "Nur online",
-  "Select_an_avatar" : "Wählen Sie ein Avatar",
+  "Select_an_avatar" : "Profilbild auswählen",
   "Select_file" : "Datei wählen",
-  "Select_service_to_login" : "Wählen Sie einen Service um sich einzuloggen, ein Bild auszuwählen oder eines direkt von Ihrem Computer hochzuladen",
+  "Select_service_to_login" : "Wählen Sie einen Dienst zum Anmelden aus, um ein Bild auszuwählen oder ein Bild direkt von Ihrem Computer hochzuladen.",
   "Selected_users" : "Ausgewählte Mitglieder",
-  "Send" : "Absenden",
-  "Send_confirmation_email" : "Bestätigungsmail versendet",
-  "Send_invitation_email" : "Einladungs E-Mail senden",
-  "Send_invitation_email_error" : "Sie haben kein gültige E-Mail-Adresse angegeben.",
-  "Send_invitation_email_info" : "Sie können mehrere E-Mail-Einladungen auf einmal absenden.",
-  "Send_invitation_email_success" : "Sie haben erfolgreich eine Einladung per E-Mail an folgende Adressen versendet:",
-  "Send_invitation_email_warning" : "Um Einladungs-E-Mails zu senden, müssen Sie zuerst die SMTP-Einstellungen konfigurieren.",
+  "Send" : "Senden",
+  "Send_a_test_mail_to_my_user" : "Eine Test-E-Mail an die Benutzer senden",
+  "Send_a_test_push_to_my_user" : "Eine Test-Push-Nachricht an die Benutzer senden",
+  "Send_confirmation_email" : "Bestätigungsmail versenden",
+  "Send_data_into_RocketChat_in_realtime" : "Daten in Rocket.Chat in Echtzeit senden.",
+  "Send_invitation_email" : "Einladung per E-Mail senden",
+  "Send_invitation_email_error" : "Sie haben keine gültige E-Mail-Adresse angegeben.",
+  "Send_invitation_email_info" : "Sie können mehrere Einladungen per E-Mail gleichzeitig absenden.",
+  "Send_invitation_email_success" : "Sie haben erfolgreich eine Einladung an folgende E-Mail-Adressen versendet:",
+  "Send_invitation_email_warning" : "Um Einladungen per E-Mail zu versenden, müssen Sie zuerst die SMTP-Einstellungen konfigurieren.",
   "Send_Message" : "Nachricht senden",
+  "Send_your_JSON_payloads_to_this_URL" : "Senden Sie Ihre JSON-Nutzlasten an diese URL.",
+  "Set_as_moderator" : "Zum Moderator ernennen",
+  "Set_as_owner" : "zum Besitzer machen",
   "Settings" : "Einstellungen",
-  "Settings_updated" : "Einstellungen aktualisiert",
+  "Settings_updated" : "Die Einstellungen wurden aktualisiert.",
+  "Should_be_a_URL_of_an_image" : "Dies soll die URL des Bildes sein.",
+  "Should_exists_a_user_with_this_username" : "Der Benutzer muss bereits vorhanden sein.",
+  "Showing_archived_results" : "<b>%s</b> archivierte Räume",
   "Showing_online_users" : "Zeige <b>__total_online__</b> von __total__ users",
-  "Showing_results" : "<p>Zeige <b>%s</b> Ergebnisse</p>",
+  "Showing_results" : "<p><b>%s</b> Ergebnisse</p>",
   "Silence" : "Ruhe",
   "since_creation" : "seit %s",
-  "Site_Name" : "Seitenname:",
-  "Site_Url" : "Website URL",
+  "Site_Name" : "Seitenname",
+  "Site_Url" : "Website-URL",
   "Site_Url_Description" : "Beispiel: https://chat.domain.com/",
   "SMTP" : "SMTP",
-  "SMTP_Host" : "SMTP Host",
-  "SMTP_Password" : "SMTP Passwort",
-  "SMTP_Port" : "SMTP Port",
-  "SMTP_Username" : "SMTP Benutzername",
-  "Sound" : "Sound",
+  "SMTP_Host" : "SMTP-Host",
+  "SMTP_Password" : "SMTP-Passwort",
+  "SMTP_Port" : "SMTP-Port",
+  "SMTP_Test_Button" : "SMTP-Einstellungen testen",
+  "SMTP_Username" : "SMTP-Benutzername",
+  "Sound" : "Ton",
+  "Start_audio_call" : "Anruf starten",
   "Start_of_conversation" : "Beginn der Konversation",
+  "Start_video_call" : "Videoanruf starten",
+  "Start_with_s_for_user_or_s_for_channel_Eg_s_or_s" : "Starten Sie mit <code class=\"inline\">%s</code> für Nutzer oder <code class=\"inline\">%s</code> für Kanäle. Beispiel: <code class=\"inline\">%s</code> oder <code class=\"inline\">%s</code>",
   "Statistics" : "Statistiken",
   "Stats_Active_Users" : "Aktive Benutzer",
-  "Stats_Avg_Channel_Users" : "Durchschnittliche Kanal Benutzer",
-  "Stats_Avg_Private_Group_Users" : "Durchschnittliche Benutzer in Privater Gruppe",
-  "Stats_Away_Users" : "Beschäftige Benutzer",
-  "Stats_Max_Room_Users" : "Maximale Raum Benutzer",
-  "Stats_Non_Active_Users" : "Ina",
+  "Stats_Avg_Channel_Users" : "Durchschnittliche Benutzeranzahl pro Kanal",
+  "Stats_Avg_Private_Group_Users" : "Durchschnittliche Benutzeranzahl in privaten Gruppen",
+  "Stats_Away_Users" : "Abwesende Benutzer",
+  "Stats_Max_Room_Users" : "Maximale Benutzeranzahl eines Raums",
+  "Stats_Non_Active_Users" : "Nicht aktive Benutzer",
   "Stats_Offline_Users" : "Benutzer offline",
   "Stats_Online_Users" : "Benutzer online",
-  "Stats_OS_Arch" : "OS Arch",
-  "Stats_OS_Cpus" : "OS CPU Count",
-  "Stats_OS_Freemem" : "OS freier Speicher",
-  "Stats_OS_Loadavg" : "OS Auslastungsdurchschnitt",
-  "Stats_OS_Platform" : "OS Plattform",
-  "Stats_OS_Release" : "OS Release",
-  "Stats_OS_Totalmem" : "OS Gesamtspeicher",
-  "Stats_OS_Type" : "OS Typ",
-  "Stats_OS_Uptime" : "OS Uptime",
-  "Stats_Total_Channels" : "Anzahl Kanäle",
-  "Stats_Total_Direct_Messages" : "Anzahl der Direktnachrichtenräume",
-  "Stats_Total_Messages" : "Anzahl der Nachrichten",
-  "Stats_Total_Private_Groups" : "Anzahl der Privaten Gruppen",
+  "Stats_OS_Arch" : "Systemtyp",
+  "Stats_OS_Cpus" : "CPU-Zähler",
+  "Stats_OS_Freemem" : "Freier Speicherplatz",
+  "Stats_OS_Loadavg" : "Durchschnittliche Systemauslastung (\"Load\")",
+  "Stats_OS_Platform" : "Plattform",
+  "Stats_OS_Release" : "Version",
+  "Stats_OS_Totalmem" : "Gesamtspeicherplatz",
+  "Stats_OS_Type" : "Betriebssystem",
+  "Stats_OS_Uptime" : "Systemverfügbarkeit",
+  "Stats_Total_Channels" : "Anzahl der Kanäle",
+  "Stats_Total_Direct_Messages" : "Anzahl der privaten Nachrichtenräume",
+  "Stats_Total_Messages" : "Anzahl aller Nachrichten",
+  "Stats_Total_Private_Groups" : "Anzahl der privaten Gruppen",
   "Stats_Total_Rooms" : "Anzahl der Räume",
   "Stats_Total_Users" : "Anzahl der Benutzer",
   "Stop_Recording" : "Aufnahme stoppen",
   "strike" : "durchgestrichen",
   "Submit" : "Abschicken",
+  "Success" : "Dieser Vorgang war erfolgreich.",
+  "The_application_name_is_required" : "Es muss ein Name für diese Anwendung angegeben werden.",
+  "The_channel_name_is_required" : "Ein Name für den Kanal muss angegeben werden.",
   "The_field_is_required" : "Das Feld %s ist erforderlich.",
-  "True" : "Wahr",
+  "The_image_resize_will_not_work_because_we_can_not_detect_ImageMagick_or_GraphicsMagick_installed_in_your_server" : "Die automatische Skalierung der Bilder funktioniert nicht, da ImageMagick oder GraphicsMagick nicht auf dem Server installiert sind.",
+  "The_redirectUri_is_required" : "Es muss eine Weiterleitung-URL angegeben werden.",
+  "The_server_will_restart_in_s_seconds" : "Der Server wird in %s Sekunden neu gestartet",
+  "The_setting_s_is_configured_to_s_and_you_are_accessing_from_s" : "Die Einstellung <strong>%s</strong> wurde zu <strong>%s</strong> konfiguriert und Sie greifen von <strong>%s</strong> zu!",
+  "The_user_will_be_removed_from_s" : "Der Benutzer wird von %s entfernt.",
+  "The_user_wont_be_able_to_type_in_s" : "Der Benutzer kann nicht mehr in %s schreiben.",
+  "There_are_no_integrations" : "Es sind keine Integrationen vorhanden.",
+  "This_is_a_push_test_messsage" : "Dies ist eine Test-Push-Nachricht.",
+  "True" : "Ja",
+  "Type_your_new_password" : "Geben Sie Ihr neues Passwort ein",
+  "Unarchive" : "Wiederherstellen",
+  "Unmute_user" : "Benutzern das Chatten erlauben ",
   "Unnamed" : "Unbenannt",
-  "Upload_file_question" : "Datei hochladen?",
-  "Use_Emojis" : "Verwende Emojis",
-  "Use_initials_avatar" : "Benutze deine Initialien",
-  "use_menu" : "Benutze das Seitenmenü um deine Chats zu öffnen",
-  "Use_service_avatar" : "Benutze %s avatar",
+  "Unread_Rooms" : "Ungelesene Räume",
+  "Unread_Rooms_Mode" : "Ungelesene Räume aufgelistet anzeigen ",
+  "Upload_file_question" : "Möchten Sie eine Datei hochladen?",
+  "Uploading_file" : "Datei wird hochgeladen...",
+  "Use_Emojis" : "Emojis verwenden",
+  "Use_initials_avatar" : "Anfangsbuchstaben deines Nutzernamens verwenden",
+  "use_menu" : "Benutze das Seitenmenü, um deine Chats zu öffnen.",
+  "Use_service_avatar" : "Benutze %s Profilbild",
   "Use_this_username" : "Benutzen Sie folgenden Benutzernamen",
-  "Use_uploaded_avatar" : "Benutze diesen Avatar",
-  "User_added_by" : "Benutzer <em>__user_added__</em> hinzugefügt von <em>__user_by__</em>.",
-  "User_Channels" : "Benutzer Kanäle",
-  "User_has_been_activated" : "Benutzer wurde aktiviert",
-  "User_has_been_deactivated" : "Benutzer wurde deaktiviert",
-  "User_has_been_deleted" : "Benutzer wurde gelöscht",
-  "User_Info" : "Benutzer-Info",
-  "User_is_no_longer_an_admin" : "Der Benutzer ist kein Admin mehr",
-  "User_is_not_activated" : "Benutzer ist nicht aktiviert",
-  "User_is_now_an_admin" : "Benutzer ist jetzt ein Admin",
+  "Use_uploaded_avatar" : "Das hochgeladene Profilbild verwenden",
+  "Use_url_for_avatar" : "URL für Profilbild verwenden",
+  "User__username__is_now_a_moderator_of__room_name_" : "Der Benuzer __username__ ist jetzt ein Moderator des Raums __room_name__.",
+  "User__username__is_now_a_owner_of__room_name_" : "Benutzer __username__ ist jetzt ein Besitzer von __room_name__",
+  "User__username__removed_from__room_name__moderators" : "Der Benutzer __username__ wurde von einem Moderator aus __room_name__ entfernt.",
+  "User__username__removed_from__room_name__owners" : "Benutzer __username__ wurde als Besitzer von __room_name__ entfernt.",
+  "User__username__was_added_as_a_moderator_by__user_by_" : "Der Benuzer <em>__username__</em> wurde von <em>__user_by__</em> als Moderator hinzugefügt.",
+  "User__username__was_added_as_a_owner_by__user_by_" : "Benutzer <em>__username__</em> wurde von <em>__user_by__</em> als Besitzer hinzugefügt.",
+  "User__username__was_removed_as_a_moderator_by__user_by_" : "Dem Benutzer <em>__username__</em> wurden die Moderatorenrechte von <em>__user_by__</em> entfernt.",
+  "User__username__was_removed_as_a_owner_by__user_by_" : "Benutzer <em>__username__</em> wurde von <em>__user_by__</em> als Besitzer entfernt.",
+  "User_added_by" : "Der Benutzer <em>__user_added__</em> wurde von <em>__user_by__</em> hinzugefügt.",
+  "User_Channels" : "Benutzerkanäle",
+  "User_has_been_activated" : "Der Benutzer wurde aktiviert.",
+  "User_has_been_deactivated" : "Der Benutzer wurde deaktiviert.",
+  "User_has_been_deleted" : "Der Benutzer wurde gelöscht.",
+  "User_has_been_muted_in_s" : "Dem Nutzer wurde das Schreiben in %s verboten.",
+  "User_has_been_removed_from_s" : "Der Benutzer wurde von %s entfernt.",
+  "User_Info" : "Benutzerinformationen",
+  "User_is_no_longer_an_admin" : "Der Benutzer ist kein Admin mehr.",
+  "User_is_not_activated" : "Der Benutzer ist nicht aktiviert.",
+  "User_is_now_an_admin" : "Der Benutzer ist jetzt ein Admin.",
   "User_joined_channel" : "Ist dem Kanal beigetreten.",
   "User_joined_channel_female" : "Ist dem Kanal beigetreten.",
   "User_joined_channel_male" : "Ist dem Kanal beigetreten.",
-  "User_left" : "Benutzer <em>__user_left__</em> ist gegangen.",
-  "User_left_female" : "Benutzer <em>__user_left__</em> ist gegangen.",
-  "User_left_male" : "Benutzer <em>__user_left__</em> ist gegangen.",
-  "User_logged_out" : "Benutzer ausgeloggt",
-  "User_not_found_or_incorrect_password" : "Benutzer nicht gefunden oder falsches Passwort",
-  "User_removed_by" : "Benutzer <em>__user_removed__</em> entfernt von <em>__user_by__</em>.",
+  "User_left" : "Der Benutzer <em>__user_left__</em> hat den Kanal verlassen.",
+  "User_left_female" : "Der Benutzer <em>__user_left__</em> hat den Kanal verlassen.",
+  "User_left_male" : "Der Benutzer <em>__user_left__</em> hat den Kanal verlassen.",
+  "User_logged_out" : "Der Benutzer wurde abgemeldet.",
+  "User_muted_by" : "Dem Benutzer <em>__user_muted__</em> wurde das Chatten von <em>__user_by__</em> verboten.",
+  "User_muted_in_room" : "Dem Benutzer wurde das Chatten verboten.",
+  "User_not_found_or_incorrect_password" : "Entweder konnte der Benutzer nicht gefunden werden oder Sie haben ein falsches Passwort angegeben.",
+  "User_or_channel_name" : "Benutzer- oder Kanalname",
+  "User_removed_by" : "Der Benutzer <em>__user_removed__</em> wurde von <em>__user_by__</em> entfernt.",
+  "User_removed_from_room" : "Der Benutzer wurde aus dem Raum entfernt.",
   "User_Settings" : "Benutzereinstellungen",
-  "User_updated_successfully" : "Benutzer erfolgreich aktualisiert",
+  "User_unmuted_by" : "Dem Benutzer <em>__user_unmuted__</em> wurde das Chatten von <em>__user_by__</em> wieder erlaubt. ",
+  "User_unmuted_in_room" : "Dem Benutzer wurde das Chatten wieder erlaubt.",
+  "User_updated_successfully" : "Der Benutzer wurde erfolgreich aktualisiert.",
   "Username" : "Benutzername",
-  "Username_cant_be_empty" : "Der Benutzername darf nicht leer sein",
-  "Username_Change_Disabled" : "Der Administrator hat das Ändern des Benutzernamens nicht erlaubt",
-  "Username_description" : "Der Benutzername wird dazu benutzt Sie in Nachtichten zu markieren.",
-  "Username_invalid" : "<strong>%s</strong> ist kein zulässiger Username.<br/> Benutze nur Buchstaben, Nummern, Punkte oder Bindestriche.",
+  "Username_cant_be_empty" : "Sie müssen einen Benutzernamen angeben.",
+  "Username_Change_Disabled" : "Der Administrator hat das Ändern von Benutzernamen deaktiviert.",
+  "Username_description" : "Der Benutzername wird dazu benutzt, Sie in Nachtichten zu erwähnen.",
+  "Username_invalid" : "<strong>%s</strong> ist kein zulässiger Benutzername.<br/> Benutzen Sie nur Buchstaben, Nummern, Punkte oder Bindestriche.",
   "Username_title" : "Benutzernamen festlegen",
-  "Username_unavaliable" : "<strong>%s</strong> wird schon verwendet :(",
+  "Username_unavaliable" : "<strong>%s</strong> wird leider schon verwendet. ",
   "Users" : "Benutzer",
+  "UTF8_Names_Slugify" : "UTF8-Namen-Slugify",
+  "UTF8_Names_Validation" : "UTF8-Namen-Verifizierung",
+  "UTF8_Names_Validation_Description" : "Erlauben Sie keine Sonderzeichen und Leerzeichen. Sie können - _ und . verwenden, aber nicht am Ende eines Namens.",
   "View_All" : "Alle ansehen",
-  "Wait_activation_warning" : "Bevor Sie sich einloggen können, muss das Konto von einem Administrator manuell aktiviert werden.",
-  "We_have_sent_password_email" : "Wir haben Ihnen eine Anleitung zum Zurücksetzen des Passworts an Ihre Email-Adresse gesendet. Wenn Sie keine Email erhalten haben versuchen Sie es bitte noch einmal.",
-  "We_have_sent_registration_email" : "Wir haben Ihnen eine Bestätigungs Email gesendet. Wenn Sie keine Email erhalten haben versuchen Sie es bitte noch einmal.",
-  "Welcome" : "Willkommen <em>%s</em>.",
+  "Wait_activation_warning" : "Bevor Sie sich anmelden können, muss das Konto von einem Administrator manuell aktiviert werden.",
+  "We_have_sent_password_email" : "Wir haben Ihnen eine Anleitung zum Zurücksetzen des Passworts an Ihre E-Mail-Adresse gesendet. Wenn Sie keine E-Mail erhalten haben, versuchen Sie es bitte noch einmal.",
+  "We_have_sent_registration_email" : "Wir haben Ihnen eine Bestätigungsmail gesendet. Wenn Sie keine E-Mail erhalten haben, versuchen Sie es bitte noch einmal.",
+  "Welcome" : "Willkommen, <em>%s</em>.",
   "Welcome_to_the" : "Willkommen bei",
+  "will_be_able_to" : "wird in der Lage sein,",
   "With_whom" : "Mit wem?",
-  "Yes_clear_all" : "Ja, alles!",
-  "Yes_delete_it" : "Ja, löschen!",
-  "you_are_in_preview_mode_of" : "Sie sind im Vorschau-Modus des Kanals #<strong>__room_name__</strong>",
-  "You_need_confirm_email" : "Sie müssen Ihre Email bestätigen!",
-  "You_will_not_be_able_to_recover" : "Sie können es nicht wieder rückgängig machen!",
+  "Yes" : "Ja",
+  "Yes_clear_all" : "Ja!",
+  "Yes_delete_it" : "Ja!",
+  "Yes_mute_user" : "Ja, Benutzer stumm schalten!\n",
+  "Yes_remove_user" : "Ja, Nutzer entfernen!",
+  "you_are_in_preview_mode_of" : "Sie befinden sich im Vorschaumodus des Kanals #<strong>__room_name__</strong>.",
+  "You_are_logged_in_as" : "Sie sind angemeldet als",
+  "You_can_change_a_different_avatar_too" : "Sie können das aktuell verwendete Profilbild überschreiben, um von dieser Integration zu veröffentlichen.",
+  "You_can_use_an_emoji_as_avatar" : "Sie können auch einen Emoji als Profilbild verwenden.",
+  "You_have_been_muted" : "Ihnen wurde das Chatten in diesem Raum verboten. ",
+  "You_need_confirm_email" : "Sie müssen Ihre E-Mail-Adresse bestätigen!",
+  "You_need_install_an_extension_to_allow_screen_sharing" : "Sie müssen eine Erweiterung installieren, um eine Bildschirmübertragung zu starten.",
+  "You_should_name_it_to_easily_manage_your_integrations" : "Zur einfachen Verwaltung der Integrationen empfehlen wir, der Integration einen Namen zuzuordnen.",
+  "You_will_not_be_able_to_recover" : "Die Nachricht kann anschließend nicht wiederhergestellt werden.",
   "Your_entry_has_been_deleted" : "Ihr Eintrag wurde gelöscht.",
-  "Your_Open_Source_solution" : "Deine eigene Open Source Chat Lösung"
+  "Your_mail_was_sent_to_s" : "Ihre E-Mail wurde an %s gesendet.",
+  "Your_Open_Source_solution" : "Deine eigene Open-Source-Chat-Lösung.",
+  "Your_push_was_sent_to_s_devices" : "Die Push-Nachricht wurde an %s Geräte gesendet."
 }
\ No newline at end of file
diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json
index 56d73d095a80146eeabbbeed3154170abb4b22d6..7514464264779d7f643f02742bc3f8f6cfaf4153 100644
--- a/i18n/en.i18n.json
+++ b/i18n/en.i18n.json
@@ -2,6 +2,7 @@
   "Access_not_authorized" : "Access not authorized",
   "Access_online_demo" : "Access the online demo",
   "Access_Online_Demo" : "Access the Online Demo",
+  "Access_Token_URL" : "Access Token URL",
   "Accounts" : "Accounts",
   "Accounts_AllowedDomainsList" : "Allowed Domains List",
   "Accounts_AllowedDomainsList_Description" : "Comma-separated list of allowed domains",
@@ -26,6 +27,7 @@
   "Accounts_OAuth_Custom_Enable" : "Enable",
   "Accounts_OAuth_Custom_id" : "Id",
   "Accounts_OAuth_Custom_Identity_Path" : "Identity Path",
+  "Accounts_OAuth_Custom_Login_Style" : "Login Style",
   "Accounts_OAuth_Custom_Secret" : "Secret",
   "Accounts_OAuth_Custom_Token_Path" : "Token Path",
   "Accounts_OAuth_Custom_URL" : "URL",
@@ -61,11 +63,13 @@
   "Accounts_RegistrationForm_SecretURL_Description" : "You must provide a random string that will be added to your registration URL. Example: https://demo.rocket.chat/register/[secret_hash]",
   "Accounts_RegistrationRequired" : "Registration Required",
   "Accounts_RequireNameForSignUp" : "Require Name For Signup",
+  "Accounts_ShowFormLogin" : "Show form-based Login",
   "Activate" : "Activate",
   "Add_custom_oauth" : "Add custom oauth",
   "Add_Members" : "Add Members",
   "Add_users" : "Add users",
   "Administration" : "Administration",
+  "After_OAuth2_authentication_users_will_be_redirected_to_this_URL" : "After OAuth2 authentication, users will be redirected to this URL",
   "Alias" : "Alias",
   "All_channels" : "All channels",
   "Allow_Invalid_SelfSigned_Certs" : "Allow Invalid Self-Signed Certs",
@@ -76,9 +80,15 @@
   "API_Embed" : "Embed",
   "API_EmbedDisabledFor" : "Disable Embed for Users",
   "API_EmbedDisabledFor_Description" : "Comma-separated list of usernames",
+  "Application_added" : "Application added",
+  "Application_Name" : "Application Name",
+  "Application_updated" : "Application updated",
+  "Archive" : "Archive",
   "are_also_typing" : "are also typing",
   "are_typing" : "are typing",
   "Are_you_sure" : "Are you sure?",
+  "Authorization_URL" : "Authorization URL",
+  "Authorize" : "Authorize",
   "Auto_Load_Images" : "Auto Load Images",
   "Avatar_changed_successfully" : "Avatar changed successfully",
   "Avatar_URL" : "Avatar URL",
@@ -89,6 +99,7 @@
   "Away_female" : "Away",
   "away_male" : "away",
   "Away_male" : "Away",
+  "Back_to_applications" : "Back to applications",
   "Back_to_integrations" : "Back to integrations",
   "Back_to_login" : "Back to login",
   "bold" : "bold",
@@ -108,6 +119,8 @@
   "Choose_the_alias_that_will_appear_before_the_username_in_messages" : "Choose the alias that will appear before the username in messages.",
   "Choose_the_username_that_this_integration_will_post_as" : "Choose the username that this integration will post as.",
   "Clear_all_unreads_question" : "Clear all unreads?",
+  "Client_ID" : "Client ID",
+  "Client_Secret" : "Client Secret",
   "close" : "close",
   "coming_soon" : "coming soon",
   "Commands" : "Commands",
@@ -137,7 +150,10 @@
   "Disable_Favorite_Rooms" : "Disable Favorites",
   "Disable_New_Message_Notification" : "Disable New Message Notification",
   "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",
@@ -153,15 +169,20 @@
   "Error_changing_password" : "Error changing password",
   "Error_too_many_requests" : "Error, too many requests. Please slow down. You must wait %s seconds before trying again",
   "Esc_to" : "Esc to",
+  "Example_s" : "Example: <code class=\"inline\">%s</code>",
   "False" : "False",
   "Favorites" : "Favorites",
   "FileUpload" : "File Upload",
   "FileUpload_Enabled" : "File Uploads Enabled",
+  "FileUpload_File_Empty" : "File empty",
   "FileUpload_MaxFileSize" : "Maximum File Upload Size (in bytes)",
   "FileUpload_MediaType_NotAccepted" : "Media Types Not Accepted",
   "FileUpload_MediaTypeWhiteList" : "Accepted Media Types",
   "FileUpload_MediaTypeWhiteListDescription" : "Comma-separated list of media types",
+  "FileUpload_ProtectFiles" : "Protect uploaded files",
+  "FileUpload_ProtectFilesDescription" : "Only authenticated users will have access",
   "Follow_social_profiles" : "Follow our social profiles, fork us on github and share your thoughts about the rocket.chat app on our trello board.",
+  "Force_SSL" : "Force SSL",
   "Forgot_password" : "Forgot your password",
   "Fork_it_on_github" : "Fork it on github",
   "From_Email" : "From Email",
@@ -169,6 +190,7 @@
   "Get_to_know_the_team" : "Get to know the Rocket.Team",
   "github_no_public_email" : "You don't have any email as public email in your GitHub account",
   "Give_a_unique_name_for_the_custom_oauth" : "Give a unique name for the custom oauth",
+  "Give_the_application_a_name_This_will_be_seen_by_your_users" : "Give the application a name. This will be seen by your users.",
   "Has_more" : "Has more",
   "Have_your_own_chat" : "Have your own web chat. Developed with Meteor.com, the Rocket.Chat is a great solution for developers looking forward to build and evolve their own chat platform.",
   "Hide_room" : "Hide room",
@@ -181,8 +203,10 @@
   "Install_FxOs_done" : "Great! You can now use Rocket.Chat via the icon on your homescreen. Have fun with Rocket.Chat!",
   "Install_FxOs_error" : "Sorry, that did not work as intended! The following error appeared:",
   "Install_FxOs_follow_instructions" : "Please confirm the app installation on your device (press \"Install\" when prompted).",
+  "Integration_added" : "Integration has been added",
   "Integration_Incoming_WebHook" : "Incoming WebHook Integration",
   "Integration_New" : "New Integration",
+  "Integration_updated" : "Integration has been updated",
   "Integrations" : "Integrations",
   "Invalid_asset" : "Invalid asset",
   "Invalid_confirm_pass" : "The password confirmation does not match password",
@@ -193,6 +217,7 @@
   "Invalid_name" : "The name must not be empty",
   "Invalid_pass" : "The password must not be empty",
   "Invalid_room_name" : "<strong>%s</strong> is not a valid room name,<br/> use only letters, numbers and dashes",
+  "Invalid_room_type" : "<strong>%s</strong> is not a valid room type.",
   "Invalid_Secret_URL" : "Invalid Secret URL",
   "Invalid_secret_URL_message" : "The URL provided is invalid.",
   "invisible" : "invisible",
@@ -208,7 +233,12 @@
   "is_typing_male" : "is typing",
   "italics" : "italics",
   "join" : "Join",
+  "Join_audio_call" : "Join audio call",
   "Join_the_Community" : "Join the Community",
+  "Join_video_call" : "Join video call",
+  "Jump_to_first_unread" : "Jump to first unread",
+  "Jump_to_message" : "Jump to message",
+  "Jump_to_recent_messages" : "Jump to recent messages",
   "Language" : "Language",
   "Language_Version" : "English Version",
   "Last_login" : "Last login",
@@ -225,6 +255,7 @@
   "LDAP" : "LDAP",
   "LDAP_Bind_Search" : "Bind Search",
   "LDAP_Bind_Search_Description" : "A piece of JSON that governs bind and connection info and is of the form {\"filter\": \"(&(objectCategory=person)(objectclass=user)(memberOf=CN=ROCKET_ACCESS,CN=Users,DC=domain,DC=com)(sAMAccountName=#{username}))\", \"scope\": \"sub\", \"userDN\": \"rocket.service@domain.com\", \"password\": \"urpass\"}",
+  "LDAP_CA_Cert" : "CA Cert",
   "LDAP_Description" : "LDAP is a hierarchical database that many companies use to provide single sign on - a facility for sharing one password between multiple sites and services. For advanced configuration information and examples, please consult our wiki: https://github.com/RocketChat/Rocket.Chat/wiki/LDAP-Authentication.",
   "LDAP_DN" : "Distinguished Name (DN)",
   "LDAP_DN_Description" : "Search root; example: dc=domain,dc=com",
@@ -232,10 +263,12 @@
   "LDAP_Enable_Description" : "Attempt to utilize LDAP for authentication.",
   "LDAP_Port" : "LDAP Port",
   "LDAP_Port_Description" : "Port to access LDAP on; eg: 389",
+  "LDAP_Reject_Unauthorized" : "Reject Unauthorized",
   "LDAP_Sync_User_Data" : "Sync Data",
   "LDAP_Sync_User_Data_Description" : "Keep user data in sync with server on login (eg: name, email).",
   "LDAP_Sync_User_Data_FieldMap" : "User Data Field Map",
   "LDAP_Sync_User_Data_FieldMap_Description" : "Configure how user account fields (like email) are populated from a record in LDAP (once found). As an example, {\"cn\":\"name\", \"mail\":\"email\"} will choose a person's human readable name from the cn attribute, and their email from the mail attribute. Available fields include name, and email.",
+  "LDAP_TLS" : "TLS",
   "LDAP_Url" : "LDAP URL",
   "LDAP_Url_Description" : "URL of the LDAP server; example: ldap://company.dns.com",
   "Leave_room" : "Leave room",
@@ -244,10 +277,12 @@
   "Loading..." : "Loading...",
   "Loading_more_from_history" : "Loading more from history",
   "Loading_suggestion" : "Loading suggestions...",
+  "Logged_out_of_other_clients_successfully" : "Logged out of other clients successfully",
   "Login" : "Login",
   "Login_with" : "Login with %s",
   "login_with" : "Or login directly with",
   "Logout" : "Logout",
+  "Logout_Others" : "Logout From Other Logged In Locations",
   "Make_Admin" : "Make Admin",
   "Mark_as_read" : "Mark as read",
   "Markdown_Headers" : "Markdown Headers",
@@ -264,6 +299,8 @@
   "Message_deleting_not_allowed" : "Message deleting not allowed",
   "Message_editing_blocked" : "This message cannot be edited anymore",
   "Message_editing_not_allowed" : "Message editing not allowed",
+  "Message_GroupingPeriod" : "Grouping Period (in seconds)",
+  "Message_GroupingPeriodDescription" : "Messages will be grouped with previous message if both are from the same user and the elapsed time was less than the informed time in seconds.",
   "Message_KeepHistory" : "Keep Message History",
   "Message_MaxAllowedSize" : "Maximum Allowed Message Size",
   "Message_pinned" : "Message pinned",
@@ -286,11 +323,14 @@
   "More_unreads" : "More unreads",
   "Msgs" : "Msgs",
   "multi" : "multi",
+  "Mute_user" : "Mute user",
+  "Muted" : "Muted",
   "My_Account" : "My Account",
   "n_messages" : "%s messages",
   "Name" : "Name",
   "Name_cant_be_empty" : "Name can't be empty",
   "Name_optional" : "Name (optional)",
+  "New_Application" : "New Application",
   "New_integration" : "New integration",
   "New_messages" : "New messages",
   "New_password" : "New password",
@@ -302,6 +342,7 @@
   "No_groups_yet" : "You have no private groups yet.",
   "No_livechats" : "You have no livechats.",
   "No_permission_to_view_room" : "You don't have permission to view this room",
+  "No_results_found" : "No results found",
   "no_tokens_for_this_user" : "There are no tokens for this user",
   "No_user_with_username_%s_was_found" : "No user with username <strong>\"%s\"</strong> was found!",
   "Not_allowed" : "Not allowed",
@@ -309,6 +350,8 @@
   "Not_found_or_not_allowed" : "Not Found or Not Allowed",
   "Nothing_found" : "Nothing found",
   "Notify_all_in_this_room" : "Notify all in this room",
+  "OAuth_Application" : "OAuth Application",
+  "OAuth_Applications" : "OAuth Applications",
   "Old_and_new_password_required" : "You need to provide both old and new password for changing your password.",
   "Old_Password" : "Old Password",
   "Online" : "Online",
@@ -323,6 +366,7 @@
   "Password_changed_successfully" : "Password changed successfully",
   "People" : "People",
   "Please_enter_value_for_url" : "Please enter a value for the url of your avatar.",
+  "Please_enter_your_new_password_below" : "Please enter your new password below:",
   "Please_wait" : "Please wait",
   "Please_wait_activation" : "Please wait, this can take some time.",
   "Please_wait_statistics" : "Please wait, statistics are being generated.",
@@ -358,20 +402,29 @@
   "quote" : "quote",
   "Recents" : "Recents",
   "Record" : "Record",
+  "Redirect_URI" : "Redirect URI",
   "Refresh_your_page_after_install_to_enable_screen_sharing" : "Refresh your page after install to enable screen sharing",
   "Register" : "Register a new account",
   "Registration_Succeeded" : "Registration Succeeded",
   "Remember_me" : "Remember me",
   "Remove" : "Remove",
   "Remove_Admin" : "Remove Admin",
+  "Remove_as_moderator" : "Remove as moderator",
+  "Remove_as_owner" : "Remove as owner",
   "Remove_custom_oauth" : "Remove custom oauth",
+  "Remove_from_room" : "Remove from room",
+  "Removed" : "Removed",
+  "Reset" : "Reset",
   "Reset_password" : "Reset password",
   "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",
@@ -397,6 +450,7 @@
   "Select_service_to_login" : "Select a service to login to load your picture or upload one directly from your computer",
   "Selected_users" : "Selected members",
   "Send" : "Send",
+  "Send_a_test_mail_to_my_user" : "Send a test mail to my user",
   "Send_a_test_push_to_my_user" : "Send a test push to my user",
   "Send_confirmation_email" : "Send confirmation email",
   "Send_data_into_RocketChat_in_realtime" : "Send data into Rocket.Chat in real-time.",
@@ -407,10 +461,13 @@
   "Send_invitation_email_warning" : "In order to send invitation e-mails, you must first configure SMTP settings.",
   "Send_Message" : "Send Message",
   "Send_your_JSON_payloads_to_this_URL" : "Send your JSON payloads to this URL.",
+  "Set_as_moderator" : "Set as moderator",
+  "Set_as_owner" : "Set as owner",
   "Settings" : "Settings",
   "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" : "Should exists a user with this username.",
+  "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",
@@ -422,9 +479,12 @@
   "SMTP_Host" : "SMTP Host",
   "SMTP_Password" : "SMTP Password",
   "SMTP_Port" : "SMTP Port",
+  "SMTP_Test_Button" : "Test SMTP Settings",
   "SMTP_Username" : "SMTP Username",
   "Sound" : "Sound",
+  "Start_audio_call" : "Start audio call",
   "Start_of_conversation" : "Start of conversation",
+  "Start_video_call" : "Start video call",
   "Start_with_s_for_user_or_s_for_channel_Eg_s_or_s" : "Start with <code class=\"inline\">%s</code> for user or <code class=\"inline\">%s</code> for channel. Eg: <code class=\"inline\">%s</code> or <code class=\"inline\">%s</code>",
   "Statistics" : "Statistics",
   "Stats_Active_Users" : "Active Users",
@@ -454,12 +514,21 @@
   "strike" : "strike",
   "Submit" : "Submit",
   "Success" : "Success",
-  "The_configured_URL_is_different_from_the_URL_you_are_accessing" : "The configured URL is different from the URL you are accessing!",
+  "The_application_name_is_required" : "Th _application name is required",
+  "The_channel_name_is_required" : "The channel name is required",
   "The_field_is_required" : "The field %s is required.",
+  "The_image_resize_will_not_work_because_we_can_not_detect_ImageMagick_or_GraphicsMagick_installed_in_your_server" : "The image resize will not work because we can not detect ImageMagick or GraphicsMagick installed on your server.",
+  "The_redirectUri_is_required" : "The redirectUri is required",
   "The_server_will_restart_in_s_seconds" : "The server will restart in %s seconds",
-  "There_is_no_integrations" : "There is no integrations",
+  "The_setting_s_is_configured_to_s_and_you_are_accessing_from_s" : "The setting <strong>%s</strong> is configured to <strong>%s</strong> and you are accessing from <strong>%s</strong>!",
+  "The_user_will_be_removed_from_s" : "The user will be removed from %s",
+  "The_user_wont_be_able_to_type_in_s" : "The user won't be able to type in %s",
+  "There_are_no_integrations" : "There are no integrations",
   "This_is_a_push_test_messsage" : "This is a push test messsage",
   "True" : "True",
+  "Type_your_new_password" : "Type your new password",
+  "Unarchive" : "Unarchive",
+  "Unmute_user" : "Unmute user",
   "Unnamed" : "Unnamed",
   "Unread_Rooms" : "Unread Rooms",
   "Unread_Rooms_Mode" : "Unread Rooms Mode",
@@ -472,11 +541,21 @@
   "Use_this_username" : "Use this username",
   "Use_uploaded_avatar" : "Use uploaded avatar",
   "Use_url_for_avatar" : "Use url for avatar",
+  "User__username__is_now_a_moderator_of__room_name_" : "User __username__ is now a moderator of __room_name__",
+  "User__username__is_now_a_owner_of__room_name_" : "User __username__ is now a owner of __room_name__",
+  "User__username__removed_from__room_name__moderators" : "User __username__ removed from __room_name__ moderators",
+  "User__username__removed_from__room_name__owners" : "User __username__ removed from __room_name__ owners",
+  "User__username__was_added_as_a_moderator_by__user_by_" : "User <em>__username__</em> was added as a moderator by <em>__user_by__</em>",
+  "User__username__was_added_as_a_owner_by__user_by_" : "User <em>__username__</em> was added as a owner by <em>__user_by__</em>",
+  "User__username__was_removed_as_a_moderator_by__user_by_" : "User <em>__username__</em> was removed as a moderator by <em>__user_by__</em>",
+  "User__username__was_removed_as_a_owner_by__user_by_" : "User <em>__username__</em> was removed as a owner by <em>__user_by__</em>",
   "User_added_by" : "User <em>__user_added__</em> added by <em>__user_by__</em>.",
   "User_Channels" : "User Channels",
   "User_has_been_activated" : "User has been activated",
   "User_has_been_deactivated" : "User has been deactivated",
   "User_has_been_deleted" : "User has been deleted",
+  "User_has_been_muted_in_s" : "User has been muted in %s",
+  "User_has_been_removed_from_s" : "User has been removed from %s",
   "User_Info" : "User Info",
   "User_is_no_longer_an_admin" : "User is no longer an admin",
   "User_is_not_activated" : "User is not activated",
@@ -488,10 +567,15 @@
   "User_left_female" : "Has left the channel.",
   "User_left_male" : "Has left the channel.",
   "User_logged_out" : "User is logged out",
+  "User_muted_by" : "User <em>__user_muted__</em> muted by <em>__user_by__</em>.",
+  "User_muted_in_room" : "User muted in room",
   "User_not_found_or_incorrect_password" : "User not found or incorrect password",
   "User_or_channel_name" : "User or channel name",
   "User_removed_by" : "User <em>__user_removed__</em> removed by <em>__user_by__</em>.",
+  "User_removed_from_room" : "The user has been removed from the room",
   "User_Settings" : "User Settings",
+  "User_unmuted_by" : "User <em>__user_unmuted__</em> unmuted by <em>__user_by__</em>.",
+  "User_unmuted_in_room" : "User unmuted in room",
   "User_updated_successfully" : "User updated successfully",
   "Username" : "Username",
   "Username_cant_be_empty" : "The username cannot be empty",
@@ -510,17 +594,24 @@
   "We_have_sent_registration_email" : "We have sent you an e-mail to confirm your registration. If you do not receive an e-mail shortly, please come back and try again.",
   "Welcome" : "Welcome <em>%s</em>.",
   "Welcome_to_the" : "Welcome to the",
+  "will_be_able_to" : "will be able to",
   "With_whom" : "With whom",
   "Yes" : "Yes",
   "Yes_clear_all" : "Yes, clear all!",
   "Yes_delete_it" : "Yes, delete it!",
+  "Yes_mute_user" : "Yes, mute user!",
+  "Yes_remove_user" : "Yes, remove user!",
   "you_are_in_preview_mode_of" : "You are in preview mode of channel #<strong>__room_name__</strong>",
-  "You_can_change_a_different_avatar_too" : "You can change a different avatar too",
+  "You_are_logged_in_as" : "You are logged in as",
+  "You_can_change_a_different_avatar_too" : "You can override the avatar used to post from this integration.",
+  "You_can_use_an_emoji_as_avatar" : "You can also use an emoji as an avatar.",
+  "You_have_been_muted" : "You have been muted and cannot speak in this room",
   "You_need_confirm_email" : "You need to confirm your email to login!",
   "You_need_install_an_extension_to_allow_screen_sharing" : "You need install an extension to allow screen sharing",
   "You_should_name_it_to_easily_manage_your_integrations" : "You should name it to easily manage your integrations.",
   "You_will_not_be_able_to_recover" : "You will not be able to recover this message!",
   "Your_entry_has_been_deleted" : "Your entry has been deleted.",
+  "Your_mail_was_sent_to_s" : "Your mail was sent to %s",
   "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/i18n/fi.i18n.json b/i18n/fi.i18n.json
index 01f48d5c754a8cc4a658adf85437fb89ffccdad6..83fdccc6647fb7e9146c4512e0fbc8573998d776 100644
--- a/i18n/fi.i18n.json
+++ b/i18n/fi.i18n.json
@@ -2,6 +2,7 @@
   "Access_not_authorized" : "Pääsy estetty.",
   "Access_online_demo" : "Access the online demo",
   "Access_Online_Demo" : "Access the Online Demo",
+  "Access_Token_URL" : "Access Token URL",
   "Accounts" : "Käyttäjätilit",
   "Accounts_AllowedDomainsList" : "Pilkkueroteltu lista sallituista domaineista",
   "Accounts_AllowedDomainsList_Description" : "Pilkuilla eroteltu luettelo sallituista verkkotunnuksia",
@@ -17,6 +18,7 @@
   "Accounts_EmailVerification" : "Sähköpostiosoitteen varmistaminen",
   "Accounts_Enrollment_Email" : "Kirjautumissähköposti",
   "Accounts_Enrollment_Email_Description" : "Voit käyttää [name], [fname], [lname] käyttäjän koko nimen, etunimen tai sukunimen paikalla.<br />Voit käyttää [email] käyttäjän sähköpostin paikalla.",
+  "Accounts_LoginExpiration" : "Kirjautumisen vanhentumisaika (päiviä)",
   "Accounts_ManuallyApproveNewUsers" : "Hyväksy uudet käyttäjät manuaalisesti",
   "Accounts_OAuth_Custom_Authorize_Path" : "Auktorisointipolku",
   "Accounts_OAuth_Custom_Button_Color" : "Painikkeen väri",
@@ -25,6 +27,7 @@
   "Accounts_OAuth_Custom_Enable" : "Kytke päälle",
   "Accounts_OAuth_Custom_id" : "Id",
   "Accounts_OAuth_Custom_Identity_Path" : "Identity polku",
+  "Accounts_OAuth_Custom_Login_Style" : "Kirjautumistyyli",
   "Accounts_OAuth_Custom_Secret" : "Secret",
   "Accounts_OAuth_Custom_Token_Path" : "Token polku",
   "Accounts_OAuth_Custom_URL" : "URL",
@@ -60,11 +63,13 @@
   "Accounts_RegistrationForm_SecretURL_Description" : "Sinun on annettava satunnainen merkkijono, joka lisätään rekisteröitymis-URLiin. Esimerkiksi: https://chat.example.com/register/[secret_hash]",
   "Accounts_RegistrationRequired" : "Rekisteröinti vaaditaan",
   "Accounts_RequireNameForSignUp" : "Vaadi nimi rekisteröityessä",
+  "Accounts_ShowFormLogin" : "Näytä lomakepohjainen kirjautuminen",
   "Activate" : "Aktivoi",
   "Add_custom_oauth" : "Lisää mukautettu oauth",
   "Add_Members" : "Lisää osallistujia",
   "Add_users" : "Lisää käyttäjiä",
   "Administration" : "Ylläpito",
+  "After_OAuth2_authentication_users_will_be_redirected_to_this_URL" : "OAuth2-todennuksen jälkeen käyttäjät ohjataan tähän URL-osoitteeseen",
   "Alias" : "Alias",
   "All_channels" : "Kaikki kanavat",
   "Allow_Invalid_SelfSigned_Certs" : "Salli virheelliset ja itse allekirjoitetut SSL varmenteet linkin validointiin ja esikatseluihin",
@@ -75,9 +80,15 @@
   "API_Embed" : "Upota",
   "API_EmbedDisabledFor" : "Poista upotustoiminto käyttäjiltä",
   "API_EmbedDisabledFor_Description" : "Pilkkueroteltu lista käyttäjätunnuksista",
+  "Application_added" : "Sovellus lisätty",
+  "Application_Name" : "Sovelluksen nimi",
+  "Application_updated" : "Sovellus päivitetty",
+  "Archive" : "Arkistoi",
   "are_also_typing" : "kirjoittavat myös",
   "are_typing" : "kirjoittavat",
   "Are_you_sure" : "Oletko varma?",
+  "Authorization_URL" : "Valtuutus URL",
+  "Authorize" : "Valtuuta",
   "Auto_Load_Images" : "Lataa kuvat automaattisesti\n",
   "Avatar_changed_successfully" : "Avatar vaihdettu onnistuneesti",
   "Avatar_URL" : "Avatarin URL",
@@ -88,6 +99,7 @@
   "Away_female" : "Poissa",
   "away_male" : "poissa",
   "Away_male" : "Poissa",
+  "Back_to_applications" : "Takaisin sovelluksiin",
   "Back_to_integrations" : "Takaisin integraatioihin",
   "Back_to_login" : "Takaisin kirjautumiseen",
   "bold" : "lihavoitu",
@@ -107,6 +119,8 @@
   "Choose_the_alias_that_will_appear_before_the_username_in_messages" : "Valitse alias, joka näkyy viesteissä ennen käyttäjätunnustasi",
   "Choose_the_username_that_this_integration_will_post_as" : "Valitse käyttäjänimi, jolla integraatio postaa keskusteluun",
   "Clear_all_unreads_question" : "Tyhjennä kaikki lukemattomat?",
+  "Client_ID" : "Client ID",
+  "Client_Secret" : "Client Secret",
   "close" : "sulje",
   "coming_soon" : "tulossa",
   "Commands" : "Komennot",
@@ -136,7 +150,10 @@
   "Disable_Favorite_Rooms" : "Poista Suosikit käytöstä",
   "Disable_New_Message_Notification" : "Poista uuden viestin ilmoitus käytöstä",
   "Disable_New_Room_Notification" : "Poista uuden huoneen ilmoitus käytöstä",
+  "Do_you_want_to_change_to_s_question" : "Haluatko vaihtaa tämän arvoon <strong>%s</strong>?",
   "Drop_to_upload_file" : "Vedä ja pudota lähettääksesi tiedoston",
+  "Duplicate_archived_channel_name" : "Arkistoitu kanava nimellä '%s' on olemassa",
+  "Duplicate_archived_private_group_name" : "Arkistoitu privaattiryhmä '%s%' on olemassa",
   "Duplicate_channel_name" : "Kanava nimeltä '%s' on olemassa jo",
   "Duplicate_private_group_name" : "Privaattiryhmä '%s' on olemassa jo",
   "E-mail" : "Sähköpostiosoite",
@@ -152,14 +169,18 @@
   "Error_changing_password" : "Virhe vaihtaessa salasanaa",
   "Error_too_many_requests" : "Virhe, liikaa pyyntöjä. Rauhoitu hieman.\nOdota %s sekuntia ennen uudelleenyritystä.",
   "Esc_to" : "Poistu",
+  "Example_s" : "Esimerkiksi: <code class=\"inline\">%s</code>",
   "False" : "Ei",
   "Favorites" : "Suosikit",
   "FileUpload" : "Lähetä tiedosto",
   "FileUpload_Enabled" : "Tiedostojen lähetykset käytössä",
+  "FileUpload_File_Empty" : "Tiedosto tyhjä",
   "FileUpload_MaxFileSize" : "Suurin lähetettävän tiedoston koko (tavuina)",
   "FileUpload_MediaType_NotAccepted" : "Mediatyyppejä ei hyväksytä",
   "FileUpload_MediaTypeWhiteList" : "Hyväksytyt mediatyypit",
   "FileUpload_MediaTypeWhiteListDescription" : "Pilkkueroteltu lista mediatyypeistä",
+  "FileUpload_ProtectFiles" : "Suojaa ladatut tiedostot",
+  "FileUpload_ProtectFilesDescription" : "Vain kirjautuneilla käyttäjillä on pääsy tiedostoihin",
   "Follow_social_profiles" : "Seuraa someamme, forkkaa Githubissa ja jaa ajatuksiasi rocket.chatista trellossa.",
   "Forgot_password" : "Unohditko salasanasi?",
   "Fork_it_on_github" : "Forkkaa GitHubissa",
@@ -168,6 +189,7 @@
   "Get_to_know_the_team" : "Tutustu Rocket.Teamiin",
   "github_no_public_email" : "GitHub-tunnukseltasi ei löydy julkisia sähköpostiosoitetietoja",
   "Give_a_unique_name_for_the_custom_oauth" : "Anna yksilöllinen nimi mukautettua oauth varten",
+  "Give_the_application_a_name_This_will_be_seen_by_your_users" : "Anna sovelluksen nimi. Käyttäjät näkevät tämän.",
   "Has_more" : "Löytyy lisää",
   "Have_your_own_chat" : "Have your own web chat. Developed with Meteor.com, the Rocket.Chat is a great solution for developers looking forward to build and evolve their own chat platform.",
   "Hide_room" : "Piilota kanava",
@@ -180,8 +202,10 @@
   "Install_FxOs_done" : "Hienoa! Voit käyttää nyt Rocket.Chatiä etusivulla olevan kuvakkeen kautta. Pidä kivaa!",
   "Install_FxOs_error" : "Pahoittelut, asennus ei onnistunut, seuraava virhe ilmeni:",
   "Install_FxOs_follow_instructions" : "Vahvista sovelluksen asennus laitteellasi (paina \"Install\" käskettäessä)",
+  "Integration_added" : "Integraatio lisätty",
   "Integration_Incoming_WebHook" : "Sisääntuleva WebHook-integraatio",
   "Integration_New" : "Uusi integraatio",
+  "Integration_updated" : "Integraatio päivitetty",
   "Integrations" : "Integraatiot",
   "Invalid_asset" : "Virheellinen resurssi",
   "Invalid_confirm_pass" : "Salasanat eivät täsmää",
@@ -192,6 +216,7 @@
   "Invalid_name" : "Nimi ei voi olla tyhjä",
   "Invalid_pass" : "Salasana ei voi olla tyhjä",
   "Invalid_room_name" : "<strong>%s</strong> ei ole hyväksyttävä kanavan nimi,<br/> käytä vain kirjaimia, numeroita ja viivaa",
+  "Invalid_room_type" : "<strong>%s</strong> ei ole sallittu huoneen tyyppi.",
   "Invalid_Secret_URL" : "Virheellinen salainen URL",
   "Invalid_secret_URL_message" : "URL on virheellinen.",
   "invisible" : "näkymätön",
@@ -207,7 +232,12 @@
   "is_typing_male" : "kirjoittaa",
   "italics" : "kursivoitu",
   "join" : "Liity",
+  "Join_audio_call" : "Liity äänipuheluun",
   "Join_the_Community" : "Liity yhteisöön",
+  "Join_video_call" : "Liity videopuheluun",
+  "Jump_to_first_unread" : "Siirry ensimmäiseen lukemattomaan",
+  "Jump_to_message" : "Siirry viestiin",
+  "Jump_to_recent_messages" : "Siirry viimeisimpiin viestiin",
   "Language" : "Kieli",
   "Language_Version" : "Suomi",
   "Last_login" : "Viimeisin kirjautuminen",
@@ -243,10 +273,12 @@
   "Loading..." : "Ladataan...",
   "Loading_more_from_history" : "Ladataan lisää historiasta",
   "Loading_suggestion" : "Ladataan ehdotuksia...",
+  "Logged_out_of_other_clients_successfully" : "Muut sessiot kirjattu ulos onnistuneesti",
   "Login" : "Kirjaudu",
   "Login_with" : "Kirjaudu käyttäen %s",
   "login_with" : "tai kirjaudu suoraan",
   "Logout" : "Kirjaudu ulos",
+  "Logout_Others" : "Kirjaa ulos muut sessiot",
   "Make_Admin" : "Tee ylläpitäjäksi",
   "Mark_as_read" : "Merkitse luetuksi",
   "Markdown_Headers" : "Markdown otsikot",
@@ -263,6 +295,8 @@
   "Message_deleting_not_allowed" : "Viestin poisto ei sallittu",
   "Message_editing_blocked" : "Tätä viestiä ei voi muokata enää.",
   "Message_editing_not_allowed" : "Viestin muokkaus ei sallittu",
+  "Message_GroupingPeriod" : "Ryhmittelyaika (sekunneissa)",
+  "Message_GroupingPeriodDescription" : "Viestit ryhmitellään edellisen viestin kanssa jos molemmat viestit ovat samalta käyttäjältä ja viestien välinen aika on pienempi kuin määritelty aika.",
   "Message_KeepHistory" : "Säilytä viestihistoria",
   "Message_MaxAllowedSize" : "Viestin suurin sallittu koko",
   "Message_pinned" : "Viesti kiinnitetty",
@@ -285,11 +319,14 @@
   "More_unreads" : "Lisää lukemattomia",
   "Msgs" : "Viestit",
   "multi" : "monta",
+  "Mute_user" : "Mykistä käyttäjä",
+  "Muted" : "Mykistetty",
   "My_Account" : "Käyttäjätilini",
   "n_messages" : "%s viestiä",
   "Name" : "Nimi",
   "Name_cant_be_empty" : "Nimi ei voi olla tyhjä",
   "Name_optional" : "Nimi (valinnainen)",
+  "New_Application" : "Uusi sovellus",
   "New_integration" : "Uusi integraatio",
   "New_messages" : "Uusia viestejä",
   "New_password" : "Uusi salasana",
@@ -301,6 +338,7 @@
   "No_groups_yet" : "Sinulla ei ole vielä privaattiryhmiä.",
   "No_livechats" : "Sinulla ei ole livechatteja.",
   "No_permission_to_view_room" : "Sinulla ei ole oikeutta katsella tätä",
+  "No_results_found" : "Ei tuloksia",
   "no_tokens_for_this_user" : "Valtuutusta käyttäjälle ei löydy",
   "No_user_with_username_%s_was_found" : "Käyttäjää nimeltä <strong>\"%s\"</strong> ei löytynyt!",
   "Not_allowed" : "Ei sallittu",
@@ -308,6 +346,8 @@
   "Not_found_or_not_allowed" : "Ei löydy tai ei sallittu",
   "Nothing_found" : "Ei löytynyt",
   "Notify_all_in_this_room" : "Ilmoita kaikille kanavallaolijoille",
+  "OAuth_Application" : "OAuth sovellus",
+  "OAuth_Applications" : "OAuth sovellukset",
   "Old_and_new_password_required" : "Sinun täytyy antaa sekä vanha että uusi salasana, että saat vaihdettua salasanasi.",
   "Old_Password" : "Vanha salasana",
   "Online" : "Online",
@@ -322,6 +362,7 @@
   "Password_changed_successfully" : "Salasana vaihdettu",
   "People" : "Ihmiset",
   "Please_enter_value_for_url" : "Anna avatarisi URL",
+  "Please_enter_your_new_password_below" : "Anna uusi salasana:",
   "Please_wait" : "Odota hetki",
   "Please_wait_activation" : "Odota, tämä voi kestää jonkin aikaa.",
   "Please_wait_statistics" : "Odota, tilastoja generoidaan.",
@@ -357,20 +398,29 @@
   "quote" : "lainaus",
   "Recents" : "Viimeisimmät",
   "Record" : "Nauhoita",
+  "Redirect_URI" : "Ohjaus URI",
   "Refresh_your_page_after_install_to_enable_screen_sharing" : "Päivitä sivu asennuksen jälkeen ottaaksesi käyttöön näytön jakamisen",
   "Register" : "Rekisteröi uusi käyttäjätili",
   "Registration_Succeeded" : "Rekisteröinti onnistui",
   "Remember_me" : "Muista minut",
   "Remove" : "Poista",
   "Remove_Admin" : "Poista ylläpitäjyys",
+  "Remove_as_moderator" : "Poista moderaattoristatus",
+  "Remove_as_owner" : "Poista omistajuus",
   "Remove_custom_oauth" : "Poista mukautettu oauth",
+  "Remove_from_room" : "Poista huoneesta",
+  "Removed" : "Poistettu",
+  "Reset" : "Nollaa",
   "Reset_password" : "Nollaa salasana",
   "Restart" : "Käynnistä uudelleen",
   "Restart_the_server" : "Käynnistä palvelin uudelleen",
   "Room" : "Huone",
+  "Room_archived" : "Huone arkistoitu",
+  "Room_has_been_deleted" : "Huone poistettu",
   "Room_name_changed" : "Huoneen nimi vaihdettu <em>__room_name__</em> <em>__user_by__</em> toimesta",
   "Room_name_changed_successfully" : "Huoneen nimi vaihdettu",
   "Room_not_found" : "Huonetta ei löytynyt",
+  "Room_unarchived" : "Huone palautettu arkistosta",
   "Room_uploaded_file_list" : "Tiedostolista",
   "Room_uploaded_file_list_empty" : "Tiedostoja ei ole saatavilla.",
   "room_user_count" : "%s käyttäjää",
@@ -396,6 +446,7 @@
   "Select_service_to_login" : "Valitse kirjautumiseen käytettävä palvelu tai lataa kuvasi suoraan koneeltasi",
   "Selected_users" : "Valitut käyttäjät",
   "Send" : "Lähetä",
+  "Send_a_test_mail_to_my_user" : "Lähetä testisähköposti käyttäjälle",
   "Send_a_test_push_to_my_user" : "Lähetä testi-push käyttäjälle",
   "Send_confirmation_email" : "Lähetä vahvistussähköposti",
   "Send_data_into_RocketChat_in_realtime" : "Lähetä data Rocket.Chatiin reaaliajassa",
@@ -406,10 +457,13 @@
   "Send_invitation_email_warning" : "Lähettääksesi sähköpostikutsuja, sinun täytyy ensin tehdä SMTP asetukset.",
   "Send_Message" : "Lähetä viesti",
   "Send_your_JSON_payloads_to_this_URL" : "Lähetä JSON payload tähän URL-osoitteeseen",
+  "Set_as_moderator" : "Aseta moderaattoriksi",
+  "Set_as_owner" : "Aseta omistajaksi",
   "Settings" : "Asetukset",
   "Settings_updated" : "Asetukset päivitetty",
   "Should_be_a_URL_of_an_image" : "Kuvan URL-osoite",
   "Should_exists_a_user_with_this_username" : "Käyttäjä tällä käyttäjätunnuksella tulisi olla olemassa",
+  "Showing_archived_results" : "<p>Näytetään <b>%s</b> arkistoitua tulosta</p>",
   "Showing_online_users" : "Näytetään <b>__total_online__</b>/__total__ users",
   "Showing_results" : "<p>Näytetään <b>%s</b> tulosta</p>",
   "Silence" : "Hiljaisuus",
@@ -421,9 +475,12 @@
   "SMTP_Host" : "SMTP-palvelin",
   "SMTP_Password" : "SMTP Salasana",
   "SMTP_Port" : "SMTP-portti",
+  "SMTP_Test_Button" : "Testaa SMTP-asetukset",
   "SMTP_Username" : "SMTP Käyttäjätunnus",
   "Sound" : "Ääni",
+  "Start_audio_call" : "Aloita äänipuhelu",
   "Start_of_conversation" : "Keskustelun alku",
+  "Start_video_call" : "Aloita videopuhelu",
   "Start_with_s_for_user_or_s_for_channel_Eg_s_or_s" : "Aloita <code class=\"inline\">%s</code> käyttäjänä or <code class=\"inline\">%s</code> kanavana. Esim: <code class=\"inline\">%s</code> tai <code class=\"inline\">%s</code>",
   "Statistics" : "Tilastot",
   "Stats_Active_Users" : "Aktiivisia käyttäjiä",
@@ -453,12 +510,21 @@
   "strike" : "yliviivaa",
   "Submit" : "Lähetä",
   "Success" : "Onnistui",
-  "The_configured_URL_is_different_from_the_URL_you_are_accessing" : "Määritetty URL-osoite on eri kuin nyt käytettävä!",
+  "The_application_name_is_required" : "Sovelluksen nimi on pakollinen",
+  "The_channel_name_is_required" : "Kanavan nimi on määriteltävä",
   "The_field_is_required" : "Kenttä %s vaaditaan.",
+  "The_image_resize_will_not_work_because_we_can_not_detect_ImageMagick_or_GraphicsMagick_installed_in_your_server" : "Kuvien koon muuttaminen ei toimi koska ImageMagickia tai GraphicsMagickia ei havaittu asennettuna palvelimelle.",
+  "The_redirectUri_is_required" : "Ohjaus URI on pakollinen",
   "The_server_will_restart_in_s_seconds" : "Palvelin käynnistyy %s sekunnin kuluttua",
-  "There_is_no_integrations" : "Integraatioita ei ole",
+  "The_setting_s_is_configured_to_s_and_you_are_accessing_from_s" : "Asetus <strong>%s</strong> on määritelty arvoon <strong>%s</strong> yrität käyttää tätä lähteenä <strong>%s</strong>!",
+  "The_user_will_be_removed_from_s" : "Käyttäjä poistetaan %s",
+  "The_user_wont_be_able_to_type_in_s" : "Käyttäjä ei pysty kirjoittamaan %s",
+  "There_are_no_integrations" : "Ei integraatioita",
   "This_is_a_push_test_messsage" : "Tämä on testi-pushviesti",
   "True" : "Kyllä",
+  "Type_your_new_password" : "Anna uusi salasana",
+  "Unarchive" : "Palauta arkistosta",
+  "Unmute_user" : "Poista mykistys käyttäjältä",
   "Unnamed" : "Nimetön",
   "Unread_Rooms" : "Lukemattomia",
   "Unread_Rooms_Mode" : "Lukemattomien tila",
@@ -471,11 +537,21 @@
   "Use_this_username" : "Käytä tätä käyttäjänimieä",
   "Use_uploaded_avatar" : "Käytä ladattua avataria",
   "Use_url_for_avatar" : "Käytä avatar-URLia",
+  "User__username__is_now_a_moderator_of__room_name_" : "Käyttäjä __username__ on nyt __room_name__ moderaattori",
+  "User__username__is_now_a_owner_of__room_name_" : "Käyttäjä __username__ on nyt __room_name__ omistaja",
+  "User__username__removed_from__room_name__moderators" : "Käyttäjän __username__ moderaattoristatus __room_name__  on poistettu",
+  "User__username__removed_from__room_name__owners" : "Käyttäjä __username__ poistettu __room_name__ omistajista",
+  "User__username__was_added_as_a_moderator_by__user_by_" : "Käyttäjä <em>__username__</em> on lisätty moderaattoriksi <em>__user_by__</em> toimesta",
+  "User__username__was_added_as_a_owner_by__user_by_" : "Käyttäjä <em>__username__</em> lisätty <em>__user_by__</em> omistajaksi",
+  "User__username__was_removed_as_a_moderator_by__user_by_" : "Käyttäjän <em>__username__</em> moderaattoristatus poistettu käyttäjän  <em>__user_by__</em> toimesta",
+  "User__username__was_removed_as_a_owner_by__user_by_" : "Käyttäjä <em>__username__</em> on poistettu <em>__user_by__</em> omistajista",
   "User_added_by" : "Käyttäjä <em>__user_added__</em> lisätty <em>__user_by__</em> toimesta.",
   "User_Channels" : "Käyttäjän kanavat",
   "User_has_been_activated" : "Käyttäjä on aktivoitu",
   "User_has_been_deactivated" : "Käyttäjä on deaktivoitu",
   "User_has_been_deleted" : "Käyttäjä on poistettu",
+  "User_has_been_muted_in_s" : "Käyttäjä on mykistetty %s",
+  "User_has_been_removed_from_s" : "Käyttäjä on poistettu %s",
   "User_Info" : "Käyttäjän tiedot",
   "User_is_no_longer_an_admin" : "Käyttäjä ei ole enää ylläpitäjä",
   "User_is_not_activated" : "Käyttäjää ei ole aktivoitu",
@@ -487,10 +563,15 @@
   "User_left_female" : "Käyttäjä poistui kanavalta.",
   "User_left_male" : "Käyttäjä poistui kanavalta.",
   "User_logged_out" : "Käyttäjä on kirjautunut ulos",
+  "User_muted_by" : "Käyttäjä <em>__user_muted__</em> mykistetty <em>__user_by__</em> toimesta.",
+  "User_muted_in_room" : "Käyttäjä mykistetty huoneessa",
   "User_not_found_or_incorrect_password" : "Käyttäjää ei löydy tai väärä salasana",
   "User_or_channel_name" : "Käyttäjän tai kanavan nimi",
   "User_removed_by" : "Käyttäjä <em>__user_removed__</em> poistettu <em>__user_by__</em> toimesta.",
+  "User_removed_from_room" : "Käyttäjä on poistettu huoneesta",
   "User_Settings" : "Käyttäjän asetukset",
+  "User_unmuted_by" : "Käyttäjän <em>__user_unmuted__</em> mykistys poistettu <em>__user_by__</em> toimesta.",
+  "User_unmuted_in_room" : "Käyttäjän mykistys poistettu huoneessa",
   "User_updated_successfully" : "Käyttäjän tiedot päivitetty",
   "Username" : "Käyttäjänimi",
   "Username_cant_be_empty" : "Käyttäjänimi ei voi olla tyhjä",
@@ -509,17 +590,24 @@
   "We_have_sent_registration_email" : "Lähetimme rekisteröitymisvahvistuksen sähköpostiisi. Mikäli et saanut sähköpostia, yritä uudelleen.",
   "Welcome" : "Tervetuloa <em>%s</em>.",
   "Welcome_to_the" : "Tervetuloa",
+  "will_be_able_to" : "mahdollistaa",
   "With_whom" : "kanssa",
   "Yes" : "Kyllä",
   "Yes_clear_all" : "Jep, tyhjennä kaikki!",
   "Yes_delete_it" : "Kyllä, poista!",
+  "Yes_mute_user" : "Kyllä, mykistä käyttäjä!",
+  "Yes_remove_user" : "Kyllä, poista käyttäjä!",
   "you_are_in_preview_mode_of" : "Tämä on kanavan #<strong>__room_name__</strong> esikatselutila",
-  "You_can_change_a_different_avatar_too" : "Voit vaihtaa myös toisen avatarin",
+  "You_are_logged_in_as" : "Olet kirjautunut sisään käyttäjänä",
+  "You_can_change_a_different_avatar_too" : "Voit vaihtaa tähän eri avatarin tätä integraatiota varten",
+  "You_can_use_an_emoji_as_avatar" : "Voit käyttää myös emojia avatarina.",
+  "You_have_been_muted" : "Olet mykistetty, et voi puhua tässä huoneessa.",
   "You_need_confirm_email" : "Sinun tulee vahvistaa sähköpostiosoitteesi!",
   "You_need_install_an_extension_to_allow_screen_sharing" : "Sinun tarvitsee asentaa laajennus mahdollistaaksesi näytön jakamisen",
   "You_should_name_it_to_easily_manage_your_integrations" : "Nimeä siten, että sinun on helppo hallita integraatioitasi",
   "You_will_not_be_able_to_recover" : "Viestin palauttaminen ei ole mahdollista!",
   "Your_entry_has_been_deleted" : "Your entry has been deleted.",
+  "Your_mail_was_sent_to_s" : "Sähköpostisi lähetettiin, vastaanottaja %s",
   "Your_Open_Source_solution" : "Your own Open Source chat solution",
   "Your_push_was_sent_to_s_devices" : "Push-viesti lähetettiin %s laitteeseen"
 }
\ No newline at end of file
diff --git a/i18n/fr.i18n.json b/i18n/fr.i18n.json
index 31144e2a9c07a7e4bb07f947005c6ada4e50cfa9..a534eea244be4b2ecb07137fed1e3d01185533ea 100644
--- a/i18n/fr.i18n.json
+++ b/i18n/fr.i18n.json
@@ -1,16 +1,30 @@
 {
+  "Access_not_authorized" : "Accès non autorisé",
   "Access_online_demo" : "Accédez à la démo en ligne",
   "Access_Online_Demo" : "Accédez à la démo en ligne",
   "Accounts" : "Comptes",
+  "Accounts_AllowedDomainsList" : "Liste des domaines autorisés",
+  "Accounts_AllowedDomainsList_Description" : "Liste des domaines autorisés (séparés par des virgules)",
+  "Accounts_AllowPasswordChange" : "Autoriser le changement de mot de passe",
+  "Accounts_AllowUserAvatarChange" : "Autoriser le changement d'avatar (utilisateurs)",
+  "Accounts_AllowUsernameChange" : "Autoriser le changement de nom d'utilisateur",
+  "Accounts_AllowUserProfileChange" : "Autoriser le changement de profil (utilisateurs)",
+  "Accounts_AvatarResize" : "Redimensionner les avatars",
+  "Accounts_AvatarSize" : "Taille des avatars",
+  "Accounts_AvatarStorePath" : "Chemin de stockage des avatars",
+  "Accounts_AvatarStoreType" : "Type de stockage des avatars",
   "Accounts_denyUnverifiedEmail" : "Refuser les emails non vérifiées",
   "Accounts_EmailVerification" : "Vérification de l'e-mail",
+  "Accounts_Enrollment_Email" : "E-mail d'inscription",
+  "Accounts_Enrollment_Email_Description" : "Vous pouvez utiliser [name], [fname], [lname] pour le nom complet de l'utilisateur, le prénom et le nom de famille respectivement.<br />Vous pouvez utiliser [email] pour le mail de l'utilisateur.",
+  "Accounts_LoginExpiration" : "Expiration de la connexion (jours)",
   "Accounts_ManuallyApproveNewUsers" : "Approuver manuellement les nouveaux utilisateurs",
   "Accounts_OAuth_Custom_Authorize_Path" : "URL d'autorisation",
   "Accounts_OAuth_Custom_Button_Color" : "Couleur du bouton",
   "Accounts_OAuth_Custom_Button_Label_Color" : "Couleur de texte du bouton",
   "Accounts_OAuth_Custom_Button_Label_Text" : "Texte du bouton",
   "Accounts_OAuth_Custom_Enable" : "Activer",
-  "Accounts_OAuth_Custom_id" : "Id",
+  "Accounts_OAuth_Custom_id" : "ID",
   "Accounts_OAuth_Custom_Identity_Path" : "URL d'identification",
   "Accounts_OAuth_Custom_Secret" : "Secret",
   "Accounts_OAuth_Custom_Token_Path" : "URL de Token",
@@ -19,8 +33,11 @@
   "Accounts_OAuth_Facebook_id" : "App Id Facebook",
   "Accounts_OAuth_Facebook_secret" : "Facebook Secret",
   "Accounts_OAuth_Github" : "Connexion avec GitHub",
-  "Accounts_OAuth_Github_id" : "GitHub Id",
+  "Accounts_OAuth_Github_id" : "ID client",
   "Accounts_OAuth_Github_secret" : "GitHub Secret",
+  "Accounts_OAuth_Gitlab" : "OAuth activé",
+  "Accounts_OAuth_Gitlab_id" : "ID GitLab",
+  "Accounts_OAuth_Gitlab_secret" : "Mot de passe client",
   "Accounts_OAuth_Google" : "Connexion avec Google",
   "Accounts_OAuth_Google_id" : "Google Id",
   "Accounts_OAuth_Google_secret" : "Google Secret",
@@ -33,23 +50,36 @@
   "Accounts_OAuth_Twitter" : "Connexion avec Twitter",
   "Accounts_OAuth_Twitter_id" : "Twitter Id",
   "Accounts_OAuth_Twitter_secret" : "Twitter Secret",
+  "Accounts_PasswordReset" : "Mot de passe réinitialisé",
+  "Accounts_Registration_AuthenticationServices_Enabled" : "Enregistrement des comptes avec les services d'authentification",
+  "Accounts_RegistrationForm" : "Formulaire d'inscription",
+  "Accounts_RegistrationForm_Disabled" : "Désactivé",
+  "Accounts_RegistrationForm_Public" : "Publique",
+  "Accounts_RegistrationForm_Secret_URL" : "URL secrète",
+  "Accounts_RegistrationForm_SecretURL_Description" : "Vous devez fournir une chaîne de caractères aléatoire qui sera ajouté à votre URL d'inscription. Exemple: https://demo.rocket.chat/register/[secret_hash]",
   "Accounts_RegistrationRequired" : "Enregistrement nécessaire",
+  "Accounts_RequireNameForSignUp" : "Exiger un nom pour s'inscrire",
   "Activate" : "Activer",
   "Add_custom_oauth" : "Ajouter OAuth personnalisé",
   "Add_Members" : "Ajouter des membres",
   "Add_users" : "Ajouter des utilisateurs",
   "Administration" : "Administration",
   "All_channels" : "Tous les canaux",
-  "Allow_Invalid_SelfSigned_Certs" : "Autoriser les certificats SSL invalides et autosignés pour la validation des liens et prévisualisations",
+  "Allow_Invalid_SelfSigned_Certs" : "Autoriser les certificats auto-signés invalides",
+  "Allow_Invalid_SelfSigned_Certs_Description" : "Autoriser les certificats SSL invalides et auto-signés pour la validation des liens et extraits.",
   "and" : "et",
   "API" : "API",
   "API_Analytics" : "Analytique",
   "API_Embed" : "Embed",
+  "API_EmbedDisabledFor" : "Désactiver l'intégration externe pour les utilisateurs",
+  "API_EmbedDisabledFor_Description" : "Liste de noms d'utilisateurs séparés par des virgules",
+  "Archive" : "Archiver",
   "are_also_typing" : "sont également en train d'écrire",
   "are_typing" : "sont en train d'écrire",
   "Are_you_sure" : "Êtes-vous sûr(e) ?",
   "Auto_Load_Images" : "Charger automatiquement les images",
   "Avatar_changed_successfully" : "Avatar modifié avec succès",
+  "Avatar_url_invalid_or_error" : "L'URL est invalide ou non accessible. Essayez de nouveau, mais avec une URL différente.",
   "away" : "absent",
   "Away" : "Absent",
   "away_female" : "absente",
@@ -65,13 +95,17 @@
   "busy_male" : "occupé",
   "Busy_male" : "Occupé",
   "Cancel" : "Annuler",
+  "CDN_PREFIX" : "Préfixe CDN",
+  "Certificates_and_Keys" : "Certificats et clés",
   "Change_avatar" : "Changer l'avatar",
   "Channels" : "Canaux",
   "Channels_list" : "Liste des canaux publics",
   "Chat_Rooms" : "Salons de discussion",
+  "Clear_all_unreads_question" : "Marquer tout comme lu ?",
   "close" : "fermer",
   "coming_soon" : "prochainement",
   "Commands" : "Commandes",
+  "Compact_View" : "Vue compacte",
   "Confirm_password" : "Confirmez votre mot de passe",
   "Contact" : "Contact",
   "Conversation" : "Conversation",
@@ -85,6 +119,7 @@
   "Custom_oauth_unique_name" : "Nom unique OAuth personnalisé",
   "days" : "jours",
   "Deactivate" : "Désactiver",
+  "Delete_Room_Warning" : "Supprimer un salon supprimera également tous les messages postés dans le salon. Cela ne peut pas être annulé.",
   "Delete_User_Warning" : "Supprimer un utilisateur va également supprimer tous les messages de celui-ci. Cette action ne peut être annulée.",
   "Deleted" : "Supprimé !",
   "Desktop_Notifications" : "Notifications sur le bureau",
@@ -94,22 +129,34 @@
   "Disable_Favorite_Rooms" : "Désactiver les favoris",
   "Disable_New_Message_Notification" : "Désactiver la notification de nouveau message",
   "Disable_New_Room_Notification" : "Désactiver la notification de nouveau salon",
+  "Do_you_want_to_change_to_s_question" : "Voulez-vous changer pour <strong>%s</strong> ?",
   "Drop_to_upload_file" : "Glissez-déposez pour transférer un fichier",
+  "Duplicate_archived_channel_name" : "Un canal archivé avec le nom '% s' existe",
   "Duplicate_channel_name" : "Un canal avec le nom '% s' existe",
   "Duplicate_private_group_name" : "Un groupe privé avec le nom '% s' existe",
   "E-mail" : "Email",
   "edited" : "modifié",
   "Email_already_exists" : "L'adresse email existe déjà",
   "Email_or_username" : "Adresse email ou nom d'utilisateur",
-  "Email_verified" : "Email vérifié",
+  "Email_verified" : "Courriel vérifié",
   "Emoji" : "Emoji",
   "Enable_Desktop_Notifications" : "Activer les notifications sur le bureau",
   "Enter_info" : "Entrez vos identifiants de connexion",
   "Enter_to" : "Entrée pour",
-  "Error_changing_password" : "Erreur lors du changement de mot de \npasse",
+  "Error_changing_password" : "Erreur lors du changement de mot de passe",
+  "Error_too_many_requests" : "Erreur, trop de requêtes. Veuillez ralentir. Vous devez attendre %s secondes avant de réessayer.",
   "Esc_to" : "Échap pour",
+  "Example_s" : "Exemple : <code class=\"inline\">%s</code>",
   "False" : "Non",
   "Favorites" : "Favoris",
+  "FileUpload" : "Envoi de fichiers",
+  "FileUpload_Enabled" : "Envois de fichiers activés",
+  "FileUpload_File_Empty" : "Fichier vide",
+  "FileUpload_MaxFileSize" : "Taille maximale d'envoi de fichier (en octets)",
+  "FileUpload_MediaTypeWhiteList" : "Types de média acceptés",
+  "FileUpload_MediaTypeWhiteListDescription" : "Liste des types de média (séparés par des virgules)",
+  "FileUpload_ProtectFiles" : "Protéger les fichiers uploadés",
+  "FileUpload_ProtectFilesDescription" : "Seuls les utilisateurs authentifiés auront accès",
   "Follow_social_profiles" : "Suivez-nous sur les réseaux sociaux, clonez le projet sur GitHub et partagez vos idées à propos de rocket.chat sur notre tableau Trello.",
   "Forgot_password" : "Mot de passe oublié",
   "Fork_it_on_github" : "Cloner sur GitHub",
@@ -125,11 +172,24 @@
   "hours" : "heures",
   "Incorrect_Password" : "Mot de passe incorrect",
   "inline_code" : "Ligne de code",
+  "Install_Extension" : "Installer l'extension",
+  "Install_FxOs" : "Installez Rocket.Chat dans votre Firefox",
+  "Install_FxOs_done" : "Formidable ! Vous pouvez maintenant utiliser Rocket.Chat via l'icône sur votre écran d'accueil. Amusez-vous avec Rocket.Chat !",
+  "Install_FxOs_error" : "Désolé, cela n'a pas fonctionné comme prévu! L'erreur suivante est apparue :",
+  "Install_FxOs_follow_instructions" : "Veuillez confirmer l'installation de l'application sur votre appareil (appuyez sur \"Installer\" lorsque c'est demandé).",
+  "Integration_added" : "L'intégration a été ajoutée",
+  "Integration_updated" : "L'intégration a été mise à jour",
   "Invalid_confirm_pass" : "Les mots de passe renseignés ne sont pas les mêmes",
   "Invalid_email" : "L'adresse email saisie est invalide",
+  "Invalid_file_height" : "Hauteur du fichier non valide",
+  "Invalid_file_type" : "Type de fichier invalide",
+  "Invalid_file_width" : "Largeur du fichier non valide",
   "Invalid_name" : "Le nom doit être renseigné",
   "Invalid_pass" : "Le mot de passe doit être renseigné",
   "Invalid_room_name" : "<strong>%s</strong> n'est pas un nom de canal valide,<br>/ utilisez des lettres, des chiffres et des tirets uniquement",
+  "Invalid_room_type" : "<strong>%s</strong> n'est pas un nom de canal valide.",
+  "Invalid_Secret_URL" : "URL secrète invalide",
+  "Invalid_secret_URL_message" : "L'URL fournie est invalide.",
   "invisible" : "invisible",
   "Invisible" : "Invisible",
   "Invitation_HTML" : "Contenu HTML de l'invitation",
@@ -144,6 +204,8 @@
   "italics" : "italique",
   "join" : "Rejoindre\n",
   "Join_the_Community" : "Rejoignez la communauté",
+  "Jump_to_message" : "Aller au message",
+  "Jump_to_recent_messages" : "Aller aux messages récents",
   "Language" : "Langue",
   "Language_Version" : "Version anglaise",
   "Last_login" : "Dernière connexion",
@@ -155,12 +217,23 @@
   "Layout_Login_Terms" : "Conditions de connexion",
   "Layout_Privacy_Policy" : "Politique de confidentialité",
   "Layout_Sidenav_Footer" : "Pied de page",
-  "Layout_Sidenav_Footer_description" : "La taille du pied de page est 260x70",
+  "Layout_Sidenav_Footer_description" : "La taille du pied de page est de 260 × 70 pixels",
   "Layout_Terms_of_Service" : "Conditions de service",
   "LDAP" : "LDAP",
-  "LDAP_DN" : "DN LDAP",
+  "LDAP_Bind_Search" : "Recherche liée (Bind Search)",
+  "LDAP_Bind_Search_Description" : "Un code JSON qui régit les informations de lien et de connexion et est sous la forme {\"filter\": \"(&(objectCategory=person)(objectclass=user)(memberOf=CN=ROCKET_ACCESS,CN=Users,DC=domain,DC=com)(sAMAccountName=#{username}))\", \"scope\": \"sub\", \"userDN\": \"rocket.service@domain.com\", \"password\": \"urpass\"}",
+  "LDAP_Description" : "LDAP est une base de données hiérarchique que de nombreuses entreprises utilisent pour fournir une authentification unique à travers leurs services - L'utilisateur ne devra s'authentifier qu'une seule fois pour accéder à tous les services. Pour plus d'informations et des exemples de configuration avancée, s'il vous plaît consulter notre wiki: https://github.com/RocketChat/Rocket.Chat/wiki/LDAP-Authentication .",
+  "LDAP_DN" : "Nom distinctif (DN)",
+  "LDAP_DN_Description" : "Recherche racine; exemple: dc=domain,DC=com",
+  "LDAP_Enable" : "Activer LDAP",
+  "LDAP_Enable_Description" : "Essayer d'utiliser LDAP pour l'authentification.",
   "LDAP_Port" : "Port LDAP",
+  "LDAP_Port_Description" : "Port pour accéder à LDAP ; par exemple: 389",
+  "LDAP_Sync_User_Data" : "Synchronisation des données",
+  "LDAP_Sync_User_Data_Description" : "Garder les données de l'utilisateur en synchronisation celles du serveur lors de la connexion (par exemple: nom, e-mail).",
+  "LDAP_Sync_User_Data_FieldMap_Description" : "Configurer la façon dont les champs de compte d'utilisateur (comme le courrier électronique) sont remplis à partir d'un enregistrement dans l'annuaire LDAP (une fois trouvés). A titre d'exemple, {\"cn\": \"nom\", \"mail\": \"e-mail\"} choisira le nom d'une personne humainement lisible à partir de l'attribut cn, et leur e-mail à partir de l'attribut mail. Les champs disponibles comprennent le nom et le courrier électronique.",
   "LDAP_Url" : "Adresse LDAP",
+  "LDAP_Url_Description" : "URL du serveur LDAP ; exemple: ldap://company.dns.com",
   "Leave_room" : "Quitter le salon",
   "line" : "ligne",
   "Load_more" : "Charger plus",
@@ -173,26 +246,33 @@
   "Logout" : "Se déconnecter",
   "Make_Admin" : "Promouvoir administrateur",
   "Mark_as_read" : "Marquer comme lu",
+  "Markdown_Headers" : "Titres Markdown",
   "Members" : "Membres",
   "Members_List" : "Liste des membres",
   "Members_placeholder" : "Membres",
   "Message" : "Message",
   "Message_AllowDeleting" : "Autoriser la suppression de messages",
   "Message_AllowEditing" : "Autoriser la modification de messages",
-  "Message_AllowEditing_BlockEditInMinutes" : "Bloquer la modification de messages après (en minutes, 0 pour désactiver)",
+  "Message_AllowEditing_BlockEditInMinutes" : "Bloquer la modification des messages après (n) minutes",
+  "Message_AllowEditing_BlockEditInMinutesDescription" : "Entrez 0 pour désactiver le blocage.",
+  "Message_AudioRecorderEnabled" : "Enregistrement audio activé",
+  "Message_AudioRecorderEnabledDescription" : "Nécessite que les fichiers de type « audio/wav » soient acceptés en tant que média dans les réglages d'envoi de fichiers.",
   "Message_deleting_not_allowed" : "Suppression d'un message non autorisée",
   "Message_editing_blocked" : "Ce message ne peut plus être modifié",
   "Message_editing_not_allowed" : "Modification d'un message non autorisée",
+  "Message_GroupingPeriod" : "Période de regroupement (en secondes)",
+  "Message_GroupingPeriodDescription" : "Les messages seront regroupés avec les messages précédents si ils sont du même utilisateur et si le temps écoulé est inférieur au temps indiqué en secondes.",
   "Message_KeepHistory" : "Conserver l'historique des messages",
-  "Message_MaxAllowedSize" : "Taille maximum de message autorisée",
+  "Message_MaxAllowedSize" : "Taille maximale d'un message autorisée",
   "Message_pinned" : "Message épinglé",
   "Message_pinning_not_allowed" : "L'épinglement de message n'est pas autorisé",
   "Message_removed" : "Message supprimé",
   "Message_ShowDeletedStatus" : "Afficher le statut de suppression",
   "Message_ShowEditedStatus" : "Afficher le statut de modification",
+  "Message_ShowFormattingTips" : "Afficher les astuces de mise en forme",
   "Messages" : "Messages",
   "Meta" : "Meta",
-  "Meta_fb_app_id" : "Facebook APP ID",
+  "Meta_fb_app_id" : "App ID Facebook",
   "Meta_google-site-verification" : "Google Site Verification",
   "Meta_language" : "Langue",
   "Meta_msvalidate01" : "MSValidate.01",
@@ -203,6 +283,7 @@
   "More_unreads" : "Davantage de messages non lus",
   "Msgs" : "Messages",
   "multi" : "multiple",
+  "Mute_user" : "Rendre muet",
   "My_Account" : "Mon compte",
   "n_messages" : "%s messages",
   "Name" : "Nom",
@@ -216,9 +297,11 @@
   "No_favorites_yet" : "Vous n'avez ajouté aucun favoris pour le moment.",
   "No_group_with_name_%s_was_found" : "Aucun groupe privé nommé <strong>\"%s\"</strong> n'a été trouvé !",
   "No_groups_yet" : "Vous n'avez pas encore de groupes privés.",
+  "No_livechats" : "Vous avez pas de chats instantanés.",
   "No_permission_to_view_room" : "Vous n'avez pas la permission de voir ce salon",
   "No_user_with_username_%s_was_found" : "Aucun utilisateur nommé <strong>\"%s\"</strong> n'a été trouvé !",
   "Not_allowed" : "Non autorisé",
+  "Not_authorized" : "Non autorisé",
   "Not_found_or_not_allowed" : "Introuvable ou non autorisé",
   "Nothing_found" : "Aucun résultat",
   "Notify_all_in_this_room" : "Notifiez tout le monde dans ce salon",
@@ -231,8 +314,10 @@
   "Opt_out_statistics_warning" : "En envoyant vos statistiques anonymes, vous allez nous aider à identifier le nombre d'instances de Rocket.Chat déployées, ainsi que le bon comportement du système, et donc que nous pourrions encore améliorer. Si vous souhaitez continuer à nous envoyer vos statistiques anonymes, décochez la case ci-dessus. Merci.",
   "others" : "autres",
   "Password" : "Mot de passe",
+  "Password_Change_Disabled" : "L'administrateur de votre Rocket.Chat a désactivé la possibilité de changer de mot de passe",
   "Password_changed_successfully" : "Mot de passe modifié avec succès",
   "People" : "Personnes",
+  "Please_enter_value_for_url" : "Veuillez entrer l'url de votre avatar.",
   "Please_wait" : "Veuillez patienter",
   "Please_wait_activation" : "Veuillez patienter, cela peut prendre un peu de temps.",
   "Please_wait_statistics" : "Veuillez patienter, les statistiques sont en cours de génération.",
@@ -254,28 +339,41 @@
   "Push_apn_passphrase" : "APN Passphrase",
   "Push_debug" : "Débogage",
   "Push_enable" : "Activer",
+  "Push_enable_gateway" : "Activer la passerelle",
+  "Push_gateway" : "Passerelle",
+  "Push_gcm_api_key" : "Clé API GCM",
+  "Push_gcm_project_number" : "Numéro de projet GCM",
   "Push_production" : "Production",
   "Quick_Search" : "Recherche rapide",
   "quote" : "citation",
   "Recents" : "Récents",
   "Record" : "Enregistrer",
+  "Refresh_your_page_after_install_to_enable_screen_sharing" : "Actualisez votre page après l'installation pour permettre le partage d'écran",
   "Register" : "Créer un nouveau compte",
   "Registration_Succeeded" : "Enregistrement réussi",
   "Remember_me" : "Se souvenir de moi",
   "Remove" : "Supprimer",
   "Remove_Admin" : "Supprimer administrateur",
   "Remove_custom_oauth" : "Supprimer OAuth personnalisé ",
+  "Remove_from_room" : "Retirer du salon",
   "Reset_password" : "Réinitialiser le mot de passe",
   "Room" : "Salon",
+  "Room_archived" : "Salon archivé",
+  "Room_has_been_deleted" : "Le salon a été supprimé",
   "Room_name_changed" : "Nom du salon changé en : <em>__room_name__</em> par <em>__user_by__</em>",
   "Room_name_changed_successfully" : "Nom du salon changé avec succès",
   "Room_not_found" : "Salon introuvable",
+  "Room_unarchived" : "Salon désarchivé",
   "Room_uploaded_file_list" : "Liste des fichiers",
   "Room_uploaded_file_list_empty" : "Aucun fichier disponible.",
   "room_user_count" : "%s utilisateurs",
   "Rooms" : "Salons",
   "S_new_messages_since_s" : "%s nouveaux messages depuis %s",
   "SAML" : "SAML",
+  "SAML_Custom_Cert" : "Certificat personnalisé",
+  "SAML_Custom_Entry_point" : "Point d'entrée personnalisée",
+  "SAML_Custom_Generate_Username" : "Générer le nom d'utilisateur",
+  "SAML_Custom_Provider" : "Fournisseur personnalisé",
   "Save_changes" : "Sauvegarder les modifications",
   "Save_Mobile_Bandwidth" : "Préserver la bande passante sur mobile",
   "Search" : "Recherche",
@@ -298,11 +396,14 @@
   "Send_Message" : "Envoyer un message",
   "Settings" : "Paramètres",
   "Settings_updated" : "Paramètres mis à jour",
+  "Showing_archived_results" : "<p>Affichage de <b>%s</b> résultats archivés</p>",
   "Showing_online_users" : "<b>__total_online__</b> utilisateur(s) sur un total de __total__ affichés",
   "Showing_results" : "<p><b>%s</b> résultat(s)</p>",
   "Silence" : "Silence",
   "since_creation" : "depuis %s",
-  "Site_Name" : "Nom du site :",
+  "Site_Name" : "Nom du site",
+  "Site_Url" : "URL du site",
+  "Site_Url_Description" : "Exemple : https://chat.domain.com/",
   "SMTP" : "SMTP",
   "SMTP_Host" : "Hôte SMTP",
   "SMTP_Password" : "Mot de passe SMTP",
@@ -337,16 +438,24 @@
   "Stop_Recording" : "Arrêter l'enregistrement",
   "strike" : "barré",
   "Submit" : "Envoyer",
+  "The_channel_name_is_required" : "Le canal doit être nommé",
   "The_field_is_required" : "Le champ %s est requis.",
+  "The_setting_s_is_configured_to_s_and_you_are_accessing_from_s" : "Le réglage <strong>%s</strong> est configuré pour <strong>%s</strong> et vous accédez à partir de <strong>%s</strong> !",
   "True" : "Oui",
+  "Unarchive" : "Désarchiver",
+  "Unmute_user" : "Réactiver",
   "Unnamed" : "Sans nom",
+  "Unread_Rooms" : "Salons contenant des messages non-lus",
+  "Unread_Rooms_Mode" : "Mode des salons non-lus",
   "Upload_file_question" : "Transférer le fichier ?",
+  "Uploading_file" : "Envoi de fichier en cours...",
   "Use_Emojis" : "Utiliser les émoticônes",
   "Use_initials_avatar" : "Utiliser les initiales de votre nom d'utilisateur",
   "use_menu" : "Utilisez le menu latéral pour accéder à vos salons et discussions.",
   "Use_service_avatar" : "Utiliser l'avatar %s",
   "Use_this_username" : "Utilisez ce nom d'utilisateur",
   "Use_uploaded_avatar" : "Utiliser l'avatar transmis",
+  "Use_url_for_avatar" : "Utilisez l'URL pour l'avatar",
   "User_added_by" : "L'utilisateur <em>__user_added__</em> a été ajouté par <em>__user_by__</em>.",
   "User_Channels" : "Salons d'utilisateur",
   "User_has_been_activated" : "L'utilisateur a été activé",
@@ -359,15 +468,20 @@
   "User_joined_channel" : "A rejoint le canal.",
   "User_joined_channel_female" : "A rejoint le canal.",
   "User_joined_channel_male" : "A rejoint le canal.",
-  "User_left" : "L'utilisateur <em>__user_left__</em> est parti.",
-  "User_left_female" : "L'utilisateur <em>__user_left__</em> est parti.",
-  "User_left_male" : "L'utilisateur <em>__user_left__</em> est parti.",
+  "User_left" : "A quitté le canal.",
+  "User_left_female" : "A quitté le canal.",
+  "User_left_male" : "A quitté le canal.",
   "User_logged_out" : "L'utilisateur est déconnecté",
+  "User_muted_in_room" : "L'utilisateur à été bloqué dans ce salon",
+  "User_not_found_or_incorrect_password" : "Utilisateur introuvable ou mot de passe incorrect",
   "User_removed_by" : "L'utilisateur <em>__user_removed__</em> a été éjecté par <em>__user_by__</em>.",
+  "User_removed_from_room" : "L'utilisateur a été retiré du salon",
   "User_Settings" : "Paramètres utilisateur",
+  "User_unmuted_in_room" : "L'utilisateur à été réactivé dans ce salon",
   "User_updated_successfully" : "Utilisateur mis à jour avec succès",
   "Username" : "Nom d'utilisateur",
   "Username_cant_be_empty" : "Le nom d'utilisateur doit être renseigné",
+  "Username_Change_Disabled" : "L'administrateur de votre Rocket.Chat a désactivé la possibilité de changer de nom d'utilisateur",
   "Username_description" : "Le nom d'utilisateur est utilisé pour permettre à d'autres personnes de vous mentionner dans leurs messages.",
   "Username_invalid" : "<strong>%s</strong> n'est pas un nom d'utilisateur valide,<br/> utilisez des lettres, des chiffres, des points et des tirets uniquement",
   "Username_title" : "Enregistrer un nom d'utilisateur",
@@ -380,10 +494,15 @@
   "Welcome" : "Bienvenue <em>%s</em>.",
   "Welcome_to_the" : "Bienvenue sur",
   "With_whom" : "Avec qui",
+  "Yes" : "Oui",
+  "Yes_clear_all" : "Oui, marquez tout comme lu !",
   "Yes_delete_it" : "Oui, je confirme la suppression !",
   "you_are_in_preview_mode_of" : "Aperçu du salon #<strong>__room_name__</strong> ",
+  "You_can_use_an_emoji_as_avatar" : "Vous pouvez également utiliser un emoji comme avatar.",
+  "You_have_been_muted" : "Vous avez été bloqué et ne pouvez pas parler dans cette salle",
   "You_need_confirm_email" : "Vous devez confirmer votre adresse email pour vous connecter !",
-  "You_will_not_be_able_to_recover" : "Cette action n'est pas réversible !",
+  "You_need_install_an_extension_to_allow_screen_sharing" : "Vous devez installer une extension pour permettre le partage d'écran",
+  "You_will_not_be_able_to_recover" : "Vous ne serez pas en mesure de récupérer ce message !",
   "Your_entry_has_been_deleted" : "Ce message a été supprimé.",
   "Your_Open_Source_solution" : "Votre propre solution de chat Open Source"
 }
\ No newline at end of file
diff --git a/i18n/he.i18n.json b/i18n/he.i18n.json
index 0a641b93d4d5215b42990fe914bf505094efa64c..fdd4e9b7b7ffd12593b01b5eba612bce39b4602c 100644
--- a/i18n/he.i18n.json
+++ b/i18n/he.i18n.json
@@ -1,147 +1,302 @@
 {
-  "Access_online_demo" : "צפה בגרסת הדגמה",
-  "Access_Online_Demo" : "צפה בגרסת ההדגמה",
-  "Add_Members" : "הוסף חברים",
-  "Add_users" : "הוסף משתמשים",
+  "Access_not_authorized" : "הגישה אינה מורשית.",
+  "Access_online_demo" : "צפייה בגרסת הדגמה",
+  "Access_Online_Demo" : "צפייה בגרסת ההדגמה",
+  "Accounts" : "חשבונות",
+  "Accounts_EmailVerification" : "אימות דוא״ל",
+  "Accounts_OAuth_Custom_Authorize_Path" : "נתיב אימות",
+  "Accounts_OAuth_Custom_Button_Color" : "צבע הכפתור",
+  "Accounts_OAuth_Custom_Button_Label_Color" : "צבע טקסט הכפתור",
+  "Accounts_OAuth_Custom_Button_Label_Text" : "טקסט הכפתור",
+  "Accounts_OAuth_Custom_Enable" : "הפעלה",
+  "Accounts_OAuth_Custom_Identity_Path" : "נתיב הזהות",
+  "Accounts_OAuth_Custom_Secret" : "סוד",
+  "Accounts_OAuth_Custom_Token_Path" : "נתיב האסימון",
+  "Accounts_OAuth_Custom_URL" : "כתובת",
+  "Accounts_OAuth_Facebook" : "כניסה לפייסבוק",
+  "Accounts_OAuth_Facebook_id" : "מזהה יישומון פייסבוק",
+  "Accounts_OAuth_Facebook_secret" : "סוד פייסבוק",
+  "Accounts_OAuth_Github_id" : "מזהה לקוח",
+  "Accounts_OAuth_Github_secret" : "סוד לקוח",
+  "Accounts_OAuth_Google" : "כניסה לגוגל",
+  "Accounts_OAuth_Google_id" : "מזהה בגוגל",
+  "Accounts_OAuth_Google_secret" : "סוד גוגל",
+  "Accounts_OAuth_Linkedin" : "כניסה ל־LinkedIn",
+  "Accounts_OAuth_Linkedin_id" : "מזהה LinkedIn",
+  "Accounts_OAuth_Linkedin_secret" : "סוד LinkedIn",
+  "Accounts_PasswordReset" : "איפוס ססמה",
+  "Accounts_RegistrationForm" : "טופס הרשמה",
+  "Accounts_RegistrationForm_Secret_URL" : "כתובת סודית",
+  "Accounts_RegistrationRequired" : "נדרשת הרשמה",
+  "Add_Members" : "הוספת חברים",
+  "Add_users" : "הוספת משתמשים",
+  "Administration" : "ניהול",
   "All_channels" : "כל הערוצים",
   "and" : "ו",
+  "API_Embed" : "הטמעה",
   "are_also_typing" : "גם מקלידים",
   "are_typing" : "מקלידים",
+  "Are_you_sure" : "בוודאות?",
+  "Auto_Load_Images" : "טעינת תמונות אוטומטית",
+  "Avatar_changed_successfully" : "התמונה הוחלפה בהצלחה",
   "away" : "לא נמצא",
   "Away" : "לא נמצא",
-  "Back_to_login" : "חזור להתחברות",
+  "away_female" : "לא נמצאת",
+  "Away_female" : "לא נמצאת",
+  "away_male" : "לא נמצא",
+  "Away_male" : "לא נמצא",
+  "Back_to_login" : "חזרה לכניסה",
   "bold" : "מודגש",
   "busy" : "עסוק",
   "Busy" : "עסוק",
+  "busy_female" : "עסוקה",
+  "Busy_female" : "עסוקה",
+  "busy_male" : "עסוק",
+  "Busy_male" : "עסוק",
   "Cancel" : "ביטול",
-  "Change_avatar" : "שנה את האוואטר",
+  "Certificates_and_Keys" : "תעודות ומפתחות",
+  "Change_avatar" : "החלפת תמונת המשתמש שלך",
   "Channels" : "ערוצים",
   "Channels_list" : "רשימת ערוצים ציבוריים",
-  "Chat_Rooms" : "חדרי צ'אט",
-  "close" : "סגור",
+  "Chat_Rooms" : "חדרי צ׳אט",
+  "close" : "סגירה",
   "coming_soon" : "בקרוב",
-  "Confirm_password" : "אמת את הסיסמא",
-  "Contact" : "צור קשר",
+  "Confirm_password" : "אימות הססמה",
+  "Contact" : "יצירת קשר",
   "Conversation" : "שיחה",
-  "Create_new" : "צור חדש",
-  "Create_new_private_group" : "צור קבוצה פרטית חדשה",
-  "Create_new_public_channel" : "צור ערוץ ציבורי חדש",
-  "Created_at" : "נוצר ב-",
+  "Convert_Ascii_Emojis" : "המרת ASCII לאימוג׳י",
+  "COPY_TO_CLIPBOARD" : "העתקה ללוח הגזירים",
+  "Create_new" : "יצירת חדש",
+  "Create_new_direct_message_room" : "יצירת חדר הודעה ישירה חדש",
+  "Create_new_private_group" : "יצירת קבוצה פרטית חדשה",
+  "Create_new_public_channel" : "יצירת ערוץ ציבורי חדש",
+  "Created_at" : "נוצר ב־",
+  "days" : "ימים",
+  "Deleted" : "נמחק!",
   "Direct_Messages" : "הודעות ישירות",
+  "Disable_New_Message_Notification" : "נטרול התרעת הודעה חדשה",
+  "Disable_New_Room_Notification" : "נטרול התרעת חדר חדש",
+  "Drop_to_upload_file" : "יש להשליך לכאן כדי להעלות קובץ",
+  "Duplicate_channel_name" : "כבר קיים ערוץ בשם ‚%s‘",
+  "Duplicate_private_group_name" : "כבר קיימת קבוצה פרטית בשם ‚%s‘",
+  "E-mail" : "דוא״ל",
   "edited" : "נערך",
-  "Email_or_username" : "כתובת אימייל או שם משתמש",
-  "Email_verified" : "כתובת האימייל אומתה",
-  "Enter_info" : "הזן את פרטי ההתחברות שלך",
-  "Error_changing_password" : "הסיסמא שונתה",
+  "Email_already_exists" : "כתובת הדוא״ל כבר קיימת",
+  "Email_or_username" : "כתובת דוא״ל או שם משתמש",
+  "Email_verified" : "כתובת הדוא״ל אומתה",
+  "Enter_info" : "נא להזין את הפרטים שלך",
+  "Error" : "שגיאה",
+  "Error_changing_password" : "הססמה הוחלפה",
+  "Example_s" : "לדוגמה: <code class=\"inline\">%s</code>",
   "Favorites" : "מועדפים",
-  "Follow_social_profiles" : "עקוב אחר הפרופילים שלנו ברשתות החברתיות, עשה fork לפרויקט שלנו ב-github ושתף את המחשבות שלך על אפליקציית rocket.chat בלוח trello שלנו.",
-  "Forgot_password" : "שכחת את הסיסמא?",
-  "Fork_it_on_github" : "עשה לנו fork ב-github",
-  "Get_to_know_the_team" : "הכר את הצוות שמאחורי Rocket.Chat",
-  "github_no_public_email" : "אין לך אף כתובת אימייל פומבית בחשבון ה-GitHub שלך",
-  "Have_your_own_chat" : "תהיה בעל שרת צ'אט. פותחה עם meteor.com, האפליקציה Rocket.Chat היא פתרון מעולה עבור מפתחים המחפשים לבנות ולשפר את פלפורמת הצ'אט שלהם.",
-  "Hide_room" : "הסתר את החדר",
+  "FileUpload_ProtectFiles" : "הגנה על קבצים שהועלו",
+  "Follow_social_profiles" : "ניתן לעקוב אחר הפרופילים שלנו ברשתות החברתיות, לעשות fork למיזם שלנו ב־github ושתף את המחשבות שלך על אפליקציית rocket.chat בלוח trello שלנו.",
+  "Forgot_password" : "שכחת את הססמה?",
+  "Fork_it_on_github" : "fork ב־github",
+  "From_Email" : "כתובת מאת",
+  "General" : "כללי",
+  "Get_to_know_the_team" : "היכרות עם הצוות שמאחורי Rocket.Chat",
+  "github_no_public_email" : "אין לך אף כתובת דוא״ל פומבית בחשבון ה־GitHub שלך",
+  "Has_more" : "יש עוד",
+  "Have_your_own_chat" : "קח את העניינים לידיים. האפליקציה Rocket.Chat, ש",
+  "Hide_room" : "להסתיר את החדר",
   "History" : "היסטוריה",
+  "hours" : "שעות",
   "inline_code" : "קוד",
-  "Invalid_confirm_pass" : "אימות הסיסמא אינו זהה לסיסמא",
-  "Invalid_email" : "כתובת האימייל שהוזנה אינה תקינה",
-  "Invalid_name" : "השם חייב להיות מוזן",
-  "Invalid_pass" : "הסיסמא חייבת להיות מוזנת",
-  "Invalid_room_name" : "<strong>%s</strong> הוא לא שם תקין לחדר,<br/> השתמש רק באותיות, מספרים ומקפים.",
+  "Install_Extension" : "התקנת הרחבה",
+  "Invalid_confirm_pass" : "אימות הססמה אינו זהה לססמה",
+  "Invalid_email" : "כתובת הדוא״ל שהוזנה אינה תקינה",
+  "Invalid_name" : "יש להזין שם",
+  "Invalid_pass" : "יש להזין ססמה",
+  "Invalid_room_name" : "השם <strong>%s</strong> הוא לא שם תקין לחדר,<br/> יש להשתמש רק באותיות, מספרים ומקפים.",
   "invisible" : "בלתי נראה",
   "Invisible" : "בלתי נראה",
   "is_also_typing" : "גם מקליד/ה",
+  "is_also_typing_female" : "גם מקלידה",
+  "is_also_typing_male" : "גם מקליד",
   "is_typing" : "מקליד/ה",
+  "is_typing_female" : "מקלידה",
+  "is_typing_male" : "מקליד",
   "italics" : "נוטה",
-  "join" : "הצטרף",
-  "Join_the_Community" : "הצטרף לקהילה",
+  "join" : "הצטרפות",
+  "Join_the_Community" : "הצטרפות לקהילה",
+  "Jump_to_message" : "מעבר להודעה",
+  "Jump_to_recent_messages" : "מעבר להודעות האחרונות",
   "Language" : "שפה",
   "Language_Version" : "גרסה אנגלית",
+  "Last_login" : "כניסה אחרונה",
   "Last_message" : "ההודעה האחרונה",
-  "Leave_room" : "עזוב את החדר",
+  "Layout" : "פריסה",
+  "Layout_Home_Body" : "גוף עמוד הבית",
+  "Layout_Home_Title" : "כותרת עמוד הבית",
+  "Layout_Login_Header" : "כותרת כניסה",
+  "Layout_Login_Terms" : "תנאי כניסה",
+  "Layout_Privacy_Policy" : "מדיניות פרטיות",
+  "Layout_Terms_of_Service" : "תנאי השירות",
+  "LDAP" : "LDAP",
+  "LDAP_DN" : "שם מבדיל (DN)",
+  "LDAP_Port" : "פתחת LDAP",
+  "LDAP_Url" : "כתובת LDAP",
+  "Leave_room" : "לעזוב את החדר",
   "line" : "שורה",
-  "Load_more" : "טען עוד",
-  "Loading_suggestion" : "טוען הצעות...",
-  "Login" : "התחבר",
-  "Login_with" : "התחבר עם %s",
-  "login_with" : "או התחבר ישירות עם",
-  "Logout" : "התנתק",
+  "Load_more" : "טעינת נוספים",
+  "Loading..." : "בטעינה…",
+  "Loading_more_from_history" : "הודעות נוספות נטענות מההיסטוריה",
+  "Loading_suggestion" : "ההצעות נטענות…",
+  "Login" : "התחברות",
+  "Login_with" : "כניסה עם %s",
+  "login_with" : "או להיכנס ישירות עם",
+  "Logout" : "יציאה",
+  "Mark_as_read" : "סימון כנקרא",
   "Members" : "חברים",
   "Members_List" : "רשימת חברים",
   "Members_placeholder" : "חברים",
+  "Message" : "הודעה",
+  "Message_AllowDeleting" : "לאפשר מחיקת הודעות",
+  "Message_AllowEditing" : "לאפשר עריכת הודעות",
+  "Message_KeepHistory" : "שמירה על היסטוריית הודעות",
+  "Message_MaxAllowedSize" : "גודל ההודעה המרבי המותר",
+  "Message_removed" : "ההודעה הוסרה",
+  "Message_ShowDeletedStatus" : "הצגת מצב מחיקה",
+  "Message_ShowEditedStatus" : "הצגת מצב ערוך",
+  "Meta_language" : "שפה",
+  "Meta_robots" : "רובוטים",
+  "minutes" : "דקות",
   "More_channels" : "עוד ערוצים",
+  "More_groups" : "קבוצות פרטיות נוספות",
   "Msgs" : "הודעות",
   "multi" : "הרבה",
+  "Mute_user" : "השתקת משתמש",
+  "My_Account" : "החשבון שלי",
   "n_messages" : "%s הודעות",
   "Name" : "שם",
   "New_messages" : "הודעות חדשות",
-  "New_password" : "סיסמא חדשה",
+  "New_password" : "ססמה חדשה",
   "No_channels_yet" : "אינך חבר באף ערוץ עד כה.",
   "No_direct_messages_yet" : "לא התחלת אף שיחה עד כה.",
   "No_favorites_yet" : "אין לך מועדפים.",
   "No_groups_yet" : "לא קיימות לך קבוצות פרטיות.",
   "No_permission_to_view_room" : "אין לך הרשאות לצפות בחדר זה",
+  "No_results_found" : "לא נמצאו תוצאות",
+  "no_tokens_for_this_user" : "אין אסימונים למשתמש זה",
   "Not_allowed" : "לא מורשה",
-  "Not_found_or_not_allowed" : "לא נמצא או אינך מורשה",
+  "Not_found_or_not_allowed" : "לא נמצא או שאין לך הרשאה",
   "Nothing_found" : "אין תוצאות",
+  "Notify_all_in_this_room" : "להודיע לכל מי שבחדר",
   "Online" : "מחובר",
   "Oops!" : "אופס",
-  "Password" : "סיסמא",
-  "Please_wait" : "אנא המתן",
-  "Powered_by" : "מופעל על ידי",
+  "Opt_out_statistics" : "לא לשלוח את הסטטיסטיקה שלי ל־Rocket.Chat",
+  "others" : "אחרים",
+  "Password" : "ססמה",
+  "Password_changed_successfully" : "הססמה הוחלפה בהצלחה",
+  "Please_wait" : "נא להמתין",
+  "Post_to_Channel" : "פרסום לערוץ",
+  "Powered_by" : "מופעל על גבי",
+  "Preferences" : "העדפות",
+  "Preferences_saved" : "ההעדפות נשמרו",
   "Privacy" : "פרטיות",
   "Private_Groups" : "קבוצות פרטיות",
+  "Private_Groups_list" : "הצגת הקבוצות הפרטיות",
+  "Profile" : "פרופיל",
+  "Profile_saved_successfully" : "הפרופיל נשמר בהצלחה",
   "Proudly_developed" : "פותח בגאווה עם Meteor",
+  "Push" : "דחיפה",
+  "Push_debug" : "ניפוי שגיאות",
+  "Push_enable_gateway" : "הפעלת שער גישה",
+  "Push_gateway" : "שער גישה",
+  "Push_test_push" : "בדיקה",
   "Quick_Search" : "חיפוש מהיר",
   "quote" : "ציטוט",
   "Recents" : "אחרונים/אחרונות",
-  "Register" : "הירשם עם חשבון חדש",
-  "Remember_me" : "זכור אותי",
-  "Remove" : "מחק",
-  "Reset_password" : "אפס סיסמא",
+  "Register" : "הרשמה עם חשבון חדש",
+  "Remember_me" : "שמירת הפרטים שלי",
+  "Remove" : "מחיקה",
+  "Reset" : "איפוס",
+  "Reset_password" : "איפוס ססמה",
+  "Restart" : "הפעלה מחדש",
+  "Restart_the_server" : "איפוס השרת",
   "Room" : "חדר",
   "Room_name_changed" : "שם החדר שונה ל: <em>__room_name__</em> על ידי המשתמש <em>__user_by__</em>",
   "Room_name_changed_successfully" : "שם החדר שונה בהצלחה",
-  "Search" : "חפש",
-  "See_all" : "צפה בהכל",
-  "See_only_online" : "רק מחובר",
-  "Select_an_avatar" : "בחר אוואטר",
-  "Select_file" : "בחר קובץ",
-  "Select_service_to_login" : "בחר שירות להתחבר דרכו כדי לטעון את התמונה שלך או העלה אחת ישירות מהמחשב שלך",
+  "room_user_count" : "משתמשי %s",
+  "Rooms" : "חדרים",
+  "SAML" : "SAML",
+  "Save_changes" : "שמירת השינויים",
+  "Save_Mobile_Bandwidth" : "חסכון בתעבורה סלולרית",
+  "Screen_Share" : "שיתוף מסך",
+  "Search" : "חיפוש",
+  "Search_Messages" : "חיפוש בהודעות",
+  "Search_settings" : "הגדרות חיפוש",
+  "See_all" : "צפייה בהכול",
+  "See_only_online" : "רק מחוברים",
+  "Select_an_avatar" : "בחירת תמונה",
+  "Select_file" : "בחירת קובץ",
+  "Select_service_to_login" : "יש לבחור בשירות להתחבר דרכו לטעינת התמונה שלך או להעלות אחת ישירות מהמחשב שלך",
   "Selected_users" : "חברים נבחרים",
-  "Send_confirmation_email" : "שלח מייל אימות",
-  "Send_Message" : "שלח הודעה",
+  "Send" : "שליחה",
+  "Send_confirmation_email" : "שליחת דוא״ל אימות",
+  "Send_Message" : "שליחת הודעה",
   "Settings" : "הגדרות",
+  "Settings_updated" : "ההגדרות עודכנו",
   "Showing_online_users" : "מציג <b>__total_online__</b> מתוך __total__ משתמשים",
-  "Showing_results" : "<p>מציג <b>%s</b> תוצאות</p>",
-  "Silence" : "השתק",
+  "Showing_results" : "<p>מוצגות <b>%s</b> תוצאות</p>",
+  "Silence" : "השתקה",
   "since_creation" : "מאז %s",
+  "Site_Name" : "שם האתר",
+  "SMTP" : "SMTP",
+  "SMTP_Host" : "מארח ",
+  "SMTP_Password" : "ססמה ל־",
+  "SMTP_Port" : "פתחת SMTP",
+  "SMTP_Username" : "שם משתמש ב־SMTP",
+  "Sound" : "שמע",
   "Start_of_conversation" : "התחלת השיחה",
+  "Statistics" : "סטטיסטיקה",
+  "Stats_Away_Users" : "משתמשים שאינם נמצאים",
+  "Stats_Total_Messages" : "סך כל ההודעות",
   "strike" : "מחוק",
-  "Submit" : "שלח",
+  "Submit" : "שליחה",
+  "Success" : "הצליח",
+  "The_channel_name_is_required" : "שם הערוץ נדרש",
   "The_field_is_required" : "השדה %s הוא חובה.",
-  "Use_initials_avatar" : "השתמש בתחיליות שם המשתמש שלך",
-  "use_menu" : "השתמש בתפריט הצד כדי לגשת לחדרים ולשיחות הצ'אט שלך.",
-  "Use_service_avatar" : "השתמש באוואטר %s",
-  "Use_this_username" : "השתמש בשם המשתמש הזה",
-  "Use_uploaded_avatar" : "השתמש באוואטר שהועלה",
+  "The_server_will_restart_in_s_seconds" : "השרת יפעיל את עצמו מחדש בעוד ",
+  "Upload_file_question" : "להעלות קובץ?",
+  "Use_Emojis" : "שימוש באימוג׳י",
+  "Use_initials_avatar" : "שימוש בראשי התיבות של שם המשתמש שלך",
+  "use_menu" : "ניתן להשתמש בתפריט הצד כדי לגשת לחדרים ולצ׳אטים שלך.",
+  "Use_service_avatar" : "שימוש בתמונה מ־%s",
+  "Use_this_username" : "יש להשתמש בשם המשתמש הזה",
+  "Use_uploaded_avatar" : "שימוש בתמונה שהועלתה",
   "User_added_by" : "המשתמש <em>__user_added__</em> נוסף על ידי <em>__user_by__</em>",
+  "User_has_been_activated" : "המשתמש הופעל",
+  "User_has_been_deactivated" : "המשתמש נוטרל",
   "User_joined_channel" : "הצטרף לערוץ.",
-  "User_left" : "המשתמש <em>__user_left__</em> עזב את השיחה.",
+  "User_joined_channel_female" : "הצטרפה לערוץ.",
+  "User_joined_channel_male" : "הצטרף לערוץ.",
+  "User_left" : "המשתמש עזב את השיחה.",
+  "User_left_female" : "עזבה את הערוץ.",
+  "User_left_male" : "עזב את הערוץ.",
   "User_logged_out" : "המשתמש לא מחובר",
   "User_removed_by" : "המשתמש <em>__user_removed__</em> הוסר על ידי <em>__user_by__</em>",
+  "User_Settings" : "הגדרות המשתמש",
   "Username" : "שם משתמש",
-  "Username_cant_be_empty" : "שם המשתמש חייב להיות מוזן",
+  "Username_cant_be_empty" : "יש להזין שם משתמש",
   "Username_description" : "שם המשתמש שלך משמש עבור אזכורים שלך בהודעות של משתמשים אחרים.",
-  "Username_invalid" : "<strong>%s</strong> הוא לא שם משתמש תקין,<br/> השתמש רק באותיות, מספרים נקודות ומקפים.",
-  "Username_title" : "רשום שם משתמש",
-  "Username_unavaliable" : "<strong>%s</strong> תפוס :(",
-  "View_All" : "הצג הכל",
-  "We_have_sent_password_email" : "הינך צריך לקבל בדקות הקרובות מייל עם הוראות לאיפוס הסיסמא. אם אינך רואה אותו, אנא נסה שנית.",
-  "We_have_sent_registration_email" : "שלחנו לך מייל לאישור ההרשמה. אם אינך מקבל את המייל בדקות הקרובות, אנא נסה שנית.",
-  "Welcome" : "ברוך הבא <em>%s</em>.",
-  "Welcome_to_the" : "ברוך הבא ל-",
-  "you_are_in_preview_mode_of" : "הנך בתצוגה מוקדמת של ערוץ #<strong>__rom_name__</strong>",
-  "You_need_confirm_email" : "הינך צריך לאמת את כתובת האימייל על מנת להתחבר!",
-  "Your_Open_Source_solution" : "פתרון הקוד הפתוח שלך לצ'אט"
+  "Username_invalid" : "השם <strong>%s</strong> אינו שם משתמש תקין,<br/> יש להשתמש רק באותיות, מספרים נקודות ומקפים.",
+  "Username_title" : "רישום שם משתמש",
+  "Username_unavaliable" : "השם <strong>%s</strong> תפוס :(",
+  "Users" : "משתמשים",
+  "View_All" : "הצגת הכול",
+  "We_have_sent_password_email" : "בדקות הקרובות אמורה להגיע אליך הודעה בדוא״ל עם הוראות לאיפוס הססמה. אם ההודעה לא מגיעה אליך, נא לנסות שוב.",
+  "We_have_sent_registration_email" : "שלחנו לך הודעת דוא״ל לאישור ההרשמה. אם ההודעה לא מגיעה אליך בדקות הקרובות, נא לחזור לכאן ולנסות שוב.",
+  "Welcome" : "ברוך בואך <em>%s</em>.",
+  "Welcome_to_the" : "ברוך בואך ל־",
+  "With_whom" : "עם מי",
+  "Yes" : "כן",
+  "Yes_delete_it" : "כן, למחוק אותה!",
+  "you_are_in_preview_mode_of" : "זוהי תצוגה מוקדמת של הערוץ #<strong>__rom_name__</strong>",
+  "You_need_confirm_email" : "עליך לאמת את כתובת הדוא״ל על מנת להתחבר!",
+  "You_need_install_an_extension_to_allow_screen_sharing" : "צריך להתקין הרחבה כדי לאפשר שיתוף מסך",
+  "You_will_not_be_able_to_recover" : "לא תהיה לך אפשרות לשחזר את ההודעה הזו!",
+  "Your_entry_has_been_deleted" : "הרשומה שלך נמחקה",
+  "Your_Open_Source_solution" : "הפתרון "
 }
\ No newline at end of file
diff --git a/i18n/hr.i18n.json b/i18n/hr.i18n.json
index 1af3a9b6f9405ab35eea230a05e18098c68d03d9..c70aaf9488dc93195f8c2c4fe45bba179be2adef 100644
--- a/i18n/hr.i18n.json
+++ b/i18n/hr.i18n.json
@@ -4,6 +4,7 @@
   "Accounts" : "Računi",
   "Accounts_AllowPasswordChange" : "Dopusti promjenu lozinke",
   "Accounts_AllowUsernameChange" : "Dopusti promjenu korisničkog imena",
+  "Accounts_AvatarResize" : "Promjeni veličinu Avatara",
   "Accounts_AvatarSize" : "Veličina Avatara",
   "Accounts_denyUnverifiedEmail" : "Odbij neprovjereni e-mail",
   "Accounts_EmailVerification" : "E-mail Verifikacija",
@@ -18,6 +19,7 @@
   "Accounts_OAuth_Linkedin" : "LinkedIn Prijava",
   "Accounts_OAuth_Meteor" : "Meteor Prijava",
   "Accounts_OAuth_Twitter" : "Twitter Prijava",
+  "Accounts_PasswordReset" : "Resetiraj lozinku",
   "Accounts_RegistrationRequired" : "Potrebna je registracija",
   "Activate" : "Aktiviraj",
   "Add_Members" : "Dodaj ÄŒlanove",
@@ -26,6 +28,7 @@
   "All_channels" : "Svi kanali",
   "and" : "i",
   "API_Analytics" : "Analitika",
+  "Archive" : "Arhiva",
   "are_also_typing" : "isto tipkaju",
   "are_typing" : "tipkaju",
   "Are_you_sure" : "Jesi li siguran?",
@@ -46,12 +49,15 @@
   "busy_male" : "zauzet",
   "Busy_male" : "Zauzet",
   "Cancel" : "Otkaži",
+  "CDN_PREFIX" : "CDN Prefiks",
   "Change_avatar" : "Promijeni avatar",
   "Channels" : "Kanali",
   "Channels_list" : "Lista javnih kanala",
   "Chat_Rooms" : "Chat Sobe",
+  "Clear_all_unreads_question" : "Makni sve nepročitane?",
   "close" : "zatvori",
   "coming_soon" : "dolazi uskoro",
+  "Commands" : "Naredbe",
   "Confirm_password" : "Potvrdi svoju lozinku",
   "Contact" : "Kontakt",
   "Conversation" : "Razgovor",
@@ -78,12 +84,15 @@
   "Email_already_exists" : "Email već postoji",
   "Email_or_username" : "Email or username",
   "Email_verified" : "Email provjeren",
+  "Emoji" : "Emoji",
   "Enter_info" : "Unesi svoje informacije za prijavu",
   "Enter_to" : "Uđi u ",
+  "Error" : "Pogreška",
   "Error_changing_password" : "Lozinka je izmijenjena",
   "Esc_to" : "Pobjegni iz",
   "False" : "Ne",
   "Favorites" : "Omiljeni",
+  "FileUpload_ProtectFiles" : "Zaštitite uploadane datoteke",
   "Follow_social_profiles" : "Slijedi naše socijalne profile, forkaj chat na githubu i podijeli svoje misli o rocket.chat aplikaciji na našoj trello ploči.",
   "Forgot_password" : "Zaboravih lozinku",
   "Fork_it_on_github" : "Forkaj na githubu",
@@ -98,6 +107,8 @@
   "Incorrect_Password" : "Netočna lozinka",
   "inline_code" : "jednolinijski kôd",
   "Install_FxOs" : "Instalirajte Rocket.Chat na svoj Firefox",
+  "Install_FxOs_error" : "Nažalost, to nije uspjelo onako kako smo zamislili! Pojavila se sljedeća greška:",
+  "Integration_added" : "Integracija je dodana",
   "Invalid_confirm_pass" : "Potvrda lozinke se ne slaže sa lozinkom",
   "Invalid_email" : "Uneseni e-mail nije valjan",
   "Invalid_name" : "Ime ne smije biti prazno",
@@ -115,6 +126,8 @@
   "italics" : "ukosi",
   "join" : "Pridruži se",
   "Join_the_Community" : "Pridruži se zajednici",
+  "Jump_to_message" : "Skoči na poruku",
+  "Jump_to_recent_messages" : "Skoči na nedavne poruke",
   "Language" : "Jezik",
   "Language_Version" : "Engleska Verzija",
   "Last_login" : "Zadnja prijava",
@@ -175,6 +188,7 @@
   "No_group_with_name_%s_was_found" : "Privatna grupa s tim imenom nije nađena",
   "No_groups_yet" : "Još nemaš privatnih grupa.",
   "No_permission_to_view_room" : "Nemaš dopuštenje da vidiš ovu sobu",
+  "No_results_found" : "Rezultati nisu nađeni",
   "No_user_with_username_%s_was_found" : "Korisnik sa korisničkim imenom <strong>\"%s\"</strong> nije nađen!",
   "Not_allowed" : "Nije dozvoljeno",
   "Not_found_or_not_allowed" : "Nije Nađeno ili Nije Dozvoljeno",
@@ -193,6 +207,7 @@
   "Please_wait" : "Pričekaj",
   "Please_wait_activation" : "Molimo pričekajte, ovo bi moglo potrajati neko vrijeme.",
   "Please_wait_statistics" : "Molimo pričekajte, statistike se generiraju.",
+  "Post_as" : "Pošalji kao",
   "Powered_by" : "Powered by",
   "Preferences" : "Postavke",
   "Preferences_saved" : "Postavke sačuvane",
@@ -208,13 +223,18 @@
   "Quick_Search" : "Brza Pretraga",
   "quote" : "c",
   "Recents" : "Nedavni",
+  "Record" : "Snimaj",
   "Register" : "Registriraj novi račun",
   "Registration_Succeeded" : "Registracija je uspjela ",
   "Remember_me" : "Zapamti me",
   "Remove" : "Makni",
   "Remove_Admin" : "Makni Administratora",
+  "Remove_from_room" : "Uklonite iz sobe",
+  "Removed" : "Uklonjeno",
   "Reset_password" : "Resetiraj lozinku",
   "Room" : "Soba",
+  "Room_archived" : "Soba je arhivirana",
+  "Room_has_been_deleted" : "Soba je obrisana",
   "Room_name_changed" : "Ime sobe promijenjeno u: <em>__room_name__</em> od <em>__user_by__</em>",
   "Room_name_changed_successfully" : "Ime sobe je uspješno izmijenjeno",
   "Room_not_found" : "Soba nije nađena",
@@ -223,6 +243,7 @@
   "room_user_count" : "% korisnika",
   "Rooms" : "Sobe",
   "S_new_messages_since_s" : "novih poruka od",
+  "SAML_Custom_Cert" : "Prilagođeni Certifikat",
   "SAML_Custom_Generate_Username" : "Izradi korisničko ime",
   "Save_changes" : "Spremi promjene",
   "Search" : "Traži",
@@ -244,11 +265,14 @@
   "Send_Message" : "Pošalji Poruku",
   "Settings" : "Postavke",
   "Settings_updated" : "Postavke su ažurirane",
+  "Should_exists_a_user_with_this_username" : "Korisnik mora već postojati.",
   "Showing_online_users" : "Prikazujem <b>__total_online__</b> od __total__ korisnika",
   "Showing_results" : "<p>Prikazujem <b>%s</b> rezultata</p>",
   "Silence" : "Tišina",
   "since_creation" : "%s",
   "Site_Name" : "Ime Stranice:",
+  "Site_Url" : "Link web stranice",
+  "Site_Url_Description" : "Primjer: https://chat.domain.com/",
   "SMTP_Password" : "SMTP lozinka",
   "SMTP_Port" : "SMTP port",
   "SMTP_Username" : "SMTP korisničko ime",
@@ -272,8 +296,11 @@
   "Stats_Total_Private_Groups" : "Ukupno Privatnih Grupa",
   "Stats_Total_Rooms" : "Ukupno soba",
   "Stats_Total_Users" : "Ukupno korisnika",
+  "Stop_Recording" : "Prestani sa snimanjem",
   "strike" : "precrtaj",
   "Submit" : "Pošalji",
+  "Success" : "Uspjeh",
+  "The_channel_name_is_required" : "Ime kanala je potrebno",
   "The_field_is_required" : "Polje% s je traženo.",
   "True" : "Da",
   "Unnamed" : "Neimenovan",
@@ -302,6 +329,7 @@
   "User_logged_out" : "Korisnik je odjavljen",
   "User_not_found_or_incorrect_password" : "Korisnik nije pronađen ili pogrešna lozinka",
   "User_removed_by" : "Korisnik <em>__user_removed__</em> maknut od <em>__user_by__</em>.",
+  "User_removed_from_room" : "Korisnik je uklonjen iz sobe",
   "User_Settings" : "Korisničke postavke",
   "User_updated_successfully" : "Korisnik je uspješno ažuriran",
   "Username" : "Korisničko ime",
@@ -319,6 +347,8 @@
   "Welcome" : "Dobro došao/la<em>%s</em>.",
   "Welcome_to_the" : "Dobro došli »",
   "With_whom" : "Sa kim",
+  "Yes" : "Da",
+  "Yes_clear_all" : "Da, makni sve!",
   "Yes_delete_it" : "Da, obriši!",
   "you_are_in_preview_mode_of" : "Ti si u preglednom načinu kanala # <strong>__room_name__</strong>",
   "You_need_confirm_email" : "Trebaš potvrditi svoj email kako bi se prijavio!",
diff --git a/i18n/km.i18n.json b/i18n/km.i18n.json
index 696cdec725e1aa06d2bbb41863d002c95de09609..1051095f4d3b76dc7ccc5d229ce6f75a47f2c442 100644
--- a/i18n/km.i18n.json
+++ b/i18n/km.i18n.json
@@ -44,6 +44,7 @@
   "Accounts_OAuth_Twitter_id" : "លេខសម្គាល់ Twitter",
   "Accounts_OAuth_Twitter_secret" : "Twitter សម្ងាត់",
   "Accounts_RegistrationRequired" : "ត្រូវ​ចុះ​ឈ្មោះ",
+  "Accounts_RequireNameForSignUp" : "ត្រូវការ Name សម្រាប់ការចុះឈ្មោះ",
   "Activate" : "ធ្វើ​ឱ្យ​សកម្ម",
   "Add_custom_oauth" : "បន្ថែម oauth ផ្ទាល់​ខ្លួន",
   "Add_Members" : "ថែម​សមាជិក",
@@ -62,6 +63,7 @@
   "Are_you_sure" : "តើ​អ្នក​ច្បាស់​ហើយ​ឬ?",
   "Auto_Load_Images" : "ផ្ទុក​រូបភាព​ដោយ​ស្វ័យប្រវត្តិ",
   "Avatar_changed_successfully" : "ផ្លាស់​ប្តូ​រ​រូប​តំ​នាង​ដោយ​ជោគជ័យ",
+  "Avatar_url_invalid_or_error" : "តំណភ្ជាប់ដែលបានមិនត្រឹមត្រូវ ដូចនេះសូមព្យាយាមម្តងទៀត ប៉ុន្តែជាមួយតំណភ្ជាប់ផ្សេងទៀត។",
   "away" : "ឆ្ងាយ",
   "Away" : "ឆ្ងាយ",
   "away_female" : "ឆ្ងាយ",
@@ -191,6 +193,7 @@
   "LDAP_Port" : "ច្រក LDAP",
   "LDAP_Port_Description" : "ផែដើម្បីចូលទៅកាន់ LDAP ត្រង់លេខ; ឧទាហរណ៍៖ 389 ",
   "LDAP_Sync_User_Data" : "រក្សាទិន្នន័យ User ដោយ Sync ជាមួយ Server",
+  "LDAP_Sync_User_Data_Description" : "រក្សាទិន្នន័យអ្នកប្រើប្រាស់ក្នុងការ Sync ជាមួយម៉ាស៊ីនមេក្នុងការ Login (eg: name, email)។",
   "LDAP_Url" : "URL របស់ LDAP",
   "Leave_room" : "ចេញ​ពីបន្ទប់",
   "line" : "ជួរ",
@@ -213,6 +216,7 @@
   "Message_AllowEditing_BlockEditInMinutes" : "បិទការកែស្រួលសារបន្ទាប់ (ជាចំនួននាទី ឬ0ដើម្បីបិទចោល)",
   "Message_AllowEditing_BlockEditInMinutesDescription" : "បញ្ចូលលេខ 0 ដើម្បីបិទការ Block",
   "Message_AudioRecorderEnabled" : "ការថតសម្លេងបានអនុញ្ញាតិ",
+  "Message_AudioRecorderEnabledDescription" : "ត្រូវការឯកសារប្រភេទ 'audio/wav' ក្នុងការកំណត់ 'File Upload' ",
   "Message_deleting_not_allowed" : "ការ​លប់សារ​មិន​ត្រូវ​បាន​អនុញ្ញាតិ",
   "Message_editing_blocked" : "សារ​នេះ​មិន​អាច​ត្រូវ​បាន​កែប្រែ​ទៀត​ទេ",
   "Message_editing_not_allowed" : "ការ​កែ​សម្រួល​សារ​មិន​ត្រូវ​បាន​អនុញ្ញាតិ",
@@ -241,6 +245,7 @@
   "n_messages" : "%s សារ",
   "Name" : "Name",
   "Name_cant_be_empty" : "ឈ្មោះ​មិន​អាច​ទទេ",
+  "Name_optional" : "ឈ្មោះ (ស្រេច​ចិត្ត​)",
   "New_messages" : "សារ​ថ្មី",
   "New_password" : "ពាក្យ​សម្ងាត់​ថ្មី",
   "No_channel_with_name_%s_was_found" : "មិន​មាន​ប៉ុស្តិ៍​ឈ្មោះ <strong>\"%s\"</strong> ឡើយ​",
diff --git a/i18n/ko.i18n.json b/i18n/ko.i18n.json
index b066ea7f2afd42ec203fa256ef514e5022397add..3804dedd2f5d712f253fbd33b1a2f8d99f1e05a5 100644
--- a/i18n/ko.i18n.json
+++ b/i18n/ko.i18n.json
@@ -1,13 +1,21 @@
 {
+  "Access_not_authorized" : "액세스 권한이 없습니다",
   "Access_online_demo" : "온라인 데모 접속",
   "Access_Online_Demo" : "온라인 데모 접속",
   "Accounts" : "계정",
+  "Accounts_AllowedDomainsList" : "허용 가능한 도메인 목록",
+  "Accounts_AllowPasswordChange" : "암호 변경 허용",
   "Accounts_AllowUserAvatarChange" : "사용자 아바타 변경을 허용",
+  "Accounts_AllowUsernameChange" : "사용자 이름 변경 허용",
   "Accounts_AllowUserProfileChange" : "사용자 프로필 변경을 허용",
+  "Accounts_AvatarResize" : "아바타 크기 조정",
   "Accounts_AvatarSize" : "아바타 크기",
+  "Accounts_AvatarStorePath" : "아바타 저장 경로",
+  "Accounts_AvatarStoreType" : "아바파 저장 타입",
   "Accounts_denyUnverifiedEmail" : "확인되지 않은 이메일 거부",
   "Accounts_EmailVerification" : "이메일 확인",
-  "Accounts_ManuallyApproveNewUsers" : "직접 새로운 사용자 허용",
+  "Accounts_Enrollment_Email" : "등록한 이메일",
+  "Accounts_ManuallyApproveNewUsers" : "수동으로 새로운 사용자 승인",
   "Accounts_OAuth_Custom_Authorize_Path" : "Authorize 경로",
   "Accounts_OAuth_Custom_Button_Color" : "버튼 색",
   "Accounts_OAuth_Custom_Button_Label_Color" : "버튼 텍스트 색",
@@ -25,6 +33,8 @@
   "Accounts_OAuth_Github_id" : "Github ID",
   "Accounts_OAuth_Github_secret" : "Github 암호",
   "Accounts_OAuth_Gitlab" : "OAuth 활성화",
+  "Accounts_OAuth_Gitlab_id" : "Gitlab ID",
+  "Accounts_OAuth_Gitlab_secret" : "Client 암호",
   "Accounts_OAuth_Google" : "구글 로그인",
   "Accounts_OAuth_Google_id" : "구글 ID",
   "Accounts_OAuth_Google_secret" : "구글 암호",
@@ -37,6 +47,12 @@
   "Accounts_OAuth_Twitter" : "트위터 로그인",
   "Accounts_OAuth_Twitter_id" : "트위터 ID",
   "Accounts_OAuth_Twitter_secret" : "트위터 암호",
+  "Accounts_PasswordReset" : "암호 재설정",
+  "Accounts_RegistrationForm" : "등록 양식",
+  "Accounts_RegistrationForm_Disabled" : "비활성화",
+  "Accounts_RegistrationForm_Public" : "공개",
+  "Accounts_RegistrationForm_Secret_URL" : "비밀 URL",
+  "Accounts_RegistrationForm_SecretURL" : "등록 양식 비밀 URL",
   "Accounts_RegistrationRequired" : "등록시 필수",
   "Activate" : "활성화",
   "Add_custom_oauth" : "사용자 정의 OAuth 추가",
@@ -44,15 +60,19 @@
   "Add_users" : "사용자 추가",
   "Administration" : "관리",
   "All_channels" : "모든 채널",
+  "Allow_Invalid_SelfSigned_Certs" : "잘못된 Self-Signed Certs 허용",
   "and" : "그리고",
   "API" : "API",
   "API_Analytics" : "분석",
   "API_Embed" : "포함",
+  "API_EmbedDisabledFor" : "사용자에대한 Embed 비활성화",
+  "API_EmbedDisabledFor_Description" : "쉼표로 구분된 사용자 이름 목록",
   "are_also_typing" : "또한 입력중",
   "are_typing" : "입력 중",
   "Are_you_sure" : "괜찮아요?",
   "Auto_Load_Images" : "이미지 자동 로드",
   "Avatar_changed_successfully" : "아바타를 성공적으로 변경하였습니다",
+  "Avatar_url_invalid_or_error" : "지정된 URL이 잘못되었거나 접근할 수 없습니다. 다른 URL로 다시 시도하세요.",
   "away" : "자리비움",
   "Away" : "자리비움",
   "away_female" : "자리비움",
@@ -68,26 +88,31 @@
   "busy_male" : "바쁨",
   "Busy_male" : "바쁨",
   "Cancel" : "취소",
+  "CDN_PREFIX" : "CDN Prefix",
+  "Certificates_and_Keys" : "인증서와 키",
   "Change_avatar" : "아바타 변경",
   "Channels" : "채널",
   "Channels_list" : "공개 채널 리스트",
   "Chat_Rooms" : "채팅방",
+  "Clear_all_unreads_question" : "읽지 않은 메시지를 삭제합니까?",
   "close" : "닫기",
   "coming_soon" : "곧",
   "Commands" : "명령",
+  "Compact_View" : "축소해 보기",
   "Confirm_password" : "암호를 확인하세요",
   "Contact" : "접속",
   "Conversation" : "대화",
-  "Convert_Ascii_Emojis" : "ASCII를 Emojis로 변환",
+  "Convert_Ascii_Emojis" : "이모지를 ASCII로 변환",
   "Create_new" : "새로 만들기",
   "Create_new_direct_message_room" : "새 귓속말 방 만들기 ",
-  "Create_new_private_group" : "새로운 개인 그룹을 만듭니다",
-  "Create_new_public_channel" : "새 공용 채널 생성",
+  "Create_new_private_group" : "새로운 비밀 그룹을 만듭니다",
+  "Create_new_public_channel" : "새 공개 채널 생성",
   "Created_at" : "제작",
+  "Custom_oauth_helper" : "OAuth Provider를 설정할때, 콜백 URL을 알려줘야합니다. <pre>%s</pre>를 사용.",
   "Custom_oauth_unique_name" : "사용자 정의 OAuth 고유한 이름",
   "days" : "일",
   "Deactivate" : "비활성화",
-  "Delete_Room_Warning" : "방을 삭제하면 방의 모든 메시지를 삭제합니다. 이 작업은 되돌릴 수 없습니다.",
+  "Delete_Room_Warning" : "방을 삭제하면 모든 메시지가 삭제됩니다. 이 작업은 취소할 수 없습니다.",
   "Delete_User_Warning" : "사용자 삭제시 사용자의 모든 메시지를 삭제합니다. 취소할 수 없습니다.",
   "Deleted" : "삭제!",
   "Desktop_Notifications" : "바탕화면 알림",
@@ -97,27 +122,34 @@
   "Disable_Favorite_Rooms" : "즐겨찾기 사용안함",
   "Disable_New_Message_Notification" : "새 메시지 알림 비활성화",
   "Disable_New_Room_Notification" : "새 방 알림 비활성화",
+  "Do_you_want_to_change_to_s_question" : "<strong>%s</strong>으로 변경합니까?",
   "Drop_to_upload_file" : "업로드할 파일 드롭",
   "Duplicate_channel_name" : "'%s' 채널 이름은 이미 존재합니다.",
-  "Duplicate_private_group_name" : "'%s'는 이미 존재하는 개인 그룹입니다.",
+  "Duplicate_private_group_name" : "'%s'는 이미 존재하는 비밀 그룹입니다.",
   "E-mail" : "이메일",
   "edited" : "수정됨",
   "Email_already_exists" : "이메일이 이미 존재합니다",
   "Email_or_username" : "이메일 또는 사용자 이름",
   "Email_verified" : "Email 확인",
   "Emoji" : "Emoji",
+  "Enable_Desktop_Notifications" : "바탕화면 알림 활성화",
   "Enter_info" : "로그인 정보를 입력하세요",
   "Enter_to" : "Enter to",
-  "Error_changing_password" : "암호 변경 중 오류 발생",
+  "Error" : "오류",
+  "Error_changing_password" : "암호 변경 중 오류 발생",
+  "Error_too_many_requests" : "너무 많은 요청으로 에러발생. 천천히 하세요. %s 초 이후 입력할 수 있습니다",
   "Esc_to" : "Esc to",
   "False" : "False",
   "Favorites" : "즐겨찾기",
   "FileUpload" : "파일 업로드",
+  "FileUpload_Enabled" : "파일 업로드 활성화",
   "FileUpload_MaxFileSize" : "파일 업로드 최대 크기 (바이트 단위)",
+  "FileUpload_MediaTypeWhiteList" : "허용 가능한 미디어 타입",
+  "FileUpload_MediaTypeWhiteListDescription" : "쉼표로 구분된 미디어 타입 목록",
   "Follow_social_profiles" : "소셜 프로파일에 따라주십시오. Github에서 포크하고, 우리의 trello 보드에서 rocket.chat app에대한 의견을 공유합니다.",
   "Forgot_password" : "암호를 잊었습니다",
   "Fork_it_on_github" : "Github에서 포크",
-  "From_Email" : "이메일로부터",
+  "From_Email" : "이메일에서",
   "General" : "일반",
   "Get_to_know_the_team" : "Rocket.Team 알아보기",
   "github_no_public_email" : "Github 계정에 공개된 이메일이 없습니다.",
@@ -129,11 +161,19 @@
   "hours" : "시간",
   "Incorrect_Password" : "잘못된 암호",
   "inline_code" : "inline_code",
+  "Install_FxOs" : "파이어폭스에 Rocket.Chat 설치",
+  "Install_FxOs_done" : "좋습니다! 홈 스크린의 아이콘을 통해 Rock.Chat을 사용할 수 있습니다. Rock.Chat과 즐거운 시간을 보내십시오.",
+  "Install_FxOs_error" : "미안, 의도한대로 작동하지 않았습니다. 에러가 발생했습니다:",
+  "Install_FxOs_follow_instructions" : "장치에 응용 프로그램 설치를 확인하십시오 ( \"설치\" 메시지가 뜨면).",
   "Invalid_confirm_pass" : "암호가 일치하지 않습니다",
   "Invalid_email" : "입력한 이메일이 잘못되었습니다",
+  "Invalid_file_height" : "잘못된 파일 높이",
+  "Invalid_file_type" : "잘못된 파일 형식",
+  "Invalid_file_width" : "잘못된 파일 너비",
   "Invalid_name" : "이름을 비워 둘 수 없습니다",
   "Invalid_pass" : "암호를 비워 둘 수 없습니다",
   "Invalid_room_name" : "<strong>%s</strong>은 사용 가능한 방 이름이 아닙니다.<br/>소문자, 숫자, 대시만 사용할 수 있습니다",
+  "Invalid_Secret_URL" : "잘못된 비밀 URL",
   "invisible" : "보지 않음",
   "Invisible" : "보지 않음",
   "Invitation_HTML" : "HTML 초대 페이지",
@@ -162,9 +202,14 @@
   "Layout_Sidenav_Footer_description" : "바닥글 크기는 260x70입니다.",
   "Layout_Terms_of_Service" : "이용약관",
   "LDAP" : "LDAP",
+  "LDAP_Bind_Search" : "검색 감추기",
   "LDAP_Description" : "LDAP는 많은 기업들이 통합 인증을 제공하기 위해 사용하는 계층적인 데이터베이스입니다. 여러 사이트와 서비스 간에 하나의 암호를 공유하기 위한 기능으로, 자세한 정보는 위키를 참고하세요: https://github.com/RocketChat/Rocket.Chat/wiki/LDAP",
-  "LDAP_DN" : "LDAP DN",
+  "LDAP_DN" : "고유 이름 (DN)",
+  "LDAP_Enable" : "LDAP 사용",
   "LDAP_Port" : "LDAP 포트",
+  "LDAP_Sync_User_Data" : "데이터 동기화",
+  "LDAP_Sync_User_Data_Description" : "서버에 로그인할 때 사용자 데이터의 동기화를 유지하세요(예: 이름, 이메일).",
+  "LDAP_Sync_User_Data_FieldMap" : "사용자 데이터 필드 맵",
   "LDAP_Url" : "LDAP URL",
   "Leave_room" : "방 나가기",
   "line" : "밑줄",
@@ -178,13 +223,17 @@
   "Logout" : "로그아웃",
   "Make_Admin" : "관리자 권한 생성",
   "Mark_as_read" : "읽었음",
+  "Markdown_Headers" : "마크다운 해더",
   "Members" : "멤버",
   "Members_List" : "멤버 리스트",
   "Members_placeholder" : "멤버",
   "Message" : "메시지",
   "Message_AllowDeleting" : "메시지 삭제 허용",
   "Message_AllowEditing" : "메시지 수정 허용",
-  "Message_AllowEditing_BlockEditInMinutes" : "이후로 메시지 수정 안됨 (분 - 0 은 사용안함)",
+  "Message_AllowEditing_BlockEditInMinutes" : "(n) 분 이후로 수정할 수 없습니다",
+  "Message_AllowEditing_BlockEditInMinutesDescription" : "0을 입력하면 블로킹 비활성화",
+  "Message_AudioRecorderEnabled" : "음성 녹음 활성화",
+  "Message_AudioRecorderEnabledDescription" : "'audio/wav' 파일은 '파일 업로드' 설정에서 허용한 미디어 타입이어야 합니다.",
   "Message_deleting_not_allowed" : "메시지 삭제를 할 수 없습니다.",
   "Message_editing_blocked" : "메시지를 더 이상 수정할 수 없습니다.",
   "Message_editing_not_allowed" : "메시지 수정을 할 수 없습니다.",
@@ -195,13 +244,14 @@
   "Message_removed" : "메시지 제거",
   "Message_ShowDeletedStatus" : "삭제된 상태 확인",
   "Message_ShowEditedStatus" : "수정 상태 확인",
+  "Message_ShowFormattingTips" : "포멧 팁 보기",
   "Messages" : "메시지",
   "Meta" : "메타",
   "Meta_fb_app_id" : "페이스북 APP ID",
   "Meta_google-site-verification" : "Google 사이트 확인",
   "Meta_language" : "언어",
   "Meta_msvalidate01" : "MSValidate.01",
-  "Meta_robots" : "검색 로봇",
+  "Meta_robots" : "로봇",
   "minutes" : "분",
   "More_channels" : "추가 채널",
   "More_groups" : "비밀 그룹 더보기",
@@ -218,12 +268,13 @@
   "No_channel_with_name_%s_was_found" : "<strong>\"%s\"</strong> 채널 이름을 찾을 수 없습니다!",
   "No_channels_yet" : "어떠한 채널에도 가입하지 않았습니다.",
   "No_direct_messages_yet" : "어떤 귓속말도 하지 않았습니다.",
-  "No_favorites_yet" : "즐겨찾기가 없습니다.",
+  "No_favorites_yet" : "아직 즐겨찾기를 추가하지 않았습니다.",
   "No_group_with_name_%s_was_found" : "<strong>\"%s\"</strong> 비밀 그룹 이름을 찾을 수 없습니다!",
-  "No_groups_yet" : "개인 그룹을 만들지 않았습니다.",
+  "No_groups_yet" : "비밀 그룹을 만들지 않았습니다.",
   "No_permission_to_view_room" : "이 방을 볼 수 있는 권한이 없습니다",
   "No_user_with_username_%s_was_found" : "<strong>\"%s\"</strong> 사용자 이름을 가진 사용자를 찾을 수 없습니다!",
   "Not_allowed" : "허용되지 않음",
+  "Not_authorized" : "권한이 없습니다",
   "Not_found_or_not_allowed" : "찾을 수 없거나 허용되지 않았습니다",
   "Nothing_found" : "찾을 수 없습니다",
   "Notify_all_in_this_room" : "이 방에 있는 모든이에게 알림",
@@ -233,19 +284,21 @@
   "Only_you_can_see_this_message" : "이 메시지는 당신만 볼 수 있습니다",
   "Oops!" : "ì•„ì°¨",
   "Opt_out_statistics" : "나의 어떤 무기명 통계도 Rocket.chat으로 보내지 마십시오.",
-  "Opt_out_statistics_warning" : "당신의 무기명 통계 자료를 전송하는 것으로 우리는 몇개의 Rocket.Chat 서비스를 설치하였는지 알 수 있으며 얼마나 시스템이 잘 작동하는지 알 수록 서비스를 개선하는데 도움이 됩니다. 만일 무기명 통계 정보를 전송하길 원하시면 위의 체크박스를 설정을 해제해주십시오. 고맙습니다.",
+  "Opt_out_statistics_warning" : "배포된 Rocket.Chat에대한 여럿 인스턴스들을 확인하여 통계를 전송하게되면 우리는 문제점을 확인하고 더 좋은 시스템을 만들 수 있습니다. 사용자 정보를 보내지 않으며, 우리가 받은 정보는 모두 비밀유지가 됩니다. 만약 계속해서 통계를 보내고 싶다면 체크박스를 해제하시면 됩니다. 감사합니다.",
   "others" : "다른 사람",
   "Password" : "암호",
+  "Password_Change_Disabled" : "Rock.Chat 관리자는 암호 변경을 할 수 없습니다.",
   "Password_changed_successfully" : "암호를 성공적으로 변경하였습니다.",
   "People" : "사람들",
+  "Please_enter_value_for_url" : "아바타 URL을 입력하십시오.",
   "Please_wait" : "잠시만 기다려 주세요.",
   "Please_wait_activation" : "시간이 좀 걸릴 수 있습니다. 잠시만 기다려주십시오.",
   "Please_wait_statistics" : "통계를 생성 중입니다. 잠시만 기다려주십시오.",
   "Powered_by" : "Powered by",
   "Preferences" : "설정",
   "Preferences_saved" : "설정 저장함.",
-  "Privacy" : "개인정보보호",
-  "Private_Groups" : "개인 그룹",
+  "Privacy" : "프라이버시",
+  "Private_Groups" : "비밀 그룹",
   "Private_Groups_list" : "비밀 그룹 목록",
   "Profile" : "프로필",
   "Profile_saved_successfully" : "프로필을 성공적으로 저장",
@@ -257,9 +310,12 @@
   "Push_apn_dev_passphrase" : "APN 개발 암호",
   "Push_apn_key" : "APN 키",
   "Push_apn_passphrase" : "APN 암호",
-  "Push_debug" : "디버그",
-  "Push_enable" : "사용",
+  "Push_debug" : "Debug",
+  "Push_enable" : "사용 가능",
+  "Push_gcm_api_key" : "GCM API Key",
+  "Push_gcm_project_number" : "GCM 프로젝트 번호",
   "Push_production" : "Production",
+  "Push_test_push" : "테스트",
   "Quick_Search" : "빠른 찾기",
   "quote" : "인용",
   "Recents" : "최근",
@@ -270,15 +326,25 @@
   "Remove" : "삭제",
   "Remove_Admin" : "관리자 권한 제거",
   "Remove_custom_oauth" : "사용자 정의 OAuth 제거",
+  "Removed" : "제거됨",
   "Reset_password" : "암호 재설정",
+  "Restart" : "재시작",
   "Room" : "ë°©",
+  "Room_has_been_deleted" : "방이 삭제되었습니다",
   "Room_name_changed" : "방 이름 변경: <em>__user_by__</em>에서 <em>__room_name__</em>로.",
   "Room_name_changed_successfully" : "방 이름 변경 완료",
   "Room_not_found" : "방을 찾을 수 없습니다.",
   "Room_uploaded_file_list" : "파일 목록",
+  "Room_uploaded_file_list_empty" : "파일을 사용할 수 없습니다.",
   "room_user_count" : "%s 사용자",
   "Rooms" : "ë°©",
+  "S_new_messages_since_s" : "%s 새로운 메시지 %s 이후로",
   "SAML" : "SAML",
+  "SAML_Custom_Cert" : "커스텀 인증",
+  "SAML_Custom_Entry_point" : "커스텀 접근 포인트",
+  "SAML_Custom_Generate_Username" : "사용자 이름 생성",
+  "SAML_Custom_Issuer" : "커스텀 발급자",
+  "SAML_Custom_Provider" : "커스텀 제공자",
   "Save_changes" : "변경사항 저장",
   "Save_Mobile_Bandwidth" : "모바일 대역폭 저장",
   "Search" : "검색",
@@ -303,9 +369,9 @@
   "Settings_updated" : "설정 업데이트",
   "Showing_online_users" : "__total__ 사용자의 <b>__total_online__</b> 표시",
   "Showing_results" : "<p><b>%s</b> 결과 확인</p>",
-  "Silence" : "무언",
+  "Silence" : "소리끄기",
   "since_creation" : "%s 이후",
-  "Site_Name" : "사이트 이름:",
+  "Site_Name" : "사이트 이름",
   "Site_Url" : "사이트 URL",
   "Site_Url_Description" : "예: https://chat.domain.com/",
   "SMTP" : "SMTP",
@@ -319,11 +385,11 @@
   "Stats_Active_Users" : "활성 사용자",
   "Stats_Avg_Channel_Users" : "채널 사용자 평균",
   "Stats_Avg_Private_Group_Users" : "비밀 그룹 사용자 평균",
-  "Stats_Away_Users" : "자리비움 사용자",
+  "Stats_Away_Users" : "사용자 자리비움",
   "Stats_Max_Room_Users" : "최대 방 사용자",
   "Stats_Non_Active_Users" : "비활성 사용자",
-  "Stats_Offline_Users" : "현실 세계인",
-  "Stats_Online_Users" : "가상 세계인",
+  "Stats_Offline_Users" : "오프라인 사용자",
+  "Stats_Online_Users" : "온라인 사용자",
   "Stats_OS_Arch" : "OS Arch",
   "Stats_OS_Cpus" : "OS CPU 갯수",
   "Stats_OS_Freemem" : "OS 빈 메모리",
@@ -342,17 +408,23 @@
   "Stop_Recording" : "기록 중지",
   "strike" : "취소선",
   "Submit" : "제출",
+  "Success" : "성공",
+  "The_channel_name_is_required" : "채널 이름이 필요합니다",
   "The_field_is_required" : "필드 %s는 필요합니다.",
+  "The_image_resize_will_not_work_because_we_can_not_detect_ImageMagick_or_GraphicsMagick_installed_in_your_server" : "당신의 서버에 ImageMagick 또는 GraphicMagick이 설치되어 있지 않아 이미지 크기를 재조정할 수 없습니다.",
+  "The_server_will_restart_in_s_seconds" : "서버가 %s 초 후 재시작합니다.",
   "True" : "True",
   "Unnamed" : "이름이없는",
   "Upload_file_question" : "파일을 업로드하시겠습니까?",
-  "Use_Emojis" : "Emojis 사용",
+  "Uploading_file" : "파일 업로드 중...",
+  "Use_Emojis" : "이모지 사용",
   "Use_initials_avatar" : "사용자 이름을 이니셜로 사용합니다",
   "use_menu" : "사이드 메뉴를 이용하여 방과 채팅에 참여할 수 있습니다",
   "Use_service_avatar" : "아바타 %s 사용",
   "Use_this_username" : "이 사용자 이름 사용",
   "Use_uploaded_avatar" : "업로드된 아바타 사용",
-  "User_added_by" : "사용자 <em>__user_added__</em>을/를 <em>__user_by__</em>에 추가함.",
+  "Use_url_for_avatar" : "아바타 URL 사용",
+  "User_added_by" : "사용자 <em>__user_added__</em>을/를 <em>__user_by__</em>에 추가합니다.",
   "User_Channels" : "사용자 채널",
   "User_has_been_activated" : "사용자가 활성화되었습니다",
   "User_has_been_deactivated" : "사용자가 비활성화되었습니다",
@@ -364,16 +436,17 @@
   "User_joined_channel" : "채널에 참여했습니다.",
   "User_joined_channel_female" : "채널에 참여했습니다.",
   "User_joined_channel_male" : "채널에 참여했습니다.",
-  "User_left" : "사용자 <em>__user_left__</em> 떠남.",
-  "User_left_female" : "사용자 <em>__user_left__</em> 떠남.",
-  "User_left_male" : "사용자 <em>__user_left__</em> 떠남.",
+  "User_left" : "채널을 떠났습니다.",
+  "User_left_female" : "채널을 떠났습니다.",
+  "User_left_male" : "채널을 떠났습니다.",
   "User_logged_out" : "사용자를 로그아웃합니다",
   "User_not_found_or_incorrect_password" : "사용자를 찾을 수 없거나 잘못된 암호입니다",
-  "User_removed_by" : "사용자 <em>__user_removed__</em>을/를 <em>__user_by__</em>에서 삭제됨.",
+  "User_removed_by" : "사용자 <em>__user_removed__</em>을/를 <em>__user_by__</em>에서 삭제하였습니다.",
   "User_Settings" : "사용자 설정",
-  "User_updated_successfully" : "사용자를 성공적으로 업데이트하였습니다.",
+  "User_updated_successfully" : "사용자를 성공적으로 업데이트 하였습니다.",
   "Username" : "사용자 이름",
   "Username_cant_be_empty" : "사용자 이름을 비워둘 수 없습니다",
+  "Username_Change_Disabled" : "Rocket.Chat 관리자는 사용자 이름 변경을 할 수 없습니다.",
   "Username_description" : "사용자 이름은 다른 사람이 메시지에서 언급할 수 있도록 하는데 사용됩니다.",
   "Username_invalid" : "<strong>&s</strong>는 알맞은 사용자명이 아닙니다,<br/> 문자, 숫자, 마침표와 밑줄을 사용하십시오.",
   "Username_title" : "사용자 이름 등록",
@@ -386,9 +459,11 @@
   "Welcome" : "환영합니다, <em>%s</em>.",
   "Welcome_to_the" : "오신것을 환영합니다",
   "With_whom" : "누구랑?",
+  "Yes" : "예",
   "Yes_clear_all" : "예, 전부 지웁니다!",
   "Yes_delete_it" : "예, 삭제합니다!",
   "you_are_in_preview_mode_of" : "#<strong>__room_name__</strong> 채널 미리보기 모드",
+  "You_have_been_muted" : "당신은 이제 이 방에서 듣지도 말하지도 못합니다",
   "You_need_confirm_email" : "로그인하려면 이메일 확인이 필요합니다!",
   "You_will_not_be_able_to_recover" : "이 메시지는 복구할 수 없습니다!",
   "Your_entry_has_been_deleted" : "항목이 삭제되었습니다.",
diff --git a/i18n/lo.i18n.json b/i18n/lo.i18n.json
index 11c7f733bb6bedcb857e01efaff45cf099da5687..68943c27834d15acf71557cf5b710b7494b7ee4b 100644
--- a/i18n/lo.i18n.json
+++ b/i18n/lo.i18n.json
@@ -1,6 +1,6 @@
 {
   "Channels" : "ຊ່ອງ​ທາງ​ການ",
   "edited" : "ແກ້​ໄຂ",
-  "User_left" : "ໄດ້​ປະ​ໄວ້​ຊ່ອງ​ທາງ​ການ​.",
-  "New_password" : "ລະ​ຫັດ​ຜ່ານ​ໃຫມ່"
+  "New_password" : "ລະ​ຫັດ​ຜ່ານ​ໃຫມ່",
+  "User_left" : "ໄດ້​ປະ​ໄວ້​ຊ່ອງ​ທາງ​ການ​."
 }
\ No newline at end of file
diff --git a/i18n/nl.i18n.json b/i18n/nl.i18n.json
index 0e333939023179c68953bb185917bd5d7c27e3ed..6a04b1d6d65c6654bf5706448f104c3d60959f51 100644
--- a/i18n/nl.i18n.json
+++ b/i18n/nl.i18n.json
@@ -1,14 +1,35 @@
 {
+  "Access_not_authorized" : "Toegang niet geautoriseerd",
   "Access_online_demo" : "Toegang tot de online demo",
   "Access_Online_Demo" : "Toegang tot de online demo",
+  "Accounts" : "Accounts",
+  "Accounts_AllowedDomainsList" : "Toegestaan ​​Domeinen Lijst",
+  "Accounts_AllowPasswordChange" : "Toestaan wachtwoord wijzigen",
+  "Accounts_AllowUsernameChange" : "Toestaan wijzigen gebruikersnaam",
+  "Accounts_AvatarResize" : "Wijzig Avatar grootte",
+  "Accounts_AvatarSize" : "Avatar grootte",
   "Accounts_denyUnverifiedEmail" : "Weiger ongeverifieerde e-mail",
   "Accounts_EmailVerification" : "Email verificatie",
+  "Accounts_LoginExpiration" : "Login Vervaltermijn in Dagen",
+  "Accounts_ManuallyApproveNewUsers" : "Handmatig goedkeuren Nieuwe Gebruikers",
+  "Accounts_OAuth_Custom_Authorize_Path" : "Machtigen Path",
+  "Accounts_OAuth_Custom_Button_Color" : "Knop Color",
+  "Accounts_OAuth_Custom_Button_Label_Color" : "Knop Tekst Kleur",
+  "Accounts_OAuth_Custom_Button_Label_Text" : "Knop Tekst",
+  "Accounts_OAuth_Custom_Enable" : "Inschakelen",
+  "Accounts_OAuth_Custom_id" : "Id",
+  "Accounts_OAuth_Custom_Identity_Path" : "Identiteit Path",
+  "Accounts_OAuth_Custom_Login_Style" : "Login Stijl",
+  "Accounts_OAuth_Custom_Secret" : "Geheim",
+  "Accounts_OAuth_Custom_Token_Path" : "Token Path",
+  "Accounts_OAuth_Custom_URL" : "URL",
   "Accounts_OAuth_Facebook" : "Facebook Inloggen",
   "Accounts_OAuth_Facebook_id" : "Facebook App Id",
   "Accounts_OAuth_Facebook_secret" : "Facebook Secret",
   "Accounts_OAuth_Github" : "OAuth Ingeschakeld",
   "Accounts_OAuth_Github_id" : "Client Id",
   "Accounts_OAuth_Github_secret" : "Client Secret",
+  "Accounts_OAuth_Gitlab_id" : "Gitlab Id",
   "Accounts_OAuth_Google" : "Google Inloggen",
   "Accounts_OAuth_Google_id" : "Google Id",
   "Accounts_OAuth_Google_secret" : "Google Secret",
@@ -21,24 +42,43 @@
   "Accounts_OAuth_Twitter" : "Twitter Inloggen",
   "Accounts_OAuth_Twitter_id" : "Twitter Id",
   "Accounts_OAuth_Twitter_secret" : "Twitter Secret",
+  "Accounts_PasswordReset" : "Wachtwoord reset",
+  "Accounts_RegistrationForm" : "Registratieformulier",
+  "Accounts_RegistrationForm_Disabled" : "Uitgeschakeld",
+  "Accounts_RegistrationForm_Public" : "Openbaar",
+  "Accounts_RegistrationForm_Secret_URL" : "Geheime URL",
   "Accounts_RegistrationRequired" : "Registratie vereist",
+  "Activate" : "Activeren",
+  "Add_custom_oauth" : "Voeg aangepaste OAuth toe",
   "Add_Members" : "Voeg leden toe",
   "Add_users" : "Gebruikers toevoegen",
   "Administration" : "Administratie",
+  "Alias" : "Alias",
   "All_channels" : "Alle kanalen",
+  "Allow_Invalid_SelfSigned_Certs" : "Sta Ongeldige Self-Signed Certs toe",
   "and" : "en",
+  "API" : "API",
   "API_Analytics" : "Analytics",
   "API_Embed" : "Embed",
+  "API_EmbedDisabledFor" : "Embed voor gebruikers uitschakelen",
+  "API_EmbedDisabledFor_Description" : "Komma's gescheiden lijst van gebruikersnamen",
+  "Application_added" : "Applicatie toegevoegd",
+  "Application_Name" : "Naam van de toepassing",
+  "Application_updated" : "Applicatie bijgewerkt",
+  "Archive" : "Archiveren",
   "are_also_typing" : "zijn ook aan het typen",
   "are_typing" : "zijn aan het typen",
   "Are_you_sure" : "Weet u het zeker?",
+  "Auto_Load_Images" : "Automatisch afbeeldingen laden",
   "Avatar_changed_successfully" : "Afbeelding is gewijzigd",
+  "Avatar_URL" : "Afbeelding URL",
   "away" : "Afwezig",
   "Away" : "Afwezig",
   "away_female" : "afwezig",
   "Away_female" : "Afwezig",
   "away_male" : "afwezig",
   "Away_male" : "Afwezig",
+  "Back_to_applications" : "Terug naar toepassingen",
   "Back_to_login" : "Terug naar Inloggen",
   "bold" : "vetgedrukt",
   "busy" : "Bezet",
@@ -52,21 +92,39 @@
   "Channels" : "Kanalen",
   "Channels_list" : "Lijst van de openbare kanalen",
   "Chat_Rooms" : "Kanalen",
+  "Choose_the_alias_that_will_appear_before_the_username_in_messages" : "Kies de alias die zal verschijnen voor de gebruikersnaam in berichten.",
+  "Clear_all_unreads_question" : "Wis alle ongelezen?",
+  "Client_ID" : "Client ID",
   "close" : "Sluiten",
   "coming_soon" : "binnekort beschikbaar",
+  "Commands" : "Commando's",
+  "Compact_View" : "Compacte weergave",
   "Confirm_password" : "Bevestig uw wachtwoord",
   "Contact" : "Contact",
   "Conversation" : "Gesprek",
+  "Convert_Ascii_Emojis" : "ASCII naar Emoji Converteren ",
   "Create_new" : "Maak nieuw",
   "Create_new_direct_message_room" : "Maak een nieuw direct bericht kamer",
   "Create_new_private_group" : "Maak een nieuwe privé-groep",
   "Create_new_public_channel" : "Maak een nieuw publiek kanaal",
   "Created_at" : "Gemaakt op",
+  "Created_at_s_by_s" : "Gemaakt op <strong>%s</strong> door <strong>%s</strong>",
+  "Custom_oauth_unique_name" : "Aangepaste OAuth unieke naam",
   "days" : "dagen",
+  "Deactivate" : "Deactiveren",
   "Delete_User_Warning" : "Een gebruiker verwijderen betekent dat alle berichten van die gebruiker ook verwijderd worden. Dit kan niet ongedaan gemaakt worden.",
   "Deleted" : "Verwijderd!",
+  "Desktop_Notifications" : "Desktop Meldingen",
+  "Desktop_Notifications_Disabled" : "Desktop Meldingen zijn uitgeschakeld. Wijzig uw browser voorkeuren als u Meldingen ingeschakeld wil hebben.",
+  "Desktop_Notifications_Enabled" : "Desktop Meldingen zijn ingeschakeld",
   "Direct_Messages" : "Directe berichten",
+  "Disable_Favorite_Rooms" : "Favorieten Uitschakelen",
+  "Disable_New_Message_Notification" : "Notificatie voor nieuwe berichten uitzetten",
+  "Disable_New_Room_Notification" : "Notificatie voor nieuwe kamer/room uitzetten",
+  "Do_you_want_to_change_to_s_question" : "Wilt u <strong>%s</strong> veranderen?",
   "Drop_to_upload_file" : "Sleep hierheen om een bestand te uploaden",
+  "Duplicate_archived_channel_name" : "An gearchiveerd kanaal met naam '%s' bestaat al",
+  "Duplicate_archived_private_group_name" : "An gearchiveerde privé-group met naam '%s' bestaat al",
   "Duplicate_channel_name" : "Een kanaal met de naam '%s' bestaat reeds",
   "Duplicate_private_group_name" : "Een privé-groep met de naam '%s' bestaat reeds",
   "E-mail" : "E-mail",
@@ -74,27 +132,59 @@
   "Email_already_exists" : "Emailadres bestaat al",
   "Email_or_username" : "E-mail of gebruikersnaam",
   "Email_verified" : "E-mail geverifiëerd",
+  "Emoji" : "Emoji",
+  "Enable_Desktop_Notifications" : "Zet Desktop Meldingen aan",
   "Enter_info" : "Voer uw gegevens in",
+  "Enter_to" : "Ga binnen bij",
+  "Error" : "Fout",
   "Error_changing_password" : "Fout bij het veranderen van het wachtwoord",
+  "Error_too_many_requests" : "Fout, te veel verzoeken. Gelieve vertragen. U moet %s seconden wachten alvorens opnieuw te proberen",
+  "Esc_to" : "Esc om",
+  "Example_s" : "Voorbeeld: <code class=\"inline\">%s</code>",
   "False" : "False",
   "Favorites" : "Favorieten",
+  "FileUpload" : "Bestand uploaden",
+  "FileUpload_Enabled" : "File uploaden ingeschakeld",
+  "FileUpload_File_Empty" : "Bestand leeg",
+  "FileUpload_MaxFileSize" : "Maximale bestandgsgrootte voor uploads (in bytes)",
+  "FileUpload_MediaType_NotAccepted" : "Mediatypen niet geaccepteerd",
+  "FileUpload_MediaTypeWhiteList" : "Geaccepteerde Media Types",
+  "FileUpload_ProtectFiles" : "Bescherm geüploade bestanden",
+  "FileUpload_ProtectFilesDescription" : "Alleen geverifieerde gebruikers hebben toegang",
   "Follow_social_profiles" : "Volg ons via de sociale netwerken, kopieer ons op GitHub en deel uw mening over de rocket.chat app op onze Trello pagina.",
   "Forgot_password" : "Wachtwoord vergeten",
   "Fork_it_on_github" : "Kopieer ons op GitHub",
+  "From_Email" : "Afzender e-mail",
+  "General" : "Algemeen",
   "Get_to_know_the_team" : "Maak kennis met het Rocket.Team",
   "github_no_public_email" : "U heeft geen openbaar e-mail adres in uw GitHub toegang",
-  "Have_your_own_chat" : "Gebruik uw eigen webchat. Ontwikkeld met Meteor.com, Rocket.Chat is een goede oplossing voor ontwikkelaars omeenn eigen chat-platform in te richten en te ontwikkelen.",
+  "Give_a_unique_name_for_the_custom_oauth" : "Geef een unieke naam voor de aangepaste OAuth",
+  "Has_more" : "Heeft meer",
+  "Have_your_own_chat" : "Gebruik uw eigen webchat. Ontwikkeld met Meteor.com, Rocket.Chat is een goede oplossing voor ontwikkelaars om een eigen chat-platform in te richten en te verder te ontwikkelen.",
   "Hide_room" : "Kamer verbergen",
   "History" : "Geschiedenis",
   "hours" : "uur",
+  "Incorrect_Password" : "Verkeerd paswoord",
   "inline_code" : "inline_code",
+  "Install_Extension" : "Installeer Uitbreiding",
+  "Install_FxOs" : "Rocket.Chat installeren op uw Firefox-",
+  "Install_FxOs_error" : "Sorry, dat werkte niet zoals de bedoeling! De volgende fout is verschenen:",
+  "Integration_added" : "Integratie is toegevoegd",
+  "Integration_updated" : "Integratie is bijgewerkt",
   "Invalid_confirm_pass" : "De wachtwoorden zijn niet gelijk",
   "Invalid_email" : "Ongeldig e-mail adres",
+  "Invalid_file_height" : "Ongeldige hoogte",
+  "Invalid_file_type" : "Ongeldig bestandstype",
+  "Invalid_file_width" : "Ongeldige breedte",
   "Invalid_name" : "De naam mag niet leeg zijn",
   "Invalid_pass" : "Het wachtwoord mag niet leeg zijn",
   "Invalid_room_name" : "<strong>%s</strong> is geen geldige naam,<br/> gebruik alleen letters, cijfers en streepjes",
+  "Invalid_room_type" : "<strong>%s</strong> is geen geldig kamer type",
   "invisible" : "onzichtbaar",
   "Invisible" : "Onzichtbaar",
+  "Invitation_HTML" : "Uitnodiging HTML",
+  "Invitation_Subject" : "Uitnodiging Onderwerp",
+  "Invite_Users" : "Gebruikers Uitnodigen",
   "is_also_typing" : "is ook aan het typen",
   "is_also_typing_female" : "is ook aan het typen",
   "is_also_typing_male" : "is ook aan het typen",
@@ -104,14 +194,23 @@
   "italics" : "cursief",
   "join" : "Toetreden",
   "Join_the_Community" : "Word lid",
+  "Jump_to_first_unread" : "Naar eerste ongelezen",
+  "Jump_to_message" : "Ga naar bericht",
+  "Jump_to_recent_messages" : "Ga naar recente berichten",
   "Language" : "Taal",
   "Language_Version" : "Nederlndse versie",
   "Last_login" : "Laatste aanmelding",
   "Last_message" : "Laatste bericht",
+  "Layout" : "Lay-out",
   "Layout_Home_Body" : "Home Body",
   "Layout_Home_Title" : "Home Titel",
+  "Layout_Login_Header" : "Login Header",
+  "Layout_Login_Terms" : "Login voorwaarden",
+  "Layout_Privacy_Policy" : "Privacybeleid",
   "Layout_Sidenav_Footer" : "Side Navigation Footer",
   "Layout_Sidenav_Footer_description" : "Footer afmetingen is 260 x 70px",
+  "Layout_Terms_of_Service" : "Algemene Voorwaarden",
+  "LDAP" : "LDAP",
   "LDAP_DN" : "Distinguished Name (DN)",
   "LDAP_Port" : "LDAP Port",
   "LDAP_Url" : "LDAP URL",
@@ -119,24 +218,37 @@
   "line" : "lijn",
   "Load_more" : "Meer laden",
   "Loading..." : "Laden ...",
+  "Loading_more_from_history" : "Meer oude berichten laden",
   "Loading_suggestion" : "Suggesties laden...",
   "Login" : "Log In",
   "Login_with" : "Login met %s",
   "login_with" : "Of log in met",
   "Logout" : "Uitloggen",
   "Make_Admin" : "Maak Admin",
+  "Mark_as_read" : "Markeer als gelezen",
   "Members" : "Leden",
   "Members_List" : "Ledenlijst",
   "Members_placeholder" : "Leden",
   "Message" : "Bericht",
   "Message_AllowDeleting" : "Bericht verwijderen toestaan",
   "Message_AllowEditing" : "Bericht bewerken toestaan",
+  "Message_AllowEditing_BlockEditInMinutes" : "Blokkeer berichtbewerkingen na (n) minuten",
+  "Message_AudioRecorderEnabled" : "Audio Recorder Ingeschakeld",
   "Message_deleting_not_allowed" : "Bericht verwijderen niet toegestaan",
+  "Message_editing_blocked" : "Dit bericht kan niet meer worden bewerkt",
   "Message_editing_not_allowed" : "Bericht bewerken niet toegestaan",
+  "Message_GroupingPeriod" : "Groeperen periode (in seconden)",
+  "Message_GroupingPeriodDescription" : "Berichten worden gegroepeerd met het vorige bericht als beide van dezelfde gebruiker zijn.",
   "Message_KeepHistory" : "Bewaar berichten geschiedenis",
+  "Message_MaxAllowedSize" : "Maximaal toegestane berichtgrootte",
+  "Message_pinned" : "Bericht is vastgezet",
+  "Message_pinning_not_allowed" : "Bericht vastzetten niet toegestaan",
   "Message_removed" : "Bericht verwijderd",
   "Message_ShowDeletedStatus" : "Toon Verwijderde Status",
   "Message_ShowEditedStatus" : "Toon Gewijzigde Status",
+  "Message_ShowFormattingTips" : "Toon opmaaktips",
+  "Messages" : "Berichten",
+  "Meta" : "Meta",
   "Meta_fb_app_id" : "Facebook App Id",
   "Meta_google-site-verification" : "Google Site Verification",
   "Meta_language" : "Taal",
@@ -144,11 +256,16 @@
   "Meta_robots" : "Robots",
   "minutes" : "minuten",
   "More_channels" : "Meer kanalen",
+  "More_groups" : "Meer privé-berichten",
+  "More_unreads" : "Meer ongelezen",
   "Msgs" : "Berichten",
   "multi" : "multi",
+  "Mute_user" : "Maak gebruiker stil",
   "My_Account" : "Mijn account",
   "n_messages" : "%s berichten",
   "Name" : "Naam",
+  "Name_cant_be_empty" : "De naam mag niet leeg zijn",
+  "New_Application" : "Nieuwe toepassing",
   "New_messages" : "Nieuwe berichten",
   "New_password" : "Nieuw Wachtwoord",
   "No_channel_with_name_%s_was_found" : "Geen kanaal met de naam  <strong>\"%s\"</strong> gevonden",
@@ -158,25 +275,42 @@
   "No_group_with_name_%s_was_found" : "Geen privé-groep met de naam  <strong>\"%s\"</strong> gevonden",
   "No_groups_yet" : "U heeft nog geen privé-groepen.",
   "No_permission_to_view_room" : "U heeft geen toestemming dit kanaal te bekijken",
+  "No_results_found" : "Geen resultaten gevonden",
+  "no_tokens_for_this_user" : "Er zijn geen tokens voor deze gebruiker",
   "No_user_with_username_%s_was_found" : "Geen gebruiker met de naam  <strong>\"%s\"</strong> gevonden",
   "Not_allowed" : "Niet toegestaan",
+  "Not_authorized" : "Geen bevoegdheid",
   "Not_found_or_not_allowed" : "Niet gevonden of niet toegestaan",
   "Nothing_found" : "Niets gevonden",
   "Notify_all_in_this_room" : "Meld aan iederen in deze kamer",
+  "Old_and_new_password_required" : "Je moet zowel je oude als nieuwe wachtwoord geven om uw wachtwoord te wijzigen.",
+  "Old_Password" : "Oud Wachtwoord",
   "Online" : "Online",
+  "Only_you_can_see_this_message" : "Alleen jij kunt dit bericht lezen",
   "Oops!" : "Oeps",
+  "Opt_out_statistics" : "Stuur mijn statistieken niet naar Rocket.Chat",
+  "Opt_out_statistics_warning" : "Door het verzenden van uw statistieken, zult u ons helpen om te bepalen hoe veel gevallen van Rocket.Chat worden ingezet, evenals hoe goed het systeem zich gedraagd, zodat we verder kunnen verbeteren. Maak je geen zorgen, omdat er geen informatie over de gebruiker wordt gestuurd en alle informatie die wij ontvangen wordt vertrouwelijk behandeld. Als u wilt doorgaan met het sturen van uw statistieken, schakelt de bovenstaande checkbox. Dank je.",
   "others" : "anderen",
   "Password" : "Wachtwoord",
+  "Password_Change_Disabled" : "Uw Rocket.Chat beheerder heeft het veranderen van wachtwoorden uitgeschakeld",
   "Password_changed_successfully" : "Wachtwoord succesvol gewijzigd",
+  "People" : "Mensen",
+  "Please_enter_your_new_password_below" : "Vul hieronder uw nieuwe wachtwoord in:",
   "Please_wait" : "Wacht alstublieft",
   "Please_wait_activation" : "Even geduld, dit kan enige tijd duren.",
   "Please_wait_statistics" : "Even geduld, er worden statistieken gegenereerd.",
+  "Post_to_Channel" : "Posten in kanaal",
+  "Post_to_s_as_s" : "Posten in <strong>%s</strong> als <strong>%s</strong>",
   "Powered_by" : "Mede mogelijk gemaakt door",
+  "Preferences" : "Voorkeuren",
+  "Preferences_saved" : "Voorkeuren opgeslagen",
   "Privacy" : "Privacy",
   "Private_Groups" : "Privé groepen",
+  "Private_Groups_list" : "Lijst van privé-groepen",
   "Profile" : "Profiel",
   "Profile_saved_successfully" : "Profiel succesvol opgeslagen",
   "Proudly_developed" : "Ontwikkeld met Meteor",
+  "Push" : "Push",
   "Push_apn_cert" : "APN Certificaat",
   "Push_apn_dev_cert" : "APN Ontwikkelaars Certificaat",
   "Push_apn_dev_key" : "APN Ontwikkelaars Sleutel",
@@ -184,24 +318,45 @@
   "Push_apn_key" : "APN Key",
   "Push_apn_passphrase" : "APN Wachtwoord",
   "Push_debug" : "Debug",
+  "push_disabled" : "Push notificaties uitgeschakeld",
   "Push_enable" : "Enable",
   "Push_production" : "Productie",
+  "Push_test_push" : "Test",
   "Quick_Search" : "Snelzoeken",
   "quote" : "citaat",
   "Recents" : "Recente",
+  "Record" : "Opnemen",
+  "Refresh_your_page_after_install_to_enable_screen_sharing" : "Ververs uw pagina na installeren om het delen van het scherm mogelijk te maken",
   "Register" : "Registreer een nieuwe gebruiker",
   "Registration_Succeeded" : "Registratie Geslaagd",
   "Remember_me" : "Onthou me",
   "Remove" : "Verwijderen",
   "Remove_Admin" : "Verwijder Admin",
-  "Reset_password" : "Nieuw Wachtwoord",
+  "Remove_custom_oauth" : "Verwijder aangepaste OAuth",
+  "Remove_from_room" : "Verwijderen uit de kamer",
+  "Removed" : "Verwijderd",
+  "Reset" : "Reset",
+  "Reset_password" : "Reset Wachtwoord",
+  "Restart" : "Herstart",
+  "Restart_the_server" : "Herstart de server",
   "Room" : "Kamer",
+  "Room_archived" : "Kamer gearchiveerd",
+  "Room_has_been_deleted" : "Kamer is verwijderd",
   "Room_name_changed" : "Naam van de kamer veranderd in: <em>__room_name__</em> door <em>__user_by__</em>",
   "Room_name_changed_successfully" : "Naam van het kanaal is aangepast",
   "Room_not_found" : "Kamer niet gevonden",
+  "Room_unarchived" : "Kamer uit meer gearchiveerd",
+  "Room_uploaded_file_list" : "Bestandslijst",
+  "Room_uploaded_file_list_empty" : "Geen bestanden beschikbaar.",
   "room_user_count" : "%s gebruikers",
+  "Rooms" : "Kamers",
+  "S_new_messages_since_s" : "%s nieuwe berichten sinds %s",
+  "SAML" : "SAML",
   "Save_changes" : "Wijzigingen opslaan",
+  "Save_Mobile_Bandwidth" : "Bespaar op mobile bandbreedte",
+  "Screen_Share" : "Scherm delen",
   "Search" : "Zoeken",
+  "Search_Messages" : "Berichten zoeken",
   "Search_settings" : "Zoekinstellingen",
   "seconds" : "secondes",
   "See_all" : "Alles zien",
@@ -210,22 +365,40 @@
   "Select_file" : "Selecteer bestand",
   "Select_service_to_login" : "Selecteer een dienst in te loggen om uw foto op te halen of  upload er één van uw computer",
   "Selected_users" : "Geselecteerde leden",
-  "Send_confirmation_email" : "Bevestigings e-mail te sturen",
+  "Send" : "Verstuur",
+  "Send_a_test_mail_to_my_user" : "Stuur een test email naar mijn gebruiker",
+  "Send_a_test_push_to_my_user" : "Stuur een test push notificatie naar mijn gebruiker",
+  "Send_confirmation_email" : "Bevestigings e-mail sturen",
+  "Send_data_into_RocketChat_in_realtime" : "Stuur gegevens in Rocket.Chat in real-time.",
+  "Send_invitation_email" : "Stuur uitnodiging e-mail",
+  "Send_invitation_email_error" : "Je hebt geen geldig e-mailadres gegeven.",
+  "Send_invitation_email_info" : "Je kunt meerdere e-mail uitnodigingen verzenden per keer sturen.",
+  "Send_invitation_email_success" : "U hebt een uitnodiging e-mail gestuurd naar de volgende adressen:",
+  "Send_invitation_email_warning" : "Om de uitnodiging e-mails te versturen, moet u eerst de SMTP-instellingen configureren.",
   "Send_Message" : "Bericht verzenden",
   "Settings" : "Instellingen",
   "Settings_updated" : "Instellingen bijgewerkt",
+  "Should_be_a_URL_of_an_image" : "Dit moet een URL van een afbeelding zijn.",
+  "Should_exists_a_user_with_this_username" : "De gebruiker moet al bestaan.",
   "Showing_online_users" : "Toont <b>__total_online__</b> van de __total__ gebruikers",
   "Showing_results" : "<p>Toon <b>%s</b> resultaten</p>",
   "Silence" : "Stilte",
   "since_creation" : "sinds%s",
+  "Site_Name" : "Site naam",
+  "Site_Url" : "URL van de site",
+  "Site_Url_Description" : "Voorbeeld: https://chat.domain.com/",
+  "SMTP" : "SMTP",
   "SMTP_Host" : "SMTP Host",
   "SMTP_Password" : "SMTP-wachtwoord",
   "SMTP_Port" : "SMTP Poort",
   "SMTP_Username" : "SMTP Gebruikersnaam",
+  "Sound" : "Geluid",
   "Start_of_conversation" : "Begin van het gesprek",
+  "Statistics" : "Statistieken",
   "Stats_Active_Users" : "Actieve gebruikers",
   "Stats_Avg_Channel_Users" : "Gemiddeld aantal Kanaal Gebruikers",
   "Stats_Avg_Private_Group_Users" : "Gemiddeld aantal Privé Groep Gebruikers",
+  "Stats_Away_Users" : "Afwezige gebruikers",
   "Stats_Max_Room_Users" : "Maximaal aantal Kamer Gebruikers",
   "Stats_Non_Active_Users" : "Inactieve Gebruikers",
   "Stats_Offline_Users" : "Offline Gebruikers",
@@ -241,24 +414,42 @@
   "Stats_OS_Uptime" : "OS Uptime",
   "Stats_Total_Channels" : "Totaal Kanalen",
   "Stats_Total_Direct_Messages" : "Totaal Directe Berichten Kamers",
+  "Stats_Total_Messages" : "Totaal aantal berichten",
   "Stats_Total_Private_Groups" : "Totaal Privé Groepen",
   "Stats_Total_Rooms" : "Totaal aantal Kamers",
   "Stats_Total_Users" : "Totaal aantal leden",
+  "Stop_Recording" : "Stop opname",
   "strike" : "doorhalen",
   "Submit" : "Verzenden",
+  "Success" : "Succes",
+  "The_channel_name_is_required" : "De naam van het kanaal is vereist",
   "The_field_is_required" : "Het veld %s is vereist.",
+  "The_image_resize_will_not_work_because_we_can_not_detect_ImageMagick_or_GraphicsMagick_installed_in_your_server" : "Het beeld zal niet van grootte worden veranderd omdat we niet kunnen zien of Imagemagick of GraphicsMagick geïnstalleerd zijn op uw server.",
+  "The_server_will_restart_in_s_seconds" : "De server wordt herstart in %s seconden",
+  "The_setting_s_is_configured_to_s_and_you_are_accessing_from_s" : "De configuratie <strong>%s</strong> is ingesteld op  <strong>%s</strong> en u gebruikt toegang vanaf <strong>%s</strong>!",
+  "This_is_a_push_test_messsage" : "Dit is een push-test messsage",
   "True" : "True",
+  "Type_your_new_password" : "Typ uw nieuwe wachtwoord",
+  "Unarchive" : "Uit archief halen",
+  "Unmute_user" : "Laat iemand weer praten",
   "Unnamed" : "Naamloos",
+  "Unread_Rooms" : "Ongelezen Kamers",
+  "Unread_Rooms_Mode" : "Ongelezen Kamers Mode",
   "Upload_file_question" : "Bestand uploaden?",
+  "Uploading_file" : "Bestand uploaden...",
+  "Use_Emojis" : "Gebruik Emojis",
   "Use_initials_avatar" : "Gebruik de initialen van uw gebruikersnaam",
   "use_menu" : "Gebruik het menu aan de zijkant om toegang te krijgen tot de kanalen en privé gesprekken",
   "Use_service_avatar" : "Gebruik %s afbeelding",
   "Use_this_username" : "Gebruik deze gebruikersnaam",
   "Use_uploaded_avatar" : "Gebruik geüploade afbeelding",
+  "Use_url_for_avatar" : "Gebruik url voor avatar",
   "User_added_by" : "Gebruiker <em>__user_added__</em> toegevoegd door <em>__user_by__</em>",
+  "User_Channels" : "Gebruikers Kanalen",
   "User_has_been_activated" : "Gebruiker is geactiveerd",
   "User_has_been_deactivated" : "Gebruiker is gedeactiveerd",
   "User_has_been_deleted" : "Gebruiker is verwijderd",
+  "User_Info" : "Gebruikers informatie",
   "User_is_no_longer_an_admin" : "Gebruiker is niet langer een admin",
   "User_is_not_activated" : "Gebruiker is niet geactiveerd",
   "User_is_now_an_admin" : "Gebruiker is nu een admin",
@@ -269,15 +460,25 @@
   "User_left_female" : "Heeft het kanaal verlaten.",
   "User_left_male" : "Heeft het kanaal verlaten.",
   "User_logged_out" : "Gebruiker is uitgelogd",
+  "User_muted_by" : "Gebruiker <em>__user_muted__</em> tot zwijgen gebracht door <em>__user_by__</em>.",
+  "User_muted_in_room" : "Gebruiker stil gemaakt in de kamer",
+  "User_not_found_or_incorrect_password" : "Gebruiker niet gevonden of onjuist wachtwoord",
+  "User_or_channel_name" : "Gebruiker of kanaal ",
   "User_removed_by" : "Gebruiker <em>__user_removed__</em> verwijderd door  <em>__user_by__</em>.",
+  "User_removed_from_room" : "De gebruiker is verwijderd uit de kamer",
   "User_Settings" : "Gebruikersinstellingen",
+  "User_unmuted_by" : "Gebruiker <em>__user_muted__</em> weer tot spreken in staat gebracht door <em>__user_by__</em>.\n",
+  "User_unmuted_in_room" : "Gebruiker kan weer spreken in de kamer",
   "User_updated_successfully" : "Gebruiker succesvol bijgewerkt",
   "Username" : "Gebruikersnaam",
   "Username_cant_be_empty" : "De gebruikersnaam mag niet leeg zijn",
+  "Username_Change_Disabled" : "Uw Rocket.Chat beheerder heeft het wijzigen van gebruikersnamen uitgeschakeld",
   "Username_description" : "De gebruikersnaam kan door anderen gebruikt worden om aan u te refereren.",
   "Username_invalid" : "<strong>%s</strong> is geen geldige gebruikersnaam,<br/> gebruik uitsluitend letters, cijfers, punten en streepjes",
   "Username_title" : "Registreer Gebruikersnaam",
   "Username_unavaliable" : "<strong>%s</strong> is al in gebruik :(",
+  "Users" : "Gebruikers",
+  "UTF8_Names_Validation_Description" : "Geen speciale tekens en spaties toestaan. U kunt - _ en. gebruiken maar niet aan het einde van de naam",
   "View_All" : "Bekijk alles",
   "Wait_activation_warning" : "Voordat u kunt inloggen, moet uw account handmatig worden geactiveerd door een beheerder.",
   "We_have_sent_password_email" : "Wij hebben u een e-mail gestuurd met herstel instructies voor uw wachtwoord. Als u deze e-mail niet snel ontvangt, ook niet in uw spam-folder, kom dan terug en probeer het opnieuw.",
@@ -285,10 +486,17 @@
   "Welcome" : "Welkom <em>%s</em>.",
   "Welcome_to_the" : "Welkom bij de",
   "With_whom" : "Met wie",
+  "Yes_clear_all" : "Ja, alles wissen!",
   "Yes_delete_it" : "Ja, verwijder het!",
   "you_are_in_preview_mode_of" : "U kijkt naar de voorbeschouwing van kanaal #<strong>__room_name__</strong>",
+  "You_can_change_a_different_avatar_too" : "U kunt de afbeelding die bij berichten gebruikt wordt vervangen.",
+  "You_can_use_an_emoji_as_avatar" : "U kunt ook een emoji gebruiken als een afbeelding.",
+  "You_have_been_muted" : "Je bent tot zwijgen gebracht in deze kamer.",
   "You_need_confirm_email" : "U dient uw e-mail te bevestigen on in te kunnen loggen!",
+  "You_need_install_an_extension_to_allow_screen_sharing" : "U moet een uitbreiding op uw browser installeren om het delen van het scherm mogelijk te maken",
   "You_will_not_be_able_to_recover" : "Dit bericht zal niet meer te herstellen zijn!",
   "Your_entry_has_been_deleted" : "Uw bericht is verwijderd.",
-  "Your_Open_Source_solution" : "Uw eigen Open Source chat-oplossing"
+  "Your_mail_was_sent_to_s" : "Uw e-mail werd verzonden naar %s",
+  "Your_Open_Source_solution" : "Uw eigen Open Source chat-oplossing",
+  "Your_push_was_sent_to_s_devices" : "Je push werd verzonden naar %s apparaten"
 }
\ No newline at end of file
diff --git a/i18n/pl.i18n.json b/i18n/pl.i18n.json
index 040ad0cf694778a4cb60ed4baa7243a4b961e9d5..59a316acc479c6a01145a66f4f47486d396af67f 100644
--- a/i18n/pl.i18n.json
+++ b/i18n/pl.i18n.json
@@ -49,6 +49,7 @@
   "Accounts_OAuth_Twitter" : "Twitter Login",
   "Accounts_OAuth_Twitter_id" : "Twitter Id",
   "Accounts_OAuth_Twitter_secret" : "Twitter Secret",
+  "Accounts_PasswordReset" : "Zresetuj hasło",
   "Accounts_Registration_AuthenticationServices_Enabled" : "Rejestracja przy użyciu serwisów zewnętrznych",
   "Accounts_RegistrationForm" : "Formularz rejestracyjny",
   "Accounts_RegistrationForm_Disabled" : "Wyłączony",
@@ -58,6 +59,7 @@
   "Accounts_RegistrationForm_SecretURL" : "Sekretny adres URL formularza rejestracyjnego",
   "Accounts_RegistrationRequired" : "Musisz się zarejestrować",
   "Accounts_RequireNameForSignUp" : "Wymagaj podana nazwy podczas rejestracji",
+  "Accounts_ShowFormLogin" : "Pokaż formularz logowania",
   "Activate" : "Aktywuj",
   "Add_custom_oauth" : "Dodaj własne OAuth",
   "Add_Members" : "Dodaj członków",
@@ -70,8 +72,9 @@
   "API" : "API",
   "API_Analytics" : "Analytics",
   "API_Embed" : "Osadź",
-  "API_EmbedDisabledFor" : "Wyłądz osadzanie dla użytkowników",
+  "API_EmbedDisabledFor" : "Wyłącz osadzanie dla użytkowników",
   "API_EmbedDisabledFor_Description" : "Lista użytkowników oddzielonych przecinkami",
+  "Archive" : "Archiwizuj",
   "are_also_typing" : "również piszą",
   "are_typing" : "piszÄ…",
   "Are_you_sure" : "JesteÅ› pewny?",
@@ -84,6 +87,7 @@
   "Away_female" : "Zaraz wracam",
   "away_male" : "zaraz wracam",
   "Away_male" : "Zaraz wracam",
+  "Back_to_integrations" : "Powrót do integracji",
   "Back_to_login" : "Wróć do strony logowania",
   "bold" : "pogrubienie",
   "busy" : "zajęty",
@@ -94,6 +98,7 @@
   "Busy_male" : "Zajęty",
   "Cancel" : "Anuluj",
   "CDN_PREFIX" : "Prefiks CDN",
+  "Certificates_and_Keys" : "Certyfikaty i klucze",
   "Change_avatar" : "Zmień avatar",
   "Channels" : "Kanały",
   "Channels_list" : "Lista kanałów publicznych",
@@ -107,6 +112,7 @@
   "Contact" : "Kontakt",
   "Conversation" : "Rozmowa",
   "Convert_Ascii_Emojis" : "Konwertuj ASCII do Emoji",
+  "COPY_TO_CLIPBOARD" : "SKOPIUJ DO SCHOWKA",
   "Create_new" : "Utwórz",
   "Create_new_direct_message_room" : "Nowa prywatna rozmowa",
   "Create_new_private_group" : "Utwórz prywatną grupę",
@@ -138,6 +144,7 @@
   "Enable_Desktop_Notifications" : "WÅ‚Ä…cz powiadomienia na pulpicie",
   "Enter_info" : "Podaj swoje dane",
   "Enter_to" : "Naciśnij Enter: ",
+  "Error" : "BÅ‚Ä…d",
   "Error_changing_password" : "Błąd zmiany hasła",
   "Error_too_many_requests" : "Błąd, zbyt wiele żądań. Proszę zwolnij. Musisz poczekać %s sekund zanim spróbujesz ponownie",
   "Esc_to" : "Naciśnij Esc: ",
@@ -163,15 +170,22 @@
   "hours" : "godzin",
   "Incorrect_Password" : "Hasło jest nieprawidłowe",
   "inline_code" : "kod",
+  "Install_Extension" : "Zainstaluj rozszerzenie",
   "Install_FxOs" : "Zainstaluj Rocket.Chat w Firefoksie",
   "Install_FxOs_done" : "Świetnie! Możesz teraz włączać Rocket.Chat poprzez ikonę na ekranie głównym. Życzymy miłego korzystania z Rocket.Chat!",
   "Install_FxOs_error" : "Niestety, coś nie zadziałało! Wystąpił następujący błąd:",
   "Install_FxOs_follow_instructions" : "Potwierdź instalowanie aplikacji na twoim urządzeniu (gdy wyskoczy pytanie naciśnij przycisk \"Zainstaluj\").",
+  "Integration_New" : "Nowy Integracja",
+  "Integrations" : "Integracje",
   "Invalid_confirm_pass" : "Podane hasła nie są jednakowe",
   "Invalid_email" : "E-mail jest nieprawidłowy",
+  "Invalid_file_height" : "Nieprawidłowa wysokość pliku",
+  "Invalid_file_type" : "Nieprawidłowy typ pliku",
+  "Invalid_file_width" : "Nieprawidłowa szerokość pliku",
   "Invalid_name" : "Nazwa nie może być pusta",
   "Invalid_pass" : "Hasło nie może być puste",
   "Invalid_room_name" : "<strong>%s</strong> nie jest poprawną nazwą pokoju, <br / >użyj tylko liter, cyfr i myślników",
+  "Invalid_secret_URL_message" : "Podany adres URL jest nieprawidłowy.",
   "invisible" : "niewidoczny",
   "Invisible" : "Niewidoczny",
   "Invitation_HTML" : "Kod HTML zaproszenia",
@@ -186,6 +200,8 @@
   "italics" : "kursywa",
   "join" : "Dołącz",
   "Join_the_Community" : "Dołącz do społeczności",
+  "Jump_to_first_unread" : "Przejdź do pierwszej nieprzeczytanej",
+  "Jump_to_recent_messages" : "Przejdź do ostatnich wiadomości",
   "Language" : "Język",
   "Language_Version" : "Wersja angielska",
   "Last_login" : "Ostatnie logowanie",
@@ -265,6 +281,7 @@
   "Name" : "Nazwa",
   "Name_cant_be_empty" : "Nazwa nie może być pusta",
   "Name_optional" : "Nazwa (opcjonalnie)",
+  "New_integration" : "Nowa integracja",
   "New_messages" : "Nowe wiadomości",
   "New_password" : "Nowe hasło",
   "No_channel_with_name_%s_was_found" : "Nie odnaleziono kanału o nazwie <strong>\"%s\"</strong>!",
@@ -288,6 +305,7 @@
   "Oops!" : "Ups",
   "Opt_out_statistics" : "Nie wysyłaj statystyk do autorów Rocket.Chat",
   "Opt_out_statistics_warning" : "Przesyłając swoje statystyki pomagasz nam określić jak instalacji Rocket.Chat jest w użyciu i jak dobrze sprawuje się nasza aplikacja, co pozwala nam ją wciąż ulepszać. Nie przesyłamy żadnych informacji o użytkownikach, a wszystkie otrzymane informacje są traktowane jako poufne. Jeśli chcesz nadal przesyłać nam statystyki, odznacz powyższe pole. Dziękujemy.",
+  "optional" : "opcjonalne",
   "others" : "inni",
   "Password" : "Hasło",
   "Password_Change_Disabled" : "Administrator czatu wyłączył możliwość zmiany haseł",
@@ -315,6 +333,8 @@
   "Push_apn_passphrase" : "APN Passphrase",
   "Push_debug" : "Debugowanie",
   "Push_enable" : "WÅ‚Ä…cz",
+  "Push_enable_gateway" : "WÅ‚Ä…cz bramÄ™",
+  "Push_gateway" : "Brama",
   "Push_gcm_api_key" : "Klucz API GCM",
   "Push_gcm_project_number" : "Identyfikator projektu GCM",
   "Push_production" : "Serwer produkcyjny",
@@ -322,14 +342,19 @@
   "quote" : "cytat",
   "Recents" : "Najnowsze",
   "Record" : "Nagrywaj",
+  "Refresh_your_page_after_install_to_enable_screen_sharing" : "Odśwież stronę po instalacji, aby umożliwić dzielenie ekranu",
   "Register" : "Zarejestruj nowe konto",
   "Registration_Succeeded" : "Rejestracja zakończona",
   "Remember_me" : "Zapamiętaj mnie",
   "Remove" : "Usuń",
   "Remove_Admin" : "Zabierz Admina",
   "Remove_custom_oauth" : "Usuń własne OAuth",
+  "Removed" : "Usunięto",
   "Reset_password" : "Zresetuj hasło",
+  "Restart" : "Uruchom ponownie",
+  "Restart_the_server" : "Uruchom serwer ponownie",
   "Room" : "Pokój",
+  "Room_archived" : "Pokój zarchiwizowany",
   "Room_name_changed" : "Nazwa pokoju zmieniona na: <em>__room_name__</em>przez <em>__user_by__</em>",
   "Room_name_changed_successfully" : "Nazwa pokoju zmieniona",
   "Room_not_found" : "Nie odnaleziono pokoju",
@@ -346,6 +371,7 @@
   "SAML_Custom_Provider" : "WÅ‚asny dostawca (provider)",
   "Save_changes" : "Zapisz zmiany",
   "Save_Mobile_Bandwidth" : "Oszczędzaj przepustowość",
+  "Screen_Share" : "Współdzielenie ekranu",
   "Search" : "Szukaj",
   "Search_Messages" : "Przeszukaj wiadomości",
   "Search_settings" : "Przeszukaj ustawienia",
@@ -407,12 +433,16 @@
   "Stop_Recording" : "Zatrzymaj nagrywanie",
   "strike" : "przekreślenie",
   "Submit" : "Prześlij",
+  "Success" : "Sukces",
   "The_field_is_required" : "Pole %s jest wymagane.",
+  "The_server_will_restart_in_s_seconds" : "Serwer zostanie ponownie uruchomiony za %s sekund",
   "True" : "Tak",
+  "Type_your_new_password" : "Wprowadź nowe hasło",
   "Unnamed" : "Anonimowy",
   "Unread_Rooms" : "Nieprzeczytane pokoje",
   "Unread_Rooms_Mode" : "Tryb nieprzeczytanych pokoi",
   "Upload_file_question" : "Przesłać plik?",
+  "Uploading_file" : "Przesyłanie pliku ...",
   "Use_Emojis" : "Użyj Emoji",
   "Use_initials_avatar" : "Użyj inicjałów",
   "use_menu" : "Otwórz menu boczne by uzyskać dostęp do twoich pokoi i rozmów",
@@ -460,6 +490,7 @@
   "Yes_delete_it" : "Tak, usuń to!",
   "you_are_in_preview_mode_of" : "Jesteś w trybie podglądu kanału # <strong>__room_name__</strong>",
   "You_need_confirm_email" : "Aby się zalogować musisz potwierdzić swój adres e-mail!",
+  "You_need_install_an_extension_to_allow_screen_sharing" : "Musisz zainstalować rozszerzenie, aby umożliwić dzielenie ekranu",
   "You_will_not_be_able_to_recover" : "Nie będziesz w stanie odzyskać tej wiadomości!",
   "Your_entry_has_been_deleted" : "Twój wpis został usunięty.",
   "Your_Open_Source_solution" : "Twój własny czat Open Source"
diff --git a/i18n/pt.i18n.json b/i18n/pt.i18n.json
index eedf1d79fa655d55764040ff90e75e6b01c7c3b9..e4af9ea8aba180de6290e9cb2725a714a44ac081 100644
--- a/i18n/pt.i18n.json
+++ b/i18n/pt.i18n.json
@@ -49,6 +49,7 @@
   "Accounts_RegistrationForm_Secret_URL" : "URL Secreta",
   "Accounts_RegistrationRequired" : "Registro Obrigatório",
   "Accounts_RequireNameForSignUp" : "Nome é obrigatório para cadastro",
+  "Accounts_ShowFormLogin" : "Mostrar formulário de login",
   "Activate" : "Ativar",
   "Add_custom_oauth" : "Adicionar oauth customizado",
   "Add_Members" : "Adicionar membros",
@@ -65,6 +66,7 @@
   "are_also_typing" : "também estão digitando",
   "are_typing" : "estão digitando",
   "Are_you_sure" : "Você tem certeza?",
+  "Authorize" : "Autorizar",
   "Auto_Load_Images" : "Auto Carregar Imagens",
   "Avatar_changed_successfully" : "Avatar alterado com sucesso",
   "Avatar_url_invalid_or_error" : "A URL fornecida é inválida ou não acessível. Por favor tente novamente, mas com uma url diferente.",
@@ -130,7 +132,7 @@
   "Enter_to" : "Enter para",
   "Error" : "Erro",
   "Error_changing_password" : "Erro ao alterar senha",
-  "Error_too_many_requests" : "Erro, foram realizadas muitas solicitações. Por favor, diminua a velocidade. Você dev esperar %s segundos antes de tentar novamente",
+  "Error_too_many_requests" : "Erro, foram realizadas muitas solicitações. Por favor, diminua a velocidade. Você deve esperar %s segundos antes de tentar novamente",
   "Esc_to" : "Esc para",
   "False" : "Não",
   "Favorites" : "Favoritos",
@@ -138,7 +140,9 @@
   "FileUpload_Enabled" : "Habilitar upload de arquivos",
   "FileUpload_MaxFileSize" : "Tamanho máximo dos arquivos (em bytes)",
   "FileUpload_MediaTypeWhiteList" : "Lista de tipos de mídia",
-  "FileUpload_MediaTypeWhiteListDescription" : "Lista de tipos de mídia separada por vírgula",
+  "FileUpload_MediaTypeWhiteListDescription" : "Separados por vírgula",
+  "FileUpload_ProtectFiles" : "Proteger arquivos enviados",
+  "FileUpload_ProtectFilesDescription" : "Somente usuários autenticados terão acesso",
   "Follow_social_profiles" : "Siga-nos nas redes sociais, faça fork no github e compartilhe suas ideias sobre o app rocket.chat em nosso trello.",
   "Forgot_password" : "Esqueceu sua senha",
   "Fork_it_on_github" : "Fork it on github",
@@ -314,6 +318,7 @@
   "Remove" : "Remover",
   "Remove_Admin" : "Remover Administrador",
   "Remove_custom_oauth" : "Remover oauth customizado",
+  "Removed" : "Removido",
   "Reset_password" : "Resetar senha",
   "Restart" : "Reiniciar",
   "Restart_the_server" : "Reiniciar o servidor",
@@ -395,7 +400,6 @@
   "strike" : "tachado",
   "Submit" : "Enviar",
   "Success" : "Sucesso",
-  "The_configured_URL_is_different_from_the_URL_you_are_accessing" : "A URL configurada é diferente da URL que você está acessando!",
   "The_field_is_required" : "O campo %s é obrigatório.",
   "The_server_will_restart_in_s_seconds" : "O servidor será reiniciado em %s segundos",
   "This_is_a_push_test_messsage" : "Este é uma mensagem de teste de push notification",
@@ -446,11 +450,13 @@
   "We_have_sent_registration_email" : "Nós lhe enviamos um e-mail para confirmar o seu registro. Se você não receber um e-mail em breve, por favor retorne e tente novamente.",
   "Welcome" : "Seja bem-vindo <em>%s</em>.",
   "Welcome_to_the" : "Bem-vindo ao",
+  "will_be_able_to" : "poderá",
   "With_whom" : "Com quem",
   "Yes" : "Sim",
   "Yes_clear_all" : "Sim, limpar tudo!",
   "Yes_delete_it" : "Sim, exclua!",
   "you_are_in_preview_mode_of" : "Esta é uma prévia do canal #<strong>__room_name__</strong>",
+  "You_are_logged_in_as" : "Vocês está logado como",
   "You_need_confirm_email" : "Você precisa confirmar seu email para logar!",
   "You_will_not_be_able_to_recover" : "Você não será capaz de desfazer!",
   "Your_entry_has_been_deleted" : "Sua mensagem foi excluída.",
diff --git a/i18n/ro.i18n.json b/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..15571b9486efa4ff1ed9f880e191d8eba4afd49d
--- /dev/null
+++ b/i18n/ro.i18n.json
@@ -0,0 +1,613 @@
+{
+  "Access_not_authorized" : "Acces neautorizat",
+  "Access_online_demo" : "Accesați demo on-line",
+  "Access_Online_Demo" : "Accesati Demo Online",
+  "Access_Token_URL" : "Acces Token URL",
+  "Accounts" : "Conturi",
+  "Accounts_AllowedDomainsList" : "Listă domenii permise",
+  "Accounts_AllowedDomainsList_Description" : "Lista separată cu virgule a domeniilor acceptate",
+  "Accounts_AllowPasswordChange" : "Permiteți schimbare parolă",
+  "Accounts_AllowUserAvatarChange" : "Permite schimbarea avatar-ului utilzatorilor",
+  "Accounts_AllowUsernameChange" : "Permiteți schimbarea numelui de utilizator",
+  "Accounts_AllowUserProfileChange" : "Permite schimbarea profilului utilzatorilor",
+  "Accounts_AvatarResize" : "Redimensionarea Avatare",
+  "Accounts_AvatarSize" : "Dimensiune Avatar",
+  "Accounts_AvatarStorePath" : "Calea de stocare Avatar",
+  "Accounts_AvatarStoreType" : "Tip stocare Avatar",
+  "Accounts_denyUnverifiedEmail" : "Nu accepta e-mail neverificat",
+  "Accounts_EmailVerification" : "Verificarea email-ului",
+  "Accounts_Enrollment_Email" : "E-mail de înscriere ",
+  "Accounts_Enrollment_Email_Description" : "Puteți utiliza [name], [fname], [lname] pentru numele complet al utilizatorului, prenumele respectiv numele de familie.<br/>Puteți folosi [email] pentru e-mailul utilizatorului.",
+  "Accounts_LoginExpiration" : "Autentificarea expiră (în zile)",
+  "Accounts_ManuallyApproveNewUsers" : "Aprobarea manuală a noilor utilizatori",
+  "Accounts_OAuth_Custom_Authorize_Path" : "Authorize Path",
+  "Accounts_OAuth_Custom_Button_Color" : "Culoare buton",
+  "Accounts_OAuth_Custom_Button_Label_Color" : "Culoare buton text",
+  "Accounts_OAuth_Custom_Button_Label_Text" : "Text buton",
+  "Accounts_OAuth_Custom_Enable" : "Activează",
+  "Accounts_OAuth_Custom_id" : "Id-ul",
+  "Accounts_OAuth_Custom_Identity_Path" : "Identity Path",
+  "Accounts_OAuth_Custom_Login_Style" : "Stil Autentificare",
+  "Accounts_OAuth_Custom_Secret" : "Secret",
+  "Accounts_OAuth_Custom_Token_Path" : "Token Path",
+  "Accounts_OAuth_Custom_URL" : "URL",
+  "Accounts_OAuth_Facebook" : "Logare cu Facebook",
+  "Accounts_OAuth_Facebook_id" : "Facebook App ID",
+  "Accounts_OAuth_Facebook_secret" : "Facebook Secret",
+  "Accounts_OAuth_Github" : "OAuth Activat",
+  "Accounts_OAuth_Github_id" : "Client Id",
+  "Accounts_OAuth_Github_secret" : "Client Secret",
+  "Accounts_OAuth_Gitlab" : "OAuth Activat",
+  "Accounts_OAuth_Gitlab_id" : "Gitlab Id",
+  "Accounts_OAuth_Gitlab_secret" : "Client Secret",
+  "Accounts_OAuth_Google" : "Login cu Google",
+  "Accounts_OAuth_Google_id" : "Google Id",
+  "Accounts_OAuth_Google_secret" : "Google Secret",
+  "Accounts_OAuth_Linkedin" : "Logare cu LinkedIn",
+  "Accounts_OAuth_Linkedin_id" : "LinkedIn Id",
+  "Accounts_OAuth_Linkedin_secret" : "LinkedIn Secret",
+  "Accounts_OAuth_Meteor" : "Logare cu Meteor",
+  "Accounts_OAuth_Meteor_id" : "Meteor ID",
+  "Accounts_OAuth_Meteor_secret" : "Meteor Secret",
+  "Accounts_OAuth_Twitter" : "Logare cu Twitter",
+  "Accounts_OAuth_Twitter_id" : "Twitter Id",
+  "Accounts_OAuth_Twitter_secret" : "Twitter Secret",
+  "Accounts_PasswordReset" : "Resetează parola",
+  "Accounts_Registration_AuthenticationServices_Enabled" : "Înregistrare cu servicii de autentificare",
+  "Accounts_RegistrationForm" : "Formular de înregistrare",
+  "Accounts_RegistrationForm_Disabled" : "Dezactivat",
+  "Accounts_RegistrationForm_LinkReplacementText" : "Înlocuire link din formularul de înregistrare",
+  "Accounts_RegistrationForm_Public" : "Public",
+  "Accounts_RegistrationForm_Secret_URL" : "URL secret",
+  "Accounts_RegistrationForm_SecretURL" : "URL secret din formularul de înregistrare",
+  "Accounts_RegistrationForm_SecretURL_Description" : "Trebuie să furnizați un șir aleatoriu care va fi adăugat la URL-ul dvs. de înregistrare. Exemplu: https://demo.rocket.chat/register/[secret_hash]",
+  "Accounts_RegistrationRequired" : "Înregistrare necesară",
+  "Accounts_RequireNameForSignUp" : "Cere nume pentru înregistrare",
+  "Accounts_ShowFormLogin" : "Arată formularul pentru autentificare",
+  "Activate" : "Activează",
+  "Add_custom_oauth" : "Adaugă OAuth personalizat",
+  "Add_Members" : "Adaugă membri",
+  "Add_users" : "Adaugă utilizatori",
+  "Administration" : "Administrare",
+  "After_OAuth2_authentication_users_will_be_redirected_to_this_URL" : "După autentificare OAuth2, utilizatorii vor fi redirecționat către această adresă URL",
+  "Alias" : "Alias",
+  "All_channels" : "Toate canalele",
+  "Allow_Invalid_SelfSigned_Certs" : "Permiteți Certificate Self-Signed Certs",
+  "Allow_Invalid_SelfSigned_Certs_Description" : "Permiteți certificat SSL invalid și auto-semnat pentru validarea link-urilor și previzualizări.",
+  "and" : "și",
+  "API" : "API",
+  "API_Analytics" : "Analytics",
+  "API_Embed" : "Embed",
+  "API_EmbedDisabledFor" : "Dezactivați Embed pentru utilizatori",
+  "API_EmbedDisabledFor_Description" : "Lista separată cu virgule a numelor de utilizator",
+  "Application_added" : "Aplicație adăugată",
+  "Application_Name" : "Nume aplicație",
+  "Application_updated" : "Aplicație actualizată",
+  "Archive" : "Arhivează",
+  "are_also_typing" : "tastează",
+  "are_typing" : "tastează",
+  "Are_you_sure" : "Sigur doriți asta?",
+  "Authorization_URL" : "URL de autorizare",
+  "Authorize" : "Autorizează",
+  "Auto_Load_Images" : "Auto-încarcă imagini",
+  "Avatar_changed_successfully" : "Avatar schimbat cu succes",
+  "Avatar_URL" : "URL Avatar ",
+  "Avatar_url_invalid_or_error" : "URL-ul furnizat este invalid sau nu este accesibil. Vă rugăm să încercați din nou, dar cu o altă adresă URL.",
+  "away" : "departe",
+  "Away" : "Departe",
+  "away_female" : "departe",
+  "Away_female" : "Departe",
+  "away_male" : "departe",
+  "Away_male" : "Departe",
+  "Back_to_applications" : "Înapoi la aplicații",
+  "Back_to_integrations" : "Înapoi la integrări",
+  "Back_to_login" : "ÃŽnapoi la autentificare",
+  "bold" : "îngroșat",
+  "busy" : "ocupat",
+  "Busy" : "Ocupat",
+  "busy_female" : "ocupat",
+  "Busy_female" : "Ocupat",
+  "busy_male" : "ocupat",
+  "Busy_male" : "Ocupat",
+  "Cancel" : "Anulează",
+  "CDN_PREFIX" : "CDN Prefix",
+  "Certificates_and_Keys" : "Certificate și chei",
+  "Change_avatar" : "Schimbare avatar",
+  "Channels" : "Canale",
+  "Channels_list" : "Listă de canale publice",
+  "Chat_Rooms" : "Camere de chat",
+  "Choose_the_alias_that_will_appear_before_the_username_in_messages" : "Alege alias care va apărea în fața numelui de utilizator în mesaje.",
+  "Choose_the_username_that_this_integration_will_post_as" : "Alege numele de utilizator cu care va posta această integrare.",
+  "Clear_all_unreads_question" : "Ștergeți toate necitite?",
+  "Client_ID" : "ID Client",
+  "Client_Secret" : "Client Secret",
+  "close" : "închide",
+  "coming_soon" : "în curând",
+  "Commands" : "Comenzi",
+  "Compact_View" : "Vizualizare compactă",
+  "Confirm_password" : "Confirmați parola",
+  "Contact" : "Contact",
+  "Conversation" : "Conversaţie",
+  "Convert_Ascii_Emojis" : "Conversie ASCII în Emoji",
+  "COPY_TO_CLIPBOARD" : "COPIAÈšI ÃŽN CLIPBOARD",
+  "Create_new" : "Crează nou",
+  "Create_new_direct_message_room" : "Creați o nouă cameră de mesaje directe",
+  "Create_new_private_group" : "Creați un nou grup privat",
+  "Create_new_public_channel" : "Crează un nou canal public.",
+  "Created_at" : "Creat la",
+  "Created_at_s_by_s" : "Creat la <strong>%s</strong> by <strong>%s</strong>",
+  "Custom_oauth_helper" : "La configurarea furnizorul de OAuth, va trebui să apelați un URL de apel invers. Utilizați <pre>%s</pre>.",
+  "Custom_oauth_unique_name" : "Nume unic OAuth personalizat",
+  "days" : "zile",
+  "Deactivate" : "Dezactivează",
+  "Delete_Room_Warning" : "Ștergerea unei camere va șterge toate mesajele postate în cameră. Acest lucru nu poate fi anulat.",
+  "Delete_User_Warning" : "Ștergerea unui utilizator va șterge și toate mesajele acelui utilizator. Acest lucru nu poate fi anulat.",
+  "Deleted" : "Șters!",
+  "Desktop_Notifications" : "Notificări pe desktop",
+  "Desktop_Notifications_Disabled" : "Notificările desktop sunt dezactivate. Schimbați preferințele browser-ului dacă aveți nevoie de notificări activate.",
+  "Desktop_Notifications_Enabled" : "Notificări pe desktop sunt activate",
+  "Direct_Messages" : "Mesaje directe",
+  "Disable_Favorite_Rooms" : "Dezactivați Favorite",
+  "Disable_New_Message_Notification" : "Dezactivează notificările privind mesajele noi",
+  "Disable_New_Room_Notification" : "Dezactivează notificările privind camere noi",
+  "Do_you_want_to_change_to_s_question" : "Doriți să modificați în <strong>%s</strong>?",
+  "Drop_to_upload_file" : "Trageți fișierul aici pentru încărcare",
+  "Duplicate_archived_channel_name" : "Există în arhivă un canalul cu numele \"%s\"",
+  "Duplicate_archived_private_group_name" : "Există în arhivă un grup privat cu numele '% s' ",
+  "Duplicate_channel_name" : "Un canal cu numele \"% s\" există deja",
+  "Duplicate_private_group_name" : "Un grup privat cu numele '% s' există deja",
+  "E-mail" : "E-mail",
+  "edited" : "editat",
+  "Email_already_exists" : "Adresa de e-mail există deja",
+  "Email_or_username" : "Adresă de e-mail sau nume de utilizator",
+  "Email_verified" : "Email verificat",
+  "Emoji" : "Emoji",
+  "Enable_Desktop_Notifications" : "Activați notificări pe desktop",
+  "Enter_info" : "Introduceți informațiile dumneavoastră",
+  "Enter_to" : "Enter pentru a",
+  "Error" : "Eroare",
+  "Error_changing_password" : "Eroare la schimbarea parolei",
+  "Error_too_many_requests" : "Eroare, prea multe cereri. Vă rugăm să încetinți. Trebuie să așteptați % s secunde înainte de a încerca din nou",
+  "Esc_to" : "Esc pentru a",
+  "Example_s" : "Exemplu: <code class=\"inline\">%s</code>",
+  "False" : "Fals",
+  "Favorites" : "Favorite",
+  "FileUpload" : "Încărcare fișier",
+  "FileUpload_Enabled" : "Încărcarea de fișiere activată",
+  "FileUpload_File_Empty" : "Fișier gol",
+  "FileUpload_MaxFileSize" : "Dimensiune maximă a fișierului (în bytes)",
+  "FileUpload_MediaType_NotAccepted" : "Tipuri de media ne-acceptate",
+  "FileUpload_MediaTypeWhiteList" : "Tipuri de media acceptate",
+  "FileUpload_MediaTypeWhiteListDescription" : "Lista separată cu virgule a tipuri de media",
+  "FileUpload_ProtectFiles" : "Protejare fișiere încărcate",
+  "FileUpload_ProtectFilesDescription" : "Doar utilizatorii autentificați vor avea acces",
+  "Follow_social_profiles" : "Urmăriți conturile noastre sociale, \"fork\" proiectul pe GitHub și împărtășiți părerile despre rocket.chat pe board-ul nostru de trello.",
+  "Forgot_password" : "Parolă uitată",
+  "Fork_it_on_github" : "\"Fork\" proiectul pe GitHub",
+  "From_Email" : "E-mail de la",
+  "General" : "General",
+  "Get_to_know_the_team" : "Faceți cunoștință cu Rocket.Team",
+  "github_no_public_email" : "Nu aveți nici un e-mail setat ca e-mail public în contul dumneavoastră GitHub",
+  "Give_a_unique_name_for_the_custom_oauth" : "Alegeți un nume unic pentru OAuth personalizat",
+  "Give_the_application_a_name_This_will_be_seen_by_your_users" : "Da aplicației un nume. Acest lucru va fi văzut de utilizatori.",
+  "Has_more" : "Are mai multe",
+  "Have_your_own_chat" : "Avea propriul dumneavoastră web chat. Scris folosind Meteor.com, Rocket.Chat este o soluție excelentă pentru developerii care vor să construiască și să dezvolte platforma lor de chat.",
+  "Hide_room" : "Ascunde camera",
+  "History" : "Istoric",
+  "hours" : "ore",
+  "Incorrect_Password" : "Parolă incorectă",
+  "inline_code" : "inline_code",
+  "Install_Extension" : "Instalați extensie",
+  "Install_FxOs" : "Instalați Rocket.Chat pe Firefox",
+  "Install_FxOs_done" : "Grozav! Acum puteți folosi Rocket.Chat atingând pictograma de pe ecranul de start. Distrează-te cu Rocket.Chat!",
+  "Install_FxOs_error" : "Ne pare rău, lucrurile n-au mers bine! Următoarea eroare a apărut:",
+  "Install_FxOs_follow_instructions" : "Vă rugăm să confirmați instalarea aplicației pe dispozitiv (apăsați \"Install\" când vi se solicită).",
+  "Integration_added" : "Integrarea a fost adăugată",
+  "Integration_Incoming_WebHook" : "Integrare Intrare WebHook",
+  "Integration_New" : "Integrare nouă",
+  "Integration_updated" : "Integrarea a fost actualizată",
+  "Integrations" : "Integrări",
+  "Invalid_asset" : "Resursă invalidă",
+  "Invalid_confirm_pass" : "Confirmarea parolei nu se potrivește cu parola introdusă",
+  "Invalid_email" : "Adresa de email folosită este invalidă",
+  "Invalid_file_height" : "Înălțime fișier invalidă.",
+  "Invalid_file_type" : "Tip de fișier invalid",
+  "Invalid_file_width" : "Lățime fișier invalidă",
+  "Invalid_name" : "Câmpul nume de utilizator nu poate fi gol",
+  "Invalid_pass" : "Câmpul de parolă nu poate fi gol",
+  "Invalid_room_name" : "<strong>%s</strong> nu este un nume de cameră valid,<br/> folosiți doar litere, cifre și cratimă",
+  "Invalid_room_type" : "<strong>%s</strong> nu e un nume de cameră valid.",
+  "Invalid_Secret_URL" : "URL secret invalid",
+  "Invalid_secret_URL_message" : "URL-ul furnizat este invalid.",
+  "invisible" : "invizibil",
+  "Invisible" : "Invizibil",
+  "Invitation_HTML" : " HTML Invitație",
+  "Invitation_Subject" : "Subiect Invitație ",
+  "Invite_Users" : "Invitați utilizatori",
+  "is_also_typing" : "tastează",
+  "is_also_typing_female" : "tastează",
+  "is_also_typing_male" : "tastează",
+  "is_typing" : "tastează",
+  "is_typing_female" : "tastează",
+  "is_typing_male" : "tastează",
+  "italics" : "cursive",
+  "join" : "Alăturați-vă",
+  "Join_audio_call" : "Intră în apel audio",
+  "Join_the_Community" : "Intrați în comunitate",
+  "Join_video_call" : "Intră în apel video",
+  "Jump_to_first_unread" : "Salt la primul mesaj necitit",
+  "Jump_to_message" : "Salt la mesaj",
+  "Jump_to_recent_messages" : "Salt la mesajele recente",
+  "Language" : "Limba",
+  "Language_Version" : "Versiunea în limba Română",
+  "Last_login" : "Ultima autentificare",
+  "Last_message" : "Ultimul mesaj",
+  "Layout" : "Layout",
+  "Layout_Home_Body" : "Corp pagină 'Acasă'",
+  "Layout_Home_Title" : "Titlu pagină 'Acasă'",
+  "Layout_Login_Header" : "Header Autentificare",
+  "Layout_Login_Terms" : "Termeni Autentificare",
+  "Layout_Privacy_Policy" : "Politica de confidențialitate",
+  "Layout_Sidenav_Footer" : "Footer meniu lateral",
+  "Layout_Sidenav_Footer_description" : "Dimensiunea footer-ului este de 260 x 70px",
+  "Layout_Terms_of_Service" : "Condții de utilizare",
+  "LDAP" : "LDAP",
+  "LDAP_Bind_Search" : "Bind Search",
+  "LDAP_Bind_Search_Description" : "O bucată de JSON care guvernează leagarea și conectarea de informații și este de forma {\"filter\": \"(&(objectCategory=person)(objectclass=user)(memberOf=CN=ROCKET_ACCESS,CN=Users,DC=domain,DC=com)(sAMAccountName=#{username}))\", \"scope\": \"sub\", \"userDN\": \"rocket.service@domain.com\", \"password\": \"urpass\"}",
+  "LDAP_Description" : "LDAP este o bază de date ierarhică pe care multe companii o folosesc pentru a oferi osingură  parolă pe mai multe site-uri și servicii. Pentru informații și exemple de configurare avansate, vă rugăm să consultați wiki nostru: https://github.com/RocketChat/Rocket.Chat/wiki/LDAP-Authentication.",
+  "LDAP_DN" : "Distinguished Name (DN)",
+  "LDAP_DN_Description" : "Rădăcină de căutare; exemplu: dc = domeniu, DC = com",
+  "LDAP_Enable" : "Activați LDAP",
+  "LDAP_Enable_Description" : "Încearcă să utilizezi LDAP pentru autentificare.",
+  "LDAP_Port" : "LDAP Port",
+  "LDAP_Port_Description" : "Port pentru a accesa LDAP pe; de exemplu: 389",
+  "LDAP_Sync_User_Data" : "Sync Data",
+  "LDAP_Sync_User_Data_Description" : "Păstrați datele utilizatorului în sincron cu serverul de autentificare (de exemplu: nume, e-mail).",
+  "LDAP_Sync_User_Data_FieldMap" : "User Data Field Map",
+  "LDAP_Sync_User_Data_FieldMap_Description" : "Configurați modul în care detalii ale contului de utilizator (cum ar fi e-mail) sunt populate de o înregistrare LDAP (odată găsită). De exemplu, {\"cn\": \"Numele\", \"e-mail\": \"e-mail\"} va alege numele unei persoane ce poate fi citit de la atributul cn, și e-mail lor de atributul e-mail. Detaliile disponibile includ numele și e-mail.",
+  "LDAP_Url" : "LDAP URL",
+  "LDAP_Url_Description" : "URL-ul serverului LDAP; exemplu: ldap: //company.dns.com",
+  "Leave_room" : "Părăsește camera",
+  "line" : "linie",
+  "Load_more" : "Încarcă mai multe",
+  "Loading..." : "Se încarcă...",
+  "Loading_more_from_history" : "Se încarcă mai multe din istoric",
+  "Loading_suggestion" : "Se încarcă sugestii...",
+  "Logged_out_of_other_clients_successfully" : "Delogat cu succes din alți clienți",
+  "Login" : "Autentificare",
+  "Login_with" : "Autentifică-te cu %s",
+  "login_with" : "Sau conectare direct cu",
+  "Logout" : "Ieșire",
+  "Logout_Others" : "Delogare din celelalte locații",
+  "Make_Admin" : "Fă utilizator de tip Admin",
+  "Mark_as_read" : "Marchează ca citit",
+  "Markdown_Headers" : "Markdown Headers",
+  "Members" : "Membri",
+  "Members_List" : "Lista de membri",
+  "Members_placeholder" : "Membri",
+  "Message" : "Mesaj",
+  "Message_AllowDeleting" : "Permiteți ștergerea mesajului",
+  "Message_AllowEditing" : "Permiteți editarea mesajului",
+  "Message_AllowEditing_BlockEditInMinutes" : "Blocare editare mesaje după (n) minute",
+  "Message_AllowEditing_BlockEditInMinutesDescription" : "Introduceți 0 pentru a dezactiva blocarea.",
+  "Message_AudioRecorderEnabled" : "Audio Recorder Activat",
+  "Message_AudioRecorderEnabledDescription" : "Necesită \"/ WAV audio\" să fie un tip de media acceptat în setările \"upload\".",
+  "Message_deleting_not_allowed" : "Nu e permisă ștergerea de mesaje",
+  "Message_editing_blocked" : "Acest mesaj nu mai poate fi editat",
+  "Message_editing_not_allowed" : "Nu e permisă editarea de mesaje",
+  "Message_GroupingPeriod" : "Perioadă pentru grupare (în secunde)",
+  "Message_GroupingPeriodDescription" : "Mesajele vor fi grupate cu mesajul anterior dacă sunt de la același utilizator și timpul scurs a fost mai mic decât perioada pentru grupare în secunde.",
+  "Message_KeepHistory" : "Păstrează istoricul mesajelor",
+  "Message_MaxAllowedSize" : "Dimensiunea maximă admisă Mesaj",
+  "Message_pinned" : "Mesaj fixat",
+  "Message_pinning_not_allowed" : "Nu e permisă fixarea de mesaje",
+  "Message_removed" : "Mesaj eliminat",
+  "Message_ShowDeletedStatus" : "Afișare starea de ștergere",
+  "Message_ShowEditedStatus" : "Afișează starea de editare",
+  "Message_ShowFormattingTips" : "Arată sugestii de formatare",
+  "Messages" : "Mesaje",
+  "Messages_that_are_sent_to_the_Incoming_WebHook_will_be_posted_here" : "Mesajele care sunt trimise prin WebHook vor fi postate aici.",
+  "Meta" : "Meta",
+  "Meta_fb_app_id" : "Facebook App ID",
+  "Meta_google-site-verification" : "Google Site Verification",
+  "Meta_language" : "Limba",
+  "Meta_msvalidate01" : "MSValidate.01",
+  "Meta_robots" : "Roboți",
+  "minutes" : "minute",
+  "More_channels" : "Mai multe canale",
+  "More_groups" : "Mai multe grupuri private",
+  "More_unreads" : "Mai multe necitite",
+  "Msgs" : "Mesaje",
+  "multi" : "multi",
+  "Mute_user" : "Blochează mesajele utilizatorului",
+  "Muted" : "Silențios",
+  "My_Account" : "Contul meu",
+  "n_messages" : "%s mesaje",
+  "Name" : "Nume",
+  "Name_cant_be_empty" : "Numele nu poate fi gol",
+  "Name_optional" : "Nume (opțional)",
+  "New_Application" : "Aplicație nouă",
+  "New_integration" : "Integrare nouă",
+  "New_messages" : "Mesaje noi",
+  "New_password" : "Parolă nouă",
+  "No_channel_with_name_%s_was_found" : "Niciun canal găsit cu numele <strong>\"%s\"</strong>!",
+  "No_channels_yet" : "Încă nu faceți parte din niciun canal.",
+  "No_direct_messages_yet" : "Încă nu ați inițiat nicio conversație.",
+  "No_favorites_yet" : "Încă nu ați adăugat niciun canal favorit.",
+  "No_group_with_name_%s_was_found" : "Niciun grup privat găsit cu numele <strong>\"%s\"</strong>!",
+  "No_groups_yet" : "Încă nu aveți niciun grup privat.",
+  "No_livechats" : "Nu aveți livechats.",
+  "No_permission_to_view_room" : "Nu aveți permisiunea de a vedea această cameră",
+  "No_results_found" : "Niciun rezultat găsit",
+  "no_tokens_for_this_user" : "Nu există tokens pentru acest utilizator.",
+  "No_user_with_username_%s_was_found" : "Niciun utilizator găsit cu numele de utilizator <strong>\"%s\"</strong>!",
+  "Not_allowed" : "Nepermis",
+  "Not_authorized" : "Neautorizat",
+  "Not_found_or_not_allowed" : "Nu a fost găsit sau nu e permis",
+  "Nothing_found" : "Nu s-a găsit nimic",
+  "Notify_all_in_this_room" : "Notifică toți utilizatorii din această cameră",
+  "OAuth_Application" : "Aplicație OAuth",
+  "OAuth_Applications" : "Aplicații OAuth",
+  "Old_and_new_password_required" : "Trebuie să introduceți și parola veche și cea nouă pentru a schimba parola.",
+  "Old_Password" : "Parola veche",
+  "Online" : "Activ",
+  "Only_you_can_see_this_message" : "Doar dumneavoastră puteți vedea acest mesaj",
+  "Oops!" : "Oops",
+  "Opt_out_statistics" : "Nu trimiteți statisticile mele la Rocket.Chat",
+  "Opt_out_statistics_warning" : "Prin trimiterea statisticilor, veți ajuta să identificăm modul în care e utilizat Rocket.Chat, precum și cât de bine se comportă sistemul, astfel încât să putem îmbunătăți în continuare aplicația. Nu vă faceți griji, nu se trimit informații despre utilizatori și toate informațiile pe care le primim sunt păstrate în mod confidențial. Dacă doriți să continuați a ne trimite statisticile, debifați caseta de selectare de mai sus. Mulțumim.",
+  "optional" : "facultativ",
+  "others" : "alți",
+  "Password" : "Parolă",
+  "Password_Change_Disabled" : "Administratorul a dezactivat schimbarea de parole",
+  "Password_changed_successfully" : "Parola a fost schimbată cu succes",
+  "People" : "Oameni",
+  "Please_enter_value_for_url" : "Vă rugăm să introduceți o valoare pentru adresa URL a avatarului.",
+  "Please_enter_your_new_password_below" : "Vă rugăm să introduceți noua parolă mai jos:",
+  "Please_wait" : "Vă rugăm așteptați",
+  "Please_wait_activation" : "Vă rugăm să așteptați, acest lucru poate dura ceva timp.",
+  "Please_wait_statistics" : "Vă rugăm să așteptați, statisticile sunt generate.",
+  "Post_as" : "Publică drept",
+  "Post_to_Channel" : "Publică pe canal",
+  "Post_to_s_as_s" : "Publică în <strong>%s</strong> as <strong>%s</strong>",
+  "Powered_by" : "Oferit de",
+  "Preferences" : "Preferințe",
+  "Preferences_saved" : "Preferințe salvate",
+  "Privacy" : "Confidențialitate",
+  "Private_Groups" : "Grupuri private",
+  "Private_Groups_list" : "Lista grupurilor private",
+  "Profile" : "Profil",
+  "Profile_saved_successfully" : "Profil salvat cu succes",
+  "Proudly_developed" : "Scris cu mândrie folosind Meteor",
+  "Push" : "Notificări Push",
+  "Push_apn_cert" : "APN Cert",
+  "Push_apn_dev_cert" : "APN Dev Cert",
+  "Push_apn_dev_key" : "APN Dev Key",
+  "Push_apn_dev_passphrase" : "APN Dev Passphrase",
+  "Push_apn_key" : "APN Key",
+  "Push_apn_passphrase" : "APN Passphrase",
+  "Push_debug" : "Depanare",
+  "push_disabled" : "Push dezactivat",
+  "Push_enable" : "Activează",
+  "Push_enable_gateway" : "Activați Gateway",
+  "Push_gateway" : "Gateway",
+  "Push_gcm_api_key" : "GCM API Key",
+  "Push_gcm_project_number" : "GCM Project Number",
+  "Push_production" : "Producție",
+  "Push_test_push" : "Test",
+  "Quick_Search" : "Cautare rapida",
+  "quote" : "citat",
+  "Recents" : "Recente",
+  "Record" : "Înregistrează",
+  "Redirect_URI" : "Redirecționare URI",
+  "Refresh_your_page_after_install_to_enable_screen_sharing" : "Reîncarcă pagina după instalare pentru a permite partajarea de ecran",
+  "Register" : "Înregistrează un cont nou",
+  "Registration_Succeeded" : "Înregistrarea a reușit",
+  "Remember_me" : "Ține-mă minte",
+  "Remove" : "Elimină",
+  "Remove_Admin" : "Eliminați utilizator de tip Admin",
+  "Remove_as_moderator" : "Eliminați ca moderator",
+  "Remove_as_owner" : "Eliminați ca proprietar",
+  "Remove_custom_oauth" : "Eliminați OAuth personalizat",
+  "Remove_from_room" : "Eliminați din cameră",
+  "Removed" : "Eliminat",
+  "Reset" : "Reset",
+  "Reset_password" : "Resetează parola",
+  "Restart" : "Repornire",
+  "Restart_the_server" : "Reporniți serverul",
+  "Room" : "Cameră",
+  "Room_archived" : "Cameră arhivată",
+  "Room_has_been_deleted" : "Camera a fost ștearsă",
+  "Room_name_changed" : "Numele camerei a fost schimbat în: <em>__room_name__</em> de către <em>__user_by__</em>",
+  "Room_name_changed_successfully" : "Numele camerei a fost schimbat cu succes.",
+  "Room_not_found" : "Camera nu a fost găsită",
+  "Room_unarchived" : "Cameră dezarhivată",
+  "Room_uploaded_file_list" : "Lista de fișiere",
+  "Room_uploaded_file_list_empty" : "Niciun fișier disponibil.",
+  "room_user_count" : "%s utilizatorii",
+  "Rooms" : "Camere",
+  "S_new_messages_since_s" : "%s mesaje noi de la %s",
+  "SAML" : "SAML",
+  "SAML_Custom_Cert" : "Custom Certificate",
+  "SAML_Custom_Entry_point" : "Custom Entry Point",
+  "SAML_Custom_Generate_Username" : "Generate Username",
+  "SAML_Custom_Issuer" : "Custom Issuer",
+  "SAML_Custom_Provider" : "Custom Provider",
+  "Save_changes" : "Salvează modificările",
+  "Save_Mobile_Bandwidth" : "Economisește lățime de bandă în modul Mobile",
+  "Screen_Share" : "Partajare ecran",
+  "Search" : "Căutare",
+  "Search_Messages" : "Căutare mesaje",
+  "Search_settings" : "Setări de căutare",
+  "seconds" : "secunde",
+  "See_all" : "Vedeți tot",
+  "See_only_online" : "Doar online",
+  "Select_an_avatar" : "Selectați un avatar",
+  "Select_file" : "Selectați fișierul",
+  "Select_service_to_login" : "Selectați un serviciu pentru a vă conecta pentru a încărca fotografia dumneavoastră de profil sau încărcați una direct de pe computer",
+  "Selected_users" : "Membri selectați",
+  "Send" : "Trimite",
+  "Send_a_test_mail_to_my_user" : "Trimite un e-mail de test pentru utilizator meu",
+  "Send_a_test_push_to_my_user" : "Trimite Push de test pentru utilizator meu",
+  "Send_confirmation_email" : "Trimite email de confirmare",
+  "Send_data_into_RocketChat_in_realtime" : "Trimite datele înspre Rocket.Chat în timp real.",
+  "Send_invitation_email" : "Trimite e-mail de invitație",
+  "Send_invitation_email_error" : "Nu ați furnizat nici o adresă de e-mail validă.",
+  "Send_invitation_email_info" : "Puteți trimite mai multe invitații de e-mail odată.",
+  "Send_invitation_email_success" : "Ați trimis cu succes o invitație de e-mail la următoarele adrese:",
+  "Send_invitation_email_warning" : "Pentru a trimite invitații e-mail, trebuie să configurați mai întâi setările SMTP.",
+  "Send_Message" : "Trimite mesaj",
+  "Send_your_JSON_payloads_to_this_URL" : "Trimiteți JSON către această adresă URL.",
+  "Set_as_moderator" : "Setați ca moderator",
+  "Set_as_owner" : "Setați ca proprietar",
+  "Settings" : "Setări",
+  "Settings_updated" : "Setări actualizare",
+  "Should_be_a_URL_of_an_image" : "Ar trebui să fie o adresă URL a unei imagini.",
+  "Should_exists_a_user_with_this_username" : "Trebuie să existe deja un utilizator cu acest nume de utilizator.",
+  "Showing_archived_results" : "<p>Se arată <b>%s</b> rezultate arhivate</p>",
+  "Showing_online_users" : "Se afișează <b>__total_online__</b> din __total__ users",
+  "Showing_results" : "<p>Se afișează <b>%s</b> rezultate</p>",
+  "Silence" : "Tăcere",
+  "since_creation" : "de la %s",
+  "Site_Name" : "Numele site-ului",
+  "Site_Url" : "URL-ul site-ului",
+  "Site_Url_Description" : "Exemplu: https://chat.domain.com/",
+  "SMTP" : "SMTP",
+  "SMTP_Host" : "SMTP Host",
+  "SMTP_Password" : "SMTP Password",
+  "SMTP_Port" : "Port SMTP",
+  "SMTP_Test_Button" : "Setări SMTP de testare",
+  "SMTP_Username" : "Nume de utilizator SMTP ",
+  "Sound" : "Sunet",
+  "Start_audio_call" : "Pornește apel audio",
+  "Start_of_conversation" : "Începutul conversației",
+  "Start_video_call" : "Pornește apel video",
+  "Start_with_s_for_user_or_s_for_channel_Eg_s_or_s" : "ÃŽncepe cu <code class=\"inline\">%s</code> pentru utilizator sau <code class=\"inline\">%s</code> pentru canal. Ex: <code class=\"inline\">%s</code> sau <code class=\"inline\">%s</code>",
+  "Statistics" : "Statistici",
+  "Stats_Active_Users" : "Utilizatori activi",
+  "Stats_Avg_Channel_Users" : "Medii utilizatori canal",
+  "Stats_Avg_Private_Group_Users" : "Medie utilizatori grup privat",
+  "Stats_Away_Users" : "Utilizatori Away",
+  "Stats_Max_Room_Users" : "Maximum număr de utilizatori în cameră",
+  "Stats_Non_Active_Users" : "Utilizatori inactivi",
+  "Stats_Offline_Users" : "Utilizatori offline",
+  "Stats_Online_Users" : "Utilizatori Activi",
+  "Stats_OS_Arch" : "OS Arch",
+  "Stats_OS_Cpus" : "OS număr CPU ",
+  "Stats_OS_Freemem" : "OS Free Memory",
+  "Stats_OS_Loadavg" : "OS Load Media",
+  "Stats_OS_Platform" : "OS Platform",
+  "Stats_OS_Release" : "OS Release",
+  "Stats_OS_Totalmem" : "OS Total Memory",
+  "Stats_OS_Type" : "Tip sistem de operare",
+  "Stats_OS_Uptime" : "OS Uptime",
+  "Stats_Total_Channels" : "Total Canale",
+  "Stats_Total_Direct_Messages" : "Total camere mesaje directe",
+  "Stats_Total_Messages" : "Numărul total de mesaje",
+  "Stats_Total_Private_Groups" : "Total grupuri private",
+  "Stats_Total_Rooms" : "Total camere",
+  "Stats_Total_Users" : "Utilizatori",
+  "Stop_Recording" : "Oprește înregistrare",
+  "strike" : "tăiat",
+  "Submit" : "Trimite",
+  "Success" : "Succes",
+  "The_application_name_is_required" : "Este nevoie de numele aplicației",
+  "The_channel_name_is_required" : "Este nevoie de numele canalului",
+  "The_field_is_required" : "Este nevoie de câmpul %s.",
+  "The_image_resize_will_not_work_because_we_can_not_detect_ImageMagick_or_GraphicsMagick_installed_in_your_server" : "Redimensionarea imaginii nu va funcționa, deoarece nu putem detecta ImageMagick sau GraphicsMagick instalat pe server.",
+  "The_redirectUri_is_required" : "URI de redirectare este necesar",
+  "The_server_will_restart_in_s_seconds" : "Serverul va reporni în %s secunde",
+  "The_setting_s_is_configured_to_s_and_you_are_accessing_from_s" : "Setarea <strong>%s</strong> e configurată să <strong>%s</strong> iar dumneavoastră accesați din <strong>%s</strong>!",
+  "The_user_will_be_removed_from_s" : "Utilizatorul va fi eliminat din %s",
+  "The_user_wont_be_able_to_type_in_s" : "Utilizatorul nu va putea să introducă text în %s",
+  "There_are_no_integrations" : "Nu sunt integrări",
+  "This_is_a_push_test_messsage" : "Acesta este un test de notificare Push",
+  "True" : "Adevărat",
+  "Type_your_new_password" : "Introduceți noua parolă",
+  "Unarchive" : "Dezarhivați",
+  "Unmute_user" : "Deblochează mesajele utilizatorului",
+  "Unnamed" : "Anonim",
+  "Unread_Rooms" : "Camere necitite",
+  "Unread_Rooms_Mode" : "Mod camere necitite",
+  "Upload_file_question" : "Încarcă fișier?",
+  "Uploading_file" : "Încărcare de fișiere ...",
+  "Use_Emojis" : "Folosiți Emoji",
+  "Use_initials_avatar" : "Folosiți inițialele numelui de utilizator",
+  "use_menu" : "Folosiți meniul lateral pentru a vă accesa camerele și chat-urile",
+  "Use_service_avatar" : "Utilizați avatarul %s",
+  "Use_this_username" : "Folosiți acest nume de utilizator",
+  "Use_uploaded_avatar" : "Utilizați avatar încărcat",
+  "Use_url_for_avatar" : "Utilizați URL pentru avatar",
+  "User__username__is_now_a_moderator_of__room_name_" : "Utilizator __username__  este acum un moderator al __room_name__",
+  "User__username__is_now_a_owner_of__room_name_" : "Utilizatorul __username__ este acum proprietar al  __room_name__",
+  "User__username__removed_from__room_name__moderators" : "Utilizatorul __username__ a fost eliminat din moderatorii  __room_name__",
+  "User__username__removed_from__room_name__owners" : "Utilizatorul __username__ scos din proprietarii __room_name__",
+  "User__username__was_added_as_a_moderator_by__user_by_" : "Utilizatorul <em>__username__</em> a fost adăugat ca moderator de către <em>__user_by__</em>",
+  "User__username__was_added_as_a_owner_by__user_by_" : "Utilizatorul <em>__username__</em> a fost adăugat ca proprietar de către <em>__user_by__</em>",
+  "User__username__was_removed_as_a_moderator_by__user_by_" : "Utilizatorul <em>__username__</em> a fost scos ca moderator de către <em>__user_by__</em>",
+  "User__username__was_removed_as_a_owner_by__user_by_" : "Utilizatorul <em>__username__</em> a fost eliminat ca proprietar de către <em>__user_by__</em>",
+  "User_added_by" : "Utilizator <em>__user_added__</em> adăugat de către <em>__user_by__</em>.",
+  "User_Channels" : "Canale utilizator",
+  "User_has_been_activated" : "Utilizatorul a fost activat",
+  "User_has_been_deactivated" : "Utilizator a fost dezactivat",
+  "User_has_been_deleted" : "Utilizatorul a fost șters",
+  "User_has_been_muted_in_s" : "Utilizator a fost oprit în %s",
+  "User_has_been_removed_from_s" : "Utilizator a fost eliminat din %s",
+  "User_Info" : "Info utilizator",
+  "User_is_no_longer_an_admin" : "Utilizatorul nu mai este Admin",
+  "User_is_not_activated" : "Utilizatorul nu este activat",
+  "User_is_now_an_admin" : "Utilizatorul este acum Admin",
+  "User_joined_channel" : "A intrat pe canal.",
+  "User_joined_channel_female" : "A intrat pe canal.",
+  "User_joined_channel_male" : "A intrat pe canal.",
+  "User_left" : "A părăsit canalul.",
+  "User_left_female" : "A părăsit canalul.",
+  "User_left_male" : "A părăsit canalul.",
+  "User_logged_out" : "Utilizatorul este deconectat",
+  "User_muted_by" : "Utilizatorul <em>__user_muted__</em> a fost blocat de către  <em>__user_by__</em>.",
+  "User_muted_in_room" : "Utilizator blocat în cameră",
+  "User_not_found_or_incorrect_password" : "Utilizator nu a fost găsit sau parolă incorectă",
+  "User_or_channel_name" : "Nume de utilizator sau de canal ",
+  "User_removed_by" : "Utilizator <em>__user_removed__</em> șters de către <em>__user_by__</em>.",
+  "User_removed_from_room" : "Utilizatorul a fost scos din cameră",
+  "User_Settings" : "Setări utilizator",
+  "User_unmuted_by" : "Utilizatorul <em>__user_muted__</em> a fost deblocat de către  <em>__user_by__</em>.",
+  "User_unmuted_in_room" : "Utilizator deblocat în cameră",
+  "User_updated_successfully" : "Utilizator actualizat cu succes",
+  "Username" : "Nume de ultilizator",
+  "Username_cant_be_empty" : "Numele de utilizator nu poate fi gol",
+  "Username_Change_Disabled" : "Administratorul a dezactivat schimbarea de nume de utilizator",
+  "Username_description" : "Numele de utilizator este folosit pentru a permite altora să vă menționeze în mesaje.",
+  "Username_invalid" : "<strong>%s</strong>nu e un nume de utilizator valid,<br/> folosiți doar litere, cifre și cratime",
+  "Username_title" : "Înregistrează nume de utilizator",
+  "Username_unavaliable" : "<strong>%s</strong> e deja folosit :(",
+  "Users" : "Utilizatori",
+  "UTF8_Names_Slugify" : "UTF8 Names Slugify",
+  "UTF8_Names_Validation" : "Validare UTF8 Names ",
+  "UTF8_Names_Validation_Description" : "Nu permite caractere și spații speciale. Puteți folosi '-',  '_' și '.' dar nu la sfârșitul numelui",
+  "View_All" : "Vezi toți",
+  "Wait_activation_warning" : "Ca să vă puteți autentifica, contul dumneavoastră trebuie să fie activat manual de către un administrator.",
+  "We_have_sent_password_email" : "V-am trimis un e-mail cu instrucțiuni de resetare a parolei. Dacă nu primiți un e-mail în scurt timp, va rugăm să reveniti și să încercați din nou.",
+  "We_have_sent_registration_email" : "V-am trimis un e-mail pentru a confirma înregistrarea dumneavoastră. Dacă nu primiți un e-mail în scurt timp, vă rugăm să reveniți și să încercați din nou.",
+  "Welcome" : "Bun venit <em>%s</em>.",
+  "Welcome_to_the" : "Bun venit în",
+  "will_be_able_to" : "va putea",
+  "With_whom" : "Cu cine",
+  "Yes" : "Da",
+  "Yes_clear_all" : "Da, șterge toate!",
+  "Yes_delete_it" : "Da, șterge-l!",
+  "Yes_mute_user" : "Da, blochează mesajele utilizatorului",
+  "Yes_remove_user" : "Da, eliminați utilizatorul!",
+  "you_are_in_preview_mode_of" : "Vă aflați în modul de previzualizare a canalului #",
+  "You_are_logged_in_as" : "Sunteți autentificat ca ",
+  "You_can_change_a_different_avatar_too" : "Puteți înlocui avatarul folosit pentru a posta din această integrare.",
+  "You_can_use_an_emoji_as_avatar" : "Puteți utiliza un emoji ca avatar",
+  "You_have_been_muted" : "Ați fost blocat și nu puteți vorbi în această cameră",
+  "You_need_confirm_email" : "Confirmați adresa de email pentru a vă înregistra!",
+  "You_need_install_an_extension_to_allow_screen_sharing" : "Aveți nevoie de a instala o extensie pentru a permite partajarea ecranului",
+  "You_should_name_it_to_easily_manage_your_integrations" : "Ar trebui să o numiți pentru a vă gestiona cu ușurință integrările.",
+  "You_will_not_be_able_to_recover" : "Nu veți putea recupera acest mesaj!",
+  "Your_entry_has_been_deleted" : "Mesajul dumneavoastră a fost șters.",
+  "Your_mail_was_sent_to_s" : "E-mail-ul a fost trimis la %s",
+  "Your_Open_Source_solution" : "Propria soluție de chat Open Source",
+  "Your_push_was_sent_to_s_devices" : "Mesajul Push a fost trimis la %s dispozitive"
+}
\ No newline at end of file
diff --git a/i18n/ru.i18n.json b/i18n/ru.i18n.json
index 4295b405854935a15a6e28ce79ccd4dc2e01fdf5..ee1c1597ec3519e87bdd3308d5b381f4173dd52c 100644
--- a/i18n/ru.i18n.json
+++ b/i18n/ru.i18n.json
@@ -1,26 +1,49 @@
 {
   "Access_online_demo" : "Попробовать демо-версию",
   "Access_Online_Demo" : "Попробовать демо-версию",
+  "Accounts" : "Аккаунты",
+  "Accounts_AllowedDomainsList" : "Список разрешенных доменов",
+  "Accounts_AllowedDomainsList_Description" : "Разделенный запятыми список разрешенных доменов",
+  "Accounts_AllowPasswordChange" : "Разрешить смену пароля",
+  "Accounts_AllowUserAvatarChange" : "Разрешить пользователю изменять Аватар",
+  "Accounts_AllowUsernameChange" : "Разрешить изменять имя пользователя",
+  "Accounts_AllowUserProfileChange" : "Разрешить пользователю изменять настройки профиля",
+  "Accounts_AvatarResize" : "Изменение размера аватара",
+  "Accounts_AvatarSize" : "Размер аватара",
+  "Accounts_AvatarStorePath" : "Путь к аватарам",
+  "Accounts_AvatarStoreType" : "Тип хранилища Аватаров",
+  "Accounts_denyUnverifiedEmail" : "Запретить непроверенные e-mail",
   "Accounts_EmailVerification" : "Подтверждение e-mail",
+  "Accounts_ManuallyApproveNewUsers" : "Утверждать вручную новых пользователей",
   "Accounts_OAuth_Custom_Button_Color" : "Цвет кнопки",
   "Accounts_OAuth_Custom_Button_Label_Color" : "Цвет текста кнопки",
   "Accounts_OAuth_Custom_Button_Label_Text" : "Текст кнопки",
   "Accounts_OAuth_Custom_Enable" : "Включить",
   "Accounts_OAuth_Custom_Secret" : "Ключ",
+  "Accounts_OAuth_Custom_URL" : "URL",
+  "Accounts_OAuth_Gitlab" : "OAuth включен",
   "Accounts_OAuth_Google" : "Google логин",
   "Accounts_OAuth_Google_id" : "Google ID",
   "Accounts_OAuth_Google_secret" : "Google пароль",
   "Accounts_RegistrationRequired" : "Требуется регистрация",
+  "Activate" : "Активировать",
+  "Add_custom_oauth" : "Добавить пользовательский OAuth",
   "Add_Members" : "Добавить Пользователей",
   "Add_users" : "Добавить пользователей",
+  "Administration" : "Администрирование",
+  "After_OAuth2_authentication_users_will_be_redirected_to_this_URL" : "После аутентификации OAuth2, пользователи будут перенаправляться на этот URL",
   "All_channels" : "Все Чаты",
+  "Allow_Invalid_SelfSigned_Certs" : "Разрешить невалидные самоподписанные сертификаты",
+  "Allow_Invalid_SelfSigned_Certs_Description" : "Разрешить некорректные и самоподписанные SSL сертификаты для связи валидации и предпросмотра",
   "and" : "и",
   "API_Analytics" : "Аналитика",
+  "API_EmbedDisabledFor_Description" : "Разделенный запятыми список имен пользователей",
+  "Archive" : "Удалить",
   "are_also_typing" : "все ещё печатают",
   "are_typing" : "печатает",
   "Are_you_sure" : "Вы уверены?",
   "Auto_Load_Images" : "Автозагрузка изображений",
-  "Avatar_changed_successfully" : "Аватар измененм успешно",
+  "Avatar_changed_successfully" : "Аватар успешно изменен",
   "away" : "отошёл",
   "Away" : "Отошёл",
   "away_female" : "отошла",
@@ -46,14 +69,25 @@
   "Confirm_password" : "Подтвердить пароль",
   "Contact" : "Контакт",
   "Conversation" : "Диалог",
+  "Convert_Ascii_Emojis" : "Конвертировать ASCII в Emoji",
   "Create_new" : "Создать новый",
+  "Create_new_direct_message_room" : "Создать комнату для личных сообщений",
   "Create_new_private_group" : "Создать новый приватный чат",
   "Create_new_public_channel" : "Создать новый публичный чат",
   "Created_at" : "Создано в",
+  "Custom_oauth_unique_name" : "Уникальное имя пользовательского OAuth ",
   "days" : "дней",
+  "Deactivate" : "Деактивировать",
+  "Delete_Room_Warning" : "Удаление чата так же удалит все сообщения в этом чате. Это не может быть отменено.",
+  "Delete_User_Warning" : "Удаление пользователя удалит все сообщения от этого пользователя. Это действие невозможно отменить.",
   "Deleted" : "Удалено!",
+  "Desktop_Notifications" : "Desktop уведомления",
+  "Desktop_Notifications_Disabled" : "Desktop уведомления отключены. Измените настройки браузера, если вам нужно включить уведомления.",
   "Desktop_Notifications_Enabled" : "Уведомления для рабочего стола включены",
   "Direct_Messages" : "Личные сообщения",
+  "Disable_Favorite_Rooms" : "Отключить избранное",
+  "Disable_New_Message_Notification" : "Отключить уведомления о новых сообщениях",
+  "Disable_New_Room_Notification" : "Отключить уведомления о новых чатах",
   "Drop_to_upload_file" : "Переместите сюда для загрузки файла",
   "Duplicate_channel_name" : "Канал с именем '%s' существует",
   "Duplicate_private_group_name" : "Частная группа с именем '%s' существует",
@@ -61,25 +95,41 @@
   "edited" : "отредактировано",
   "Email_already_exists" : "Эл. адрес уже существует",
   "Email_or_username" : "Почтовый ящик или логин",
-  "Email_verified" : "Электронный адрес проверен",
+  "Email_verified" : "E-mail проверяется",
   "Enable_Desktop_Notifications" : "Включить уведомления для рабочего стола",
   "Enter_info" : "Введите свои данные",
+  "Enter_to" : "Войти в",
   "Error_changing_password" : "Ошибка изменения пароля",
+  "Error_too_many_requests" : "Ошибка, слишком много запросов. Пожалуйста, помедленнее. Вы должны подождать%s секунд, прежде чем попробовать снова",
+  "Esc_to" : "Выйти из",
+  "False" : "Нет",
   "Favorites" : "Избранные чаты",
+  "FileUpload" : "Загрузка файла",
+  "FileUpload_Enabled" : "Загрузка файлов включена",
+  "FileUpload_MaxFileSize" : "Максимальный размер загружаемых файлов (в байтах)",
+  "FileUpload_ProtectFilesDescription" : "Только авторизованные пользователи будут иметь доступ",
   "Follow_social_profiles" : "Добавляйте нас в друзья в социальных сетях, форкайте на github и пишите свои отзывы о нашем приложении у нас в trello.",
   "Forgot_password" : "Забыли пароль?",
   "Fork_it_on_github" : "Форкайте на github",
+  "From_Email" : "От Email",
+  "General" : "Общий",
   "github_no_public_email" : "В настройках GitHub отсутствует публично доступный e-mail",
+  "Give_a_unique_name_for_the_custom_oauth" : "Задайте уникальное имя для пользовательского OAuth",
+  "Give_the_application_a_name_This_will_be_seen_by_your_users" : "Задайте приложению имя. Оно будет видно всем пользователям.",
   "Has_more" : "Еще",
+  "Have_your_own_chat" : "Создайте свой веб чат. Разработанный на основе Meteor.com Rocket.Chat это отличное решение для разработчкиков, которые хотят создать свою собственную платформу для общения.",
   "Hide_room" : "Скрыть чат",
   "History" : "История",
   "hours" : "час(ы)",
+  "Incorrect_Password" : "Неверный пароль",
   "inline_code" : "внутренний код",
   "Invalid_confirm_pass" : "Пароли не совпадают",
   "Invalid_email" : "Неверный e-mail",
+  "Invalid_file_type" : "Неверный тип файла",
   "Invalid_name" : "Имя не может быть пустым",
   "Invalid_pass" : "Пароль не может быть пустым",
   "Invalid_room_name" : "<strong>%s</strong> недопустимое имя комнаты, <br/> допустимые символы: цифры, подчеркивание и буквы.",
+  "Invalid_room_type" : "<strong>%s</strong> недопустимый тип комнаты.",
   "invisible" : "невидимый",
   "Invisible" : "Невидимый",
   "Invite_Users" : "Пригласить пользователей",
@@ -92,12 +142,19 @@
   "italics" : "курсив",
   "join" : "Присоединиться",
   "Join_the_Community" : "Присоединиться к сообществу",
+  "Jump_to_first_unread" : "Перейти к первому непрочитанному",
+  "Jump_to_message" : "Перейти к сообщению",
+  "Jump_to_recent_messages" : "Перейти к последнему сообщению",
   "Language" : "Язык",
   "Language_Version" : "Русская версия",
+  "Last_login" : "Последний визит",
   "Last_message" : "Последнее сообщение",
+  "Layout_Home_Body" : "Контент главной",
+  "Layout_Home_Title" : "Название главной",
   "Layout_Privacy_Policy" : "Политика конфиденциальности",
   "Layout_Terms_of_Service" : "Условия использования",
   "LDAP_DN" : "LDAP домен",
+  "LDAP_Enable" : "Включить LDAP",
   "LDAP_Port" : "LDAP Порт",
   "LDAP_Url" : "URL-адрес LDAP",
   "Leave_room" : "Покинуть чат",
@@ -118,40 +175,58 @@
   "Message" : "Сообщение",
   "Message_AllowDeleting" : "Разрешить удаление сообщений",
   "Message_AllowEditing" : "Разрешить редактирование сообщений",
+  "Message_AllowEditing_BlockEditInMinutes" : "Запреить редактирование сообщений после (n) минут",
+  "Message_AllowEditing_BlockEditInMinutesDescription" : "Введите 0, чтобы отключить блокировку.",
+  "Message_deleting_not_allowed" : "Удаление сообщений запрещено",
+  "Message_editing_blocked" : "Это сообщение больше не может быть отредактировано",
+  "Message_editing_not_allowed" : "Редактирование сообщений запрещено",
   "Message_KeepHistory" : "Хранить историю сообщений",
+  "Message_MaxAllowedSize" : "Максимально допустимый размер сообщения",
+  "Message_pinned" : "Сообщение прикреплено",
+  "Message_pinning_not_allowed" : "Прикрепление сообщений запрещено",
   "Message_removed" : "Сообщение удалено",
   "Message_ShowDeletedStatus" : "Отображать статус \"Удалено\"",
   "Message_ShowEditedStatus" : "Отображать статус \"Отредактировано\"",
+  "Message_ShowFormattingTips" : "Показывать советы по форматированию",
   "Messages" : "Сообщения",
   "Meta_language" : "Язык",
+  "Meta_robots" : "Боты",
   "minutes" : "минут(ы)",
   "More_channels" : "Другие чаты",
+  "More_groups" : "Больше приватных чатов",
   "More_unreads" : "Еще непрочитанные",
   "Msgs" : "Сообщения",
   "multi" : "много",
   "My_Account" : "Мой аккаунт",
   "n_messages" : "%s сообщений",
   "Name" : "Имя",
+  "Name_cant_be_empty" : "Имя не может быть пустым",
   "New_messages" : "Новые сообщения",
   "New_password" : "Новый пароль",
-  "No_channel_with_name_%s_was_found" : "Канал с именем <strong>\"%s\"</strong> не найден!",
+  "No_channel_with_name_%s_was_found" : "Чат с названием <strong>\"%s\"</strong> не найден!",
   "No_channels_yet" : "Вы не состоите в публичных чатах.",
   "No_direct_messages_yet" : "Можно писать пользователям приватные сообщения.",
   "No_favorites_yet" : "В избранном пусто. Попробуй добавить сюда что-нибудь.",
-  "No_group_with_name_%s_was_found" : "Частная группа с именем <strong>\"%s\"</strong> не существует",
+  "No_group_with_name_%s_was_found" : "Приватный чат с названием <strong>\"%s\"</strong> не существует",
   "No_groups_yet" : "Вы не состоите ни в одном приватном чате.",
   "No_permission_to_view_room" : "У вас нет прав для просмотра этого чата.",
-  "No_user_with_username_%s_was_found" : "Нет пользователя с именем  <strong>\"%s\"</strong>!",
+  "No_user_with_username_%s_was_found" : "Пользователь с логином  <strong>\"%s\"</strong> не найден!",
   "Not_allowed" : "Не допускается",
   "Not_found_or_not_allowed" : "Чат не существует или владелец ограничил доступ ",
   "Nothing_found" : "Ничего не найдено",
   "Notify_all_in_this_room" : "Уведомить всех в данном чате",
+  "Old_and_new_password_required" : "Вы должны предоставить как старый, так и новый пароль для изменения пароля.",
+  "Old_Password" : "Старый пароль",
   "Online" : "В сети",
+  "Only_you_can_see_this_message" : "Только вы можете видеть это сообщение",
   "Oops!" : "Ой",
   "Opt_out_statistics" : "Не отправлять мою статистику в Rocket.Chat",
+  "Opt_out_statistics_warning" : "Отправляя вашу статистику, вы помогаете нам идентифицировать количество установок Rocket.Chat, а также узнать насколько система хорошо работает для дальнейшей ее модернизации и улучшения. Не беспокойтесь, информация о вашем чате конфиденциальна и информация о пользователях не отправляется нам. Если вы хотите отправлять нам свою статистику, уберите галочку выше. Спасибо.",
   "others" : "другие",
   "Password" : "Пароль",
+  "Password_Change_Disabled" : "Администратор отключил возможность изменения паролей",
   "Password_changed_successfully" : "Пароль успешно изменен",
+  "People" : "Люди",
   "Please_wait" : "Минуточку",
   "Please_wait_activation" : "Пожалуйста, подождите, это может занять некоторое время.",
   "Please_wait_statistics" : "Пожалуйста, подождите, статистика генерируются.",
@@ -160,6 +235,7 @@
   "Preferences_saved" : "Настройки сохранены",
   "Privacy" : "Приватность",
   "Private_Groups" : "Приватные чаты",
+  "Private_Groups_list" : "Список приватных чатов",
   "Profile" : "Профиль",
   "Profile_saved_successfully" : "Профиль успешно сохранен",
   "Proudly_developed" : "Разработано с Meteor",
@@ -168,16 +244,24 @@
   "Quick_Search" : "Быстрый поиск",
   "quote" : "цитата",
   "Recents" : "Недавние",
+  "Record" : "Запись",
   "Register" : "Зарегистрироваться",
   "Registration_Succeeded" : "Успешная регистрация",
   "Remember_me" : "Запомните меня",
   "Remove" : "Удалить",
+  "Remove_Admin" : "Разжаловать администратора",
+  "Remove_custom_oauth" : "Удалить пользовательский OAuth",
+  "Remove_from_room" : "Удалить из чата",
   "Reset_password" : "Сбросить пароль",
   "Room" : "Чат",
   "Room_name_changed" : "Название чата изменено: <em>__room_name__</em> пользователем <em>__user_by__</em>",
   "Room_name_changed_successfully" : "Название чата успешно изменено",
   "Room_not_found" : "Комната не найдена",
+  "Room_uploaded_file_list" : "Список файлов",
+  "Room_uploaded_file_list_empty" : "Нет доступных файлов",
   "room_user_count" : "%s пользователей",
+  "Rooms" : "Чаты",
+  "S_new_messages_since_s" : "%s новых сообщений с %s",
   "Save_changes" : "Сохранить изменения",
   "Search" : "Поиск",
   "Search_Messages" : "Поиск сообщений",
@@ -188,9 +272,13 @@
   "Select_an_avatar" : "Выбор автара",
   "Select_file" : "Выберите файл",
   "Selected_users" : "Выбранные участники",
-  "Send" : "Послать",
+  "Send" : "Отправить",
   "Send_confirmation_email" : "Отправить письмо с подтверждением",
   "Send_invitation_email" : "Отправить приглашение по электронной почте",
+  "Send_invitation_email_error" : "Вы не предоставили корректный e-mail адрес.",
+  "Send_invitation_email_info" : "Вы можете отправить несколько e-mail приглашений за раз.",
+  "Send_invitation_email_success" : "Вы успешно отправили приглашения на следующие адреса:",
+  "Send_invitation_email_warning" : "Для того, чтобы отправлять приглашение по электронной почте, вы должны сначала настроить параметры SMTP.",
   "Send_Message" : "Отправить сообщение",
   "Settings" : "Настройки",
   "Settings_updated" : "Настройки обновлены",
@@ -204,37 +292,52 @@
   "SMTP_Username" : "Имя пользователя SMTP-",
   "Sound" : "Звук",
   "Start_of_conversation" : "Начать диалог",
+  "Statistics" : "Статистика",
   "Stats_Active_Users" : "Активные пользователи",
+  "Stats_Avg_Channel_Users" : "Количество пользователей в публичных чатах",
+  "Stats_Avg_Private_Group_Users" : "Количество пользователей в приватных чатах",
+  "Stats_Away_Users" : "Отошедших пользователей",
+  "Stats_Max_Room_Users" : "Максимальное количество пользователей в чате",
   "Stats_Non_Active_Users" : "Неактивные пользователи",
   "Stats_Offline_Users" : "Пользователи не в сети",
   "Stats_Online_Users" : "Пользователи в сети",
   "Stats_OS_Arch" : "Архитектура ОС",
   "Stats_OS_Cpus" : "Количество процессоров в ОС",
   "Stats_OS_Freemem" : "Свободное кол-во памяти",
+  "Stats_OS_Loadavg" : "Загрузка ОС",
   "Stats_OS_Platform" : "Платформа ОС",
   "Stats_OS_Release" : "Версия ОС",
   "Stats_OS_Totalmem" : "Общее кол-во памяти в ОС",
   "Stats_OS_Type" : "Тип Системы",
   "Stats_OS_Uptime" : "Аптайм системы",
-  "Stats_Total_Channels" : "Общее кол-во каналов",
+  "Stats_Total_Channels" : "Всего публичных чатов",
+  "Stats_Total_Direct_Messages" : "Общее количество сообщений в личных чатах",
   "Stats_Total_Messages" : "Всего сообщений",
+  "Stats_Total_Private_Groups" : "Всего приватных чатов",
+  "Stats_Total_Rooms" : "Всего чатов",
   "Stats_Total_Users" : "Всего пользователей",
+  "Stop_Recording" : "Остановить запись",
+  "strike" : "зачеркнутый",
   "Submit" : "Отправить",
   "The_field_is_required" : "Поле %s обязательно.",
-  "True" : "Истина",
+  "True" : "Да",
+  "Type_your_new_password" : "Введите новый пароль",
+  "Unnamed" : "Без названия",
   "Upload_file_question" : "Загрузить файл?",
+  "Use_Emojis" : "Использовать Emojis",
   "Use_initials_avatar" : "Использовать стандартный аватар",
   "use_menu" : "Используйте боковое меню для доступа к вашим сообщениям и чатам",
   "Use_service_avatar" : "Использовать %s аватар",
   "Use_this_username" : "Использовать это имя пользователя",
   "Use_uploaded_avatar" : "Использовать загруженную аватарку",
+  "Use_url_for_avatar" : "Использовать аватар по URL",
   "User_added_by" : "Пользователь <em>__user_added__</em> добавлен <em>__user_by__</em>.",
   "User_Channels" : "Чаты пользователя",
   "User_has_been_activated" : "Пользователь активирован",
   "User_has_been_deactivated" : "Пользователь деактивирован",
   "User_has_been_deleted" : "Пользователь был удален",
   "User_Info" : "Информация о пользователе",
-  "User_is_no_longer_an_admin" : "Пользователь не больше не администратор",
+  "User_is_no_longer_an_admin" : "Пользователь больше не администратор",
   "User_is_not_activated" : "Пользователь не активирован",
   "User_is_now_an_admin" : "Пользователь теперь администратор",
   "User_joined_channel" : "Присоединился к чату.",
@@ -244,15 +347,23 @@
   "User_left_female" : "Пользователь <em>__user_left__</em> покинула чат.",
   "User_left_male" : "Пользователь <em>__user_left__</em> покинул чат.",
   "User_logged_out" : "Пользователь не в сети",
+  "User_muted_by" : "Пользователь <em>__user_muted__</em> заблокирован пользователем <em>__user_by__</em>.",
+  "User_muted_in_room" : "Пользователь заблокирован в чате",
+  "User_not_found_or_incorrect_password" : "Пользователь не найден, или введен неправильный пароль ",
   "User_removed_by" : "Пользователь <em>__user_removed__</em> удален <em>__user_by__</em>.",
   "User_Settings" : "Пользовательские настройки",
+  "User_unmuted_by" : "Пользователь <em>__user_unmuted__</em> разблокирован пользователем <em>__user_by__</em>.",
+  "User_unmuted_in_room" : "Пользователь разблокирован в чате",
   "User_updated_successfully" : "Пользователь успешно обновлен",
   "Username" : "Имя пользователя",
   "Username_cant_be_empty" : "Имя пользователя не может быть пустым",
+  "Username_Change_Disabled" : "Администратор отключил возможность изменения имен пользователей",
   "Username_description" : "Имя пользователя используется для обращения других участников к вам.",
   "Username_invalid" : "<strong>%s</strong> неправильное имя пользователя, <br/> можно использовать только цифры, точки, подчеркивания и латинские буквы",
   "Username_title" : "Зарегистрировать логин",
   "Username_unavaliable" : "<strong>%s</strong> уже используется :(",
+  "Users" : "Пользователи",
+  "UTF8_Names_Validation_Description" : "Специальные символы запрещены. Вы можете использовать - _ и . но только не в конце имени",
   "View_All" : "Посмотреть всех",
   "Wait_activation_warning" : "Прежде чем вы сможете войти в ваш аккаунт, он должен быть активирован вручную администратором.",
   "We_have_sent_password_email" : "На вашу почту было отправлено письмо с инструкциями. Если по каким-то причинам письмо не пришло, попробуйте еще раз и/или напишите нам.",
@@ -262,7 +373,9 @@
   "With_whom" : "C кем",
   "Yes_delete_it" : "Да, удалить его!",
   "you_are_in_preview_mode_of" : "Вы находитесь в режиме предварительного просмотра канала # <strong>__room_name__</strong>",
+  "You_can_use_an_emoji_as_avatar" : "Вы также можете использовать emoji в качестве аватара.",
+  "You_have_been_muted" : "Вы были заблокированы и не можете говорить в этом чате",
   "You_need_confirm_email" : "Необходимо подтвердить email для входа!",
-  "You_will_not_be_able_to_recover" : "Вы не сможете восстановить!",
+  "You_will_not_be_able_to_recover" : "Вы не сможете восстановить это сообщение!",
   "Your_Open_Source_solution" : "Ваш собственный чат на базе Open Source-технологий"
 }
\ No newline at end of file
diff --git a/i18n/sq.i18n.json b/i18n/sq.i18n.json
index 364aaf1e358c618d91d582323503404ff128d156..a76109b0e15a3fc6c7563a423bbdcebecdfd6f2a 100644
--- a/i18n/sq.i18n.json
+++ b/i18n/sq.i18n.json
@@ -1,41 +1,111 @@
 {
+  "Access_online_demo" : "Hyni demo internet",
+  "Access_Online_Demo" : "Qasja Online Demo",
+  "Accounts_EmailVerification" : "E-mail Verifikimi",
+  "Accounts_RegistrationRequired" : "Regjistrimi kërkuar",
+  "Add_Members" : "Shto Anëtarët",
   "Add_users" : "Shtoni përdoruesit",
+  "All_channels" : "Të gjitha kanalet",
   "and" : "dhe",
+  "API_Analytics" : "Analitikë",
+  "API_Embed" : "Mbjell",
   "are_also_typing" : "janë gjithashtu shtypja",
   "are_typing" : "janë shtypur",
+  "Are_you_sure" : "Jeni te sigurte qe?",
+  "Avatar_changed_successfully" : "Avatari i ndryshuar me sukses",
+  "away" : "larg",
+  "Away" : "Larg",
+  "away_female" : "larg",
+  "Away_female" : "Larg",
+  "away_male" : "larg",
+  "Away_male" : "Larg",
+  "Back_to_login" : "Kthehu tek login",
+  "bold" : "guximshme",
+  "busy" : "i zënë",
+  "Busy" : "I zënë",
+  "busy_female" : "i zënë",
+  "Busy_female" : "I zënë",
+  "busy_male" : "i zënë",
+  "Busy_male" : "I zënë",
   "Cancel" : "Anuloj",
+  "Change_avatar" : "Ndrysho avatarin",
   "Channels" : "Kanalet",
   "Channels_list" : "Lista e kanaleve publike",
   "Chat_Rooms" : "Chat dhoma",
   "close" : "Mbyll",
+  "coming_soon" : "se shpejti",
   "Confirm_password" : "Konfirmoni fjalëkalimin tuaj",
   "Contact" : "Kontakt",
   "Conversation" : "Bisedë",
+  "Create_new" : "Krijo  te ri",
+  "Create_new_direct_message_room" : "Krijo një dhomë të re mesazh të drejtpërdrejtë",
+  "Create_new_private_group" : "Krijo një grup të ri privat",
   "Create_new_public_channel" : "Krijo një kanal të ri publik",
-  "Direct_Messages" : "Mesazhe të drejtpërdrejta",
+  "Created_at" : "Krijuar në",
+  "Deleted" : "Fshihet!",
+  "Direct_Messages" : "Mesazhe Private",
+  "Drop_to_upload_file" : "Drop të ngarkoni fotografi",
+  "Duplicate_channel_name" : "Ekziston një Channel me emrin '% s'",
+  "Duplicate_private_group_name" : "Një grup privat me emrin ekziston '% s'",
   "edited" : "edited",
+  "Email_already_exists" : "Emaili ekziston",
   "Email_or_username" : "Email ose emrin e përdoruesit",
   "Email_verified" : "Email verifikuar",
   "Enter_info" : "Shkruani të dhënat tuaja",
   "Error_changing_password" : "Gabim ndryshuar fjalëkalimin",
+  "False" : "I rremë",
   "Favorites" : "Favoritet",
   "Follow_social_profiles" : "Ndiqni profilet tona sociale, na paguaj në Github dhe të ndajnë mendimet tuaja në lidhje me app rocket.chat në bord tonë Trello.",
   "Forgot_password" : "Keni harruar fjalëkalimin tuaj",
   "Fork_it_on_github" : "Paguaj atë në Github",
+  "github_no_public_email" : "Ju nuk keni ndonjë email si email publik në llogarinë tuaj GitHub",
   "Have_your_own_chat" : "Ketë web chat tuaj. Zhvilluar me Meteor.com, The Rocket.Chat është një zgjidhje e madhe për zhvilluesit në kërkim përpara për të ndërtuar dhe të zhvillohet vetë platformën e tyre chat.",
   "Hide_room" : "Dhomë Fshih",
   "History" : "Historiku",
+  "inline_code" : "inline_code",
+  "Invalid_confirm_pass" : "Konfirmimi Fjalëkalimi nuk përputhet me fjalëkalimin",
+  "Invalid_email" : "E-mail dhënë është i pavlefshëm",
+  "Invalid_name" : "Emri nuk duhet të jetë bosh",
+  "Invalid_pass" : "Fjalëkalimi nuk duhet të jetë bosh",
+  "invisible" : "i padukshëm",
+  "Invisible" : "I padukshëm",
   "is_also_typing" : "janë gjithashtu shtypja",
+  "is_also_typing_female" : "është shtypja",
+  "is_also_typing_male" : "është edhe shtypja",
   "is_typing" : "është shtypja",
+  "is_typing_female" : "është shtypja",
+  "is_typing_male" : "është shtypja",
+  "italics" : "italics",
+  "join" : "Bashkohuni",
   "Join_the_Community" : "Join Komuniteti",
+  "Language" : "Gjuhë",
   "Language_Version" : "Versioni anglisht",
+  "Last_message" : "Mesazhi i fundit",
+  "LDAP_DN" : "Të nderuar Emri (DN)",
+  "LDAP_Port" : "LDAP Port",
+  "LDAP_Url" : "LDAP URL",
   "Leave_room" : "Dhomë Leave",
+  "line" : "linjë",
   "Load_more" : "Lexo më shumë",
+  "Loading_suggestion" : "Sugjerimet Duke u ngarkuar ...",
   "Login" : "Hyrje",
+  "Login_with" : "Identifikohuni me% s",
+  "login_with" : "Ose login direkt me",
+  "Logout" : "Largohu",
   "Members" : "Anëtarët",
   "Members_List" : "Lista e Anëtarëve",
   "Members_placeholder" : "Anëtarët",
+  "Message" : "Mesazh",
+  "Message_AllowDeleting" : "Lejo Mesazh Fshirja",
+  "Message_AllowEditing" : "Lejo Mesazh Editing",
+  "Message_ShowDeletedStatus" : "Trego Statusi Deleted",
+  "Message_ShowEditedStatus" : "Trego Statusi Edited",
+  "Meta_language" : "Gjuhë",
+  "Meta_robots" : "Robots",
   "More_channels" : "Më shumë kanale",
+  "multi" : "multi",
+  "My_Account" : "Llogaria ime",
+  "n_messages" : "% s Mesazhet",
   "Name" : "Emër",
   "New_messages" : "Mesazhe të reja",
   "New_password" : "Fjalëkalimi i ri",
@@ -43,35 +113,80 @@
   "No_direct_messages_yet" : "Ju nuk kanë filluar asnjë biseda ende.",
   "No_favorites_yet" : "Ju nuk keni shtuar asnjë preferuarat ende.",
   "No_groups_yet" : "Nuk keni asnjë faqe grupe private ende.",
+  "No_permission_to_view_room" : "Ju nuk keni leje për të parë këtë dhomë",
+  "Not_allowed" : "Nuk lejohet",
+  "Not_found_or_not_allowed" : "Not Found ose jo Lejohet",
+  "Nothing_found" : "Asgjë për të gjetur",
+  "Notify_all_in_this_room" : "Të njoftojë të gjithë në këtë dhomë",
+  "Online" : "Online",
+  "Oops!" : "Oops",
+  "others" : "të tjerët",
   "Password" : "Fjalëkalim",
-  "Please_wait" : "Te lutem prit",
+  "Password_changed_successfully" : "Fjalëkalimi ndryshuar me sukses",
+  "Please_wait" : "Te lutem prisni",
   "Powered_by" : "Mundësuar nga",
+  "Privacy" : "Privacy",
   "Private_Groups" : "Grupet Private",
+  "Profile" : "Profil",
+  "Profile_saved_successfully" : "Profili ruajtur me sukses",
   "Proudly_developed" : "Zhvilluar me krenari me Meteor",
   "Quick_Search" : "Kërko Shpejt",
+  "quote" : "citoj",
   "Recents" : "Recents",
   "Register" : "Regjistrohu një llogari të re",
-  "Remember_me" : "Mua më kujtoni",
+  "Remember_me" : "Më kujton mua",
   "Remove" : "Hiq",
   "Reset_password" : "Fjalëkalimi i ri",
+  "Room" : "Dhomë",
   "Room_name_changed" : "Emri dhomë ndryshuar për:",
-  "Room_name_changed_successfully" : "Emri dhomë ndryshuar me sukses",
+  "Room_name_changed_successfully" : "Emri dhomës  është ndryshuar me sukses",
+  "Save_changes" : "Ruaj ndryshimet",
   "Search" : "Kërko",
+  "Search_settings" : "Cilësimet",
   "See_all" : "Shih të gjithë",
   "See_only_online" : "Vetëm online",
+  "Select_an_avatar" : "Zgjidh një avatar",
+  "Select_file" : "Zgjidh skedar",
+  "Select_service_to_login" : "Zgjidh një shërbim të identifikoheni për të ngarkuar foton tuaj ose ngarkoni një direkt nga kompjuteri juaj",
   "Selected_users" : "Anëtarë të zgjedhur",
   "Send_confirmation_email" : "Dërgo email konfirmimi",
   "Send_Message" : "Dërgoni mesazh",
+  "Settings" : "Cilësimet",
   "Showing_online_users" : "Duke treguar",
+  "Silence" : "Heshtje",
+  "since_creation" : "që nga% s",
   "Start_of_conversation" : "Fillimi i bisedës",
+  "strike" : "grevë",
   "Submit" : "Paraqes",
+  "The_field_is_required" : "Fusha% s është e nevojshme.",
+  "Use_initials_avatar" : "Përdorni inicialet tënd Emri i përdoruesit",
   "use_menu" : "Përdorni menynë anësore për të hyrë në dhomat tuaja dhe biseda",
+  "Use_service_avatar" : "Përdorni% s avatar",
+  "Use_this_username" : "Përdoreni këtë emrin e përdoruesit",
+  "Use_uploaded_avatar" : "Përdorni avatar ngarkuar",
   "User_added_by" : "Përdorues",
-  "User_left" : "Ka lënë kanal.",
+  "User_joined_channel" : "Është bashkuar kanalit.",
+  "User_joined_channel_female" : "Është bashkuar kanalit.",
+  "User_joined_channel_male" : "Është bashkuar kanalit.",
+  "User_left" : "Ka lënë kanalin.",
+  "User_left_female" : "Ka lënë kanalin.",
+  "User_left_male" : "Ka lënë kanalin.",
   "User_logged_out" : "Përdoruesi është regjistruar jashtë",
   "User_removed_by" : "Përdorues",
+  "User_Settings" : "Përdoruesi Cilësimet",
+  "Username" : "Emri i përdoruesit",
+  "Username_cant_be_empty" : "Emri i përdoruesit nuk mund të jetë bosh",
+  "Username_description" : "Emri i përdoruesit është përdorur për të lejuar të tjerët për të përmendur ju në mesazhe.",
   "View_All" : "Shiko të gjitha",
+  "We_have_sent_password_email" : "Ne të dërguam ty një e-mail me udhëzime të rivendosur fjalëkalimin. Nëse ju nuk merrni një e-mail shpejti, ju lutem të ktheheni dhe provoni përsëri.",
+  "We_have_sent_registration_email" : "Ne të dërguam ty një e-mail për të konfirmuar regjistrimin tuaj. Nëse ju nuk merrni një e-mail shpejti, ju lutem të ktheheni dhe provoni përsëri.",
   "Welcome" : "I mirëpritur",
   "Welcome_to_the" : "Mirë se vini në",
-  "You_need_confirm_email" : "Ju duhet për të konfirmuar email-it tuaj të identifikoheni!"
+  "With_whom" : "Me kë",
+  "Yes_delete_it" : "Po, fshini atë!",
+  "you_are_in_preview_mode_of" : "Ju jeni në mënyrë preview e kanalit #",
+  "You_need_confirm_email" : "Ju duhet për të konfirmuar email-it tuaj të identifikoheni!",
+  "You_will_not_be_able_to_recover" : "Ju nuk do të jetë në gjendje të mbulojë këtë mesazh!",
+  "Your_entry_has_been_deleted" : "Hyrja juaj është fshirë.",
+  "Your_Open_Source_solution" : "Vet Open Source chat zgjidhja juaj"
 }
\ No newline at end of file
diff --git a/i18n/sr.i18n.json b/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..39a02b9d8b427422a1302ff20784339e21178347
--- /dev/null
+++ b/i18n/sr.i18n.json
@@ -0,0 +1,67 @@
+{
+  "Add_users" : "Додај кориснике",
+  "and" : "и",
+  "are_also_typing" : "такође куцају",
+  "are_typing" : "куцају",
+  "Cancel" : "Откажи",
+  "Channels" : "Канали",
+  "Channels_list" : "Списак јавних канала",
+  "Chat_Rooms" : "Собе за ћаскање",
+  "close" : "затвори",
+  "Contact" : "Контакт",
+  "Conversation" : "Разговор",
+  "Create_new_public_channel" : "Направи нови јавни канал",
+  "Direct_Messages" : "Директне поруке",
+  "edited" : "измењено",
+  "Email_verified" : "Е-адреса потврђена",
+  "Error_changing_password" : "Грешка приликом промене лозинке",
+  "Favorites" : "Омиљено",
+  "Follow_social_profiles" : "Пратите наше друштвене профиле, форкујте нас на Гитхабу и поделите ваша мишљења о нашој rocket.chat апликацији на нашој Трело табли.",
+  "Fork_it_on_github" : "Форкуј на Гитхабу",
+  "Hide_room" : "Сакриј собу",
+  "History" : "Историјат",
+  "Invalid_room_name" : "<strong>%s</strong> није исправно име канала,<br/> користите само слова, бројеве и цртице",
+  "is_also_typing" : "такође куца",
+  "is_typing" : "куца",
+  "Join_the_Community" : "Придружи се заједници",
+  "Language_Version" : "Енглеска верзија",
+  "Leave_room" : "Напусти собу",
+  "Load_more" : "Учитај још",
+  "Login" : "Пријава",
+  "Members" : "Чланови",
+  "Members_List" : "Списак чланова",
+  "Members_placeholder" : "Чланови",
+  "More_channels" : "Више канала",
+  "Name" : "Име",
+  "New_messages" : "Нове поруке",
+  "New_password" : "Нова лозинка",
+  "No_channels_yet" : "Нисте члан било ког канала још.",
+  "No_direct_messages_yet" : "Нисте започели ниједан разговор још.",
+  "No_favorites_yet" : "Нисте означили ништа омиљеним још.",
+  "No_groups_yet" : "Немате ниједну приватну групу за сада.",
+  "Please_wait" : "Сачекајте",
+  "Powered_by" : "Покреће",
+  "Private_Groups" : "Приватне групе",
+  "Proudly_developed" : "Поносно развијено користећи Метеор",
+  "Quick_Search" : "Брза претрага",
+  "Recents" : "Скорашње",
+  "Remove" : "Уклони",
+  "Reset_password" : "Поново постави лозинку",
+  "Room_name_changed" : "Назив собе промењен у: <em>__room_name__</em> променио/ла <em>__user_by__</em>",
+  "Room_name_changed_successfully" : "Име собе успешно промењено",
+  "Search" : "Претрага",
+  "See_all" : "Погледај све",
+  "See_only_online" : "Само на мрежи",
+  "Selected_users" : "Изабрани чланови",
+  "Send_confirmation_email" : "Пошаљи потврдну поруку",
+  "Send_Message" : "Пошаљи поруку",
+  "Showing_online_users" : "Приказујем <b>__total_online__</b> од __total__ корисника",
+  "Start_of_conversation" : "Почетак разговора",
+  "Submit" : "Пошаљи",
+  "User_added_by" : "Корисник/ца <em>__user_added__</em> је додат(а) од стране <em>__user_by__</em>.",
+  "User_left" : "је напустио/ла канал.",
+  "User_logged_out" : "Корисник је одјављен",
+  "User_removed_by" : "Корисник/ца <em>__user_removed__</em> је уклоњен од стране <em>__user_by__</em>.",
+  "View_All" : "Погледај све",
+  "Welcome" : "Добродошли <em>%s</em>."
+}
\ No newline at end of file
diff --git a/install.sh b/install.sh
index 9980acc5751ca4d6154280c3c165963a9af4a3fc..361dbcb90f63eb0baf48ad1ae7868b08c33b6e66 100755
--- a/install.sh
+++ b/install.sh
@@ -8,7 +8,7 @@ if [ "$1" == "development" ]; then
 fi
 
 cd $ROOTPATH
-curl -fSL "https://s3.amazonaws.com/rocketchatbuild/demo.rocket.chat-v.latest.tgz" -o rocket.chat.tgz
+curl -fSL "https://s3.amazonaws.com/rocketchatbuild/rocket.chat-develop.tgz" -o rocket.chat.tgz
 tar zxf rocket.chat.tgz  &&  rm rocket.chat.tgz
 cd $ROOTPATH/bundle/programs/server
 npm install
diff --git a/lib/fileUpload.coffee b/lib/fileUpload.coffee
index 62cf49677a5425a02a3c70a4031a3d7c9b107c27..3ee0e68c276d1b55afb19829e8d4644caeadff88 100644
--- a/lib/fileUpload.coffee
+++ b/lib/fileUpload.coffee
@@ -31,6 +31,12 @@ if UploadFS?
 		return false;
 
 	initFileStore = ->
+		cookie = new Cookies()
+		if Meteor.isClient
+			cookie.set 'rc_uid', Meteor.userId();
+			cookie.set 'rc_token', Meteor._localStorage.getItem('Meteor.loginToken')
+			cookie.send()
+
 		Meteor.fileStore = new UploadFS.store.GridFS
 			collection: fileCollection
 			name: 'rocketchat_uploads'
@@ -40,13 +46,49 @@ if UploadFS?
 				contentTypes: fileUploadMediaWhiteList()
 			onFinishUpload: ->
 				console.log arguments
+			transformWrite: (readStream, writeStream, fileId, file) ->
+				if RocketChatFile.enabled is false or not /^image\/.+/.test(file.type)
+					return readStream.pipe writeStream
+
+				stream = undefined
+
+				identify = (err, data) ->
+					if err?
+						return stream.pipe writeStream
+
+					file.identify =
+						format: data.format
+						size: data.size
+
+					if data.Orientation? and data.Orientation not in ['', 'Unknown', 'Undefined']
+						RocketChatFile.gm(stream).autoOrient().stream().pipe(writeStream)
+					else
+						stream.pipe writeStream
+
+				stream = RocketChatFile.gm(readStream).identify(identify).stream()
+
 			onRead: (fileId, file, req, res) ->
+				if RocketChat.settings.get 'FileUpload_ProtectFiles'
+					rawCookies = req.headers.cookie if req?.headers?.cookie?
+					uid = cookie.get('rc_uid', rawCookies) if rawCookies?
+					token = cookie.get('rc_token', rawCookies) if rawCookies?
+
+					if not uid?
+						uid = req.query.rc_uid
+						token = req.query.rc_token
+
+					unless uid and token and RocketChat.models.Users.findOneByIdAndLoginToken(uid, token)
+						res.writeHead 403
+						return false
+
 				res.setHeader 'content-disposition', "attachment; filename=\"#{ encodeURIComponent(file.name) }\""
+				return true
 
+Meteor.startup ->
 	if Meteor.isServer
 		initFileStore()
 	else
 		Tracker.autorun (c) ->
-			if RocketChat.settings.subscription.ready()
+			if Meteor.userId() and RocketChat.settings.subscription.ready()
 				initFileStore()
 				c.stop()
diff --git a/packages/meteor-accounts-saml/saml_server.js b/packages/meteor-accounts-saml/saml_server.js
index 030922b82b941a2289e6ed0ba42bc467bec52a96..1dd3f227201cd0151e9023022742ae6333f42b44 100644
--- a/packages/meteor-accounts-saml/saml_server.js
+++ b/packages/meteor-accounts-saml/saml_server.js
@@ -78,6 +78,13 @@ Accounts.registerLoginHandler(function (loginRequest) {
 		console.log("RESULT :" + JSON.stringify(loginResult));
 	}
 
+	if (loginResult == undefined) {
+		return {
+			type: "saml",
+			error: new Meteor.Error(Accounts.LoginCancelledError.numericError, "No matching login attempt found")
+		}
+	}
+
 	if (loginResult && loginResult.profile && loginResult.profile.email) {
 		var user = Meteor.users.findOne({
 			'emails.address': loginResult.profile.email
@@ -87,8 +94,10 @@ Accounts.registerLoginHandler(function (loginRequest) {
 			var newUser = {
 				name: loginResult.profile.cn || loginResult.profile.username,
 				active: true,
+				globalRoles: ['user'],
 				emails: [{
-					address: loginResult.profile.email
+					address: loginResult.profile.email,
+					verified: true
 				}]
 			};
 
@@ -99,10 +108,8 @@ Accounts.registerLoginHandler(function (loginRequest) {
 				}
 			}
 
-			Meteor.users.insert(newUser);
-			user = Meteor.users.findOne({
-				'emails.address': loginResult.profile.email
-			});
+			var userId = Accounts.insertUserDoc({}, newUser);
+			user = Meteor.users.findOne(userId);
 		}
 
 		//creating the token and adding to the user
diff --git a/packages/rocketchat-api/package.js b/packages/rocketchat-api/package.js
new file mode 100644
index 0000000000000000000000000000000000000000..bc639498450e578b149a13e7d2d62ac7f43105a3
--- /dev/null
+++ b/packages/rocketchat-api/package.js
@@ -0,0 +1,24 @@
+Package.describe({
+	name: 'rocketchat:api',
+	version: '0.0.1',
+	summary: 'Rest API',
+	git: ''
+});
+
+Package.onUse(function(api) {
+	api.versionsFrom('1.0');
+
+	api.use([
+		'coffeescript',
+		'underscore',
+		'rocketchat:lib',
+		'nimble:restivus'
+	]);
+
+	api.addFiles('server/api.coffee', 'server');
+	api.addFiles('server/routes.coffee', 'server');
+});
+
+Package.onTest(function(api) {
+
+});
diff --git a/packages/rocketchat-api/server/api.coffee b/packages/rocketchat-api/server/api.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..e15db14f1fa9741eafa6c13a2b71a58799f39a51
--- /dev/null
+++ b/packages/rocketchat-api/server/api.coffee
@@ -0,0 +1,61 @@
+class API extends Restivus
+	constructor: ->
+		@authMethods = []
+		super
+
+	addAuthMethod: (method) ->
+		@authMethods.push method
+
+	success: (result={}) ->
+		if _.isObject(result)
+			result.success = true
+
+		return {} =
+			statusCode: 200
+			body: result
+
+	failure: (result) ->
+		if _.isObject(result)
+			result.success = false
+		else
+			result =
+				success: false
+				error: result
+
+		return {} =
+			statusCode: 400
+			body: result
+
+	unauthorized: (msg) ->
+		return {} =
+			statusCode: 401
+			body:
+				success: false
+				error: msg or 'unauthorized'
+
+
+RocketChat.API = {}
+
+
+RocketChat.API.v1 = new API
+	version: 'v1'
+	useDefaultAuth: true
+	prettyJson: false
+	enableCors: false
+	auth:
+		token: 'services.resume.loginTokens.hashedToken'
+		user: ->
+			if @bodyParams?.payload?
+				@bodyParams = JSON.parse @bodyParams.payload
+
+			for method in RocketChat.API.v1.authMethods
+				result = method.apply @, arguments
+				if result not in [undefined, null, false]
+					return result
+
+			if @request.headers['x-auth-token']
+				token = Accounts._hashLoginToken @request.headers['x-auth-token']
+
+			return {} =
+				userId: @request.headers['x-user-id']
+				token: token
diff --git a/packages/rocketchat-api/server/routes.coffee b/packages/rocketchat-api/server/routes.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..16a3efc14ae58bfbc82d7cd06382e9cc6567d5b8
--- /dev/null
+++ b/packages/rocketchat-api/server/routes.coffee
@@ -0,0 +1,109 @@
+RocketChat.API.v1.addRoute 'info', authRequired: false,
+	get: -> RocketChat.Info
+
+
+RocketChat.API.v1.addRoute 'me', authRequired: true,
+	get: ->
+		return _.pick @user, [
+			'_id'
+			'name'
+			'emails'
+			'status'
+			'statusConnection'
+			'username'
+			'utcOffset'
+			'active'
+			'language'
+		]
+
+
+# Send Channel Message
+RocketChat.API.v1.addRoute 'chat.messageExamples', authRequired: true,
+	get: ->
+		return RocketChat.API.v1.success
+			body: [
+				token: Random.id(24)
+				channel_id: Random.id()
+				channel_name: 'general'
+				timestamp: new Date
+				user_id: Random.id()
+				user_name: 'rocket.cat'
+				text: 'Sample text 1'
+				trigger_word: 'Sample'
+			,
+				token: Random.id(24)
+				channel_id: Random.id()
+				channel_name: 'general'
+				timestamp: new Date
+				user_id: Random.id()
+				user_name: 'rocket.cat'
+				text: 'Sample text 2'
+				trigger_word: 'Sample'
+			,
+				token: Random.id(24)
+				channel_id: Random.id()
+				channel_name: 'general'
+				timestamp: new Date
+				user_id: Random.id()
+				user_name: 'rocket.cat'
+				text: 'Sample text 3'
+				trigger_word: 'Sample'
+			]
+
+
+# Send Channel Message
+RocketChat.API.v1.addRoute 'chat.postMessage', authRequired: true,
+	post: ->
+		try
+			@bodyParams.bot =
+				u: @userId
+
+			messageReturn = processWebhookMessage @bodyParams, @user
+
+			if not messageReturn?
+				return RocketChat.API.v1.failure 'unknown-error'
+
+			return RocketChat.API.v1.success
+				ts: Date.now()
+				channel: messageReturn.channel
+				message: messageReturn.message
+		catch e
+			return RocketChat.API.v1.failure e.error
+
+# Set Channel Topic
+RocketChat.API.v1.addRoute 'channels.setTopic', authRequired: true,
+	post: ->
+		if not @bodyParams.channel?
+			return RocketChat.API.v1.failure 'Body param "channel" is required'
+
+		if not @bodyParams.topic?
+			return RocketChat.API.v1.failure 'Body param "topic" is required'
+
+		unless RocketChat.authz.hasPermission(@userId, 'edit-room', @bodyParams.channel)
+			return RocketChat.API.v1.unauthorized()
+
+		if not RocketChat.saveRoomTopic(@bodyParams.channel, @bodyParams.topic)
+			return RocketChat.API.v1.failure 'invalid_channel'
+
+		return RocketChat.API.v1.success
+			topic: @bodyParams.topic
+
+
+# Create Channel
+RocketChat.API.v1.addRoute 'channels.create', authRequired: true,
+	post: ->
+		if not @bodyParams.name?
+			return RocketChat.API.v1.failure 'Body param "name" is required'
+
+		if not RocketChat.authz.hasPermission(@userId, 'create-c')
+			return RocketChat.API.v1.unauthorized()
+
+		id = undefined
+		try
+			Meteor.runAsUser this.userId, =>
+				id = Meteor.call 'createChannel', @bodyParams.name, []
+		catch e
+			return RocketChat.API.v1.failure e.name + ': ' + e.message
+
+		return RocketChat.API.v1.success
+			channel: RocketChat.models.Rooms.findOne({_id: id.rid})
diff --git a/packages/rocketchat-assets/.npm/package/npm-shrinkwrap.json b/packages/rocketchat-assets/.npm/package/npm-shrinkwrap.json
index f69e18d8fe1f4e8ece18f785cccb6f4acf9e5566..78afe4f3ae8144939a273a33a428d50ebe6beadc 100644
--- a/packages/rocketchat-assets/.npm/package/npm-shrinkwrap.json
+++ b/packages/rocketchat-assets/.npm/package/npm-shrinkwrap.json
@@ -2,6 +2,14 @@
   "dependencies": {
     "image-size": {
       "version": "0.4.0"
+    },
+    "mime-types": {
+      "version": "2.1.9",
+      "dependencies": {
+        "mime-db": {
+          "version": "1.21.0"
+        }
+      }
     }
   }
 }
diff --git a/packages/rocketchat-assets/package.js b/packages/rocketchat-assets/package.js
index e5f75eaf3d27f5f47f50790894c19bdc0b1b7bc3..7f299bb33aa5121657480bf3091da94519857e72 100644
--- a/packages/rocketchat-assets/package.js
+++ b/packages/rocketchat-assets/package.js
@@ -13,14 +13,15 @@ Package.onUse(function(api) {
 		'underscore',
 		'webapp',
 		'rocketchat:file',
-		'rocketchat:lib@0.0.1'
+		'rocketchat:lib'
 	]);
 
 	api.addFiles('server/assets.coffee', 'server');
 });
 
 Npm.depends({
-	"image-size": "0.4.0"
+	"image-size": "0.4.0",
+	"mime-types": "2.1.9"
 });
 
 Package.onTest(function(api) {
diff --git a/packages/rocketchat-assets/server/assets.coffee b/packages/rocketchat-assets/server/assets.coffee
index acf9d258456c1a69c3082201375ecacfcdf74e38..4c99b703d1d0cec937f52f0e46bf8818ab2b9e0b 100644
--- a/packages/rocketchat-assets/server/assets.coffee
+++ b/packages/rocketchat-assets/server/assets.coffee
@@ -1,5 +1,5 @@
 sizeOf = Npm.require 'image-size'
-
+mime = Npm.require 'mime-types'
 
 @RocketChatAssetsInstance = new RocketChatFile.GridFS
 	name: 'assets'
@@ -11,8 +11,7 @@ assets =
 		defaultUrl: 'favicon.ico?v=3'
 		constraints:
 			type: 'image'
-			contentType: 'image/vnd.microsoft.icon'
-			extention: 'ico'
+			extension: 'ico'
 			width: undefined
 			height: undefined
 	'favicon.svg':
@@ -20,8 +19,7 @@ assets =
 		defaultUrl: '/images/logo/icon.svg?v=3'
 		constraints:
 			type: 'image'
-			contentType: 'image/svg+xml'
-			extention: 'svg'
+			extension: 'svg'
 			width: undefined
 			height: undefined
 	'favicon_64.png':
@@ -29,8 +27,7 @@ assets =
 		defaultUrl: 'images/logo/favicon-64x64.png?v=3'
 		constraints:
 			type: 'image'
-			contentType: 'image/png'
-			extention: 'png'
+			extension: 'png'
 			width: 64
 			height: 64
 	'favicon_96.png':
@@ -38,8 +35,7 @@ assets =
 		defaultUrl: 'images/logo/favicon-96x96.png?v=3'
 		constraints:
 			type: 'image'
-			contentType: 'image/png'
-			extention: 'png'
+			extension: 'png'
 			width: 96
 			height: 96
 	'favicon_128.png':
@@ -47,8 +43,7 @@ assets =
 		defaultUrl: 'images/logo/favicon-128x128.png?v=3'
 		constraints:
 			type: 'image'
-			contentType: 'image/png'
-			extention: 'png'
+			extension: 'png'
 			width: 128
 			height: 128
 	'favicon_192.png':
@@ -56,8 +51,7 @@ assets =
 		defaultUrl: 'images/logo/android-chrome-192x192.png?v=3'
 		constraints:
 			type: 'image'
-			contentType: 'image/png'
-			extention: 'png'
+			extension: 'png'
 			width: 192
 			height: 192
 	'favicon_256.png':
@@ -65,8 +59,7 @@ assets =
 		defaultUrl: 'images/logo/favicon-256x256.png?v=3'
 		constraints:
 			type: 'image'
-			contentType: 'image/png'
-			extention: 'png'
+			extension: 'png'
 			width: 256
 			height: 256
 
@@ -104,8 +97,8 @@ Meteor.methods
 		if not assets[asset]?
 			throw new Meteor.Error "Invalid_asset"
 
-		if contentType isnt assets[asset].constraints.contentType
-			throw new Meteor.Error "Invalid_file_type"
+		if mime.extension(contentType) isnt assets[asset].constraints.extension
+			throw new Meteor.Error "Invalid_file_type", contentType
 
 		file = new Buffer(binaryContent, 'binary')
 
diff --git a/packages/rocketchat-authorization/README.md b/packages/rocketchat-authorization/README.md
index 239b085c856dc0d1280af7d604b5f5a40c2d2eb7..c2365d83f6986f4c0c0b0889aa1f4c9b147942c3 100644
--- a/packages/rocketchat-authorization/README.md
+++ b/packages/rocketchat-authorization/README.md
@@ -1,6 +1,6 @@
-Supports role or permission based authorization, and defines the association between them. 
+Supports role or permission based authorization, and defines the association between them.
 
-A user is associated with role(s), and a role is associated with permission(s).  This package depends on alanning:roles for the role/user association, while the role/permission association is handled internally.  Thus, the underlying alanning:roles has no concept of a permission or the association between a role and permission.   
+A user is associated with role(s), and a role is associated with permission(s).  This package depends on alanning:roles for the role/user association, while the role/permission association is handled internally.  Thus, the underlying alanning:roles has no concept of a permission or the association between a role and permission.
 
 Authorization checks can be done based on a role or permission.  However, permission based checks are preferred because they loosely associate an action with a role.  For example:
 
@@ -19,13 +19,12 @@ if hasRole(userId, ['admin','site-moderator','moderator'])
 
 Usage:
 ```
-# assign user to moderator role.  Permissions scoped globally
-# user can moderate (e.g. edit channel name, delete private group message) for all rooms
-RocketChat.authz.addUsersToRoles(userId, 'moderator')
+# assign user to admin role.  Permissions scoped globally
+RocketChat.authz.addUserRoles(userId, 'admin')
 
 # assign user to moderator role.  Permissions scoped to the specified room
 # user can moderate (e.g. edit channel name, delete private group message) for only one room specified by the roomId
-RocketChat.authz.addUsersToRoles(userId, 'moderator', roomId )
+RocketChat.authz.addUserRoles(userId, 'moderator', roomId )
 
 # check if user can modify message for any room
 RocketChat.authz.hasPermission(userId, 'edit-message')
@@ -37,5 +36,5 @@ RocketChat.authz.hasPermission(userId, 'edit-message', roomId)
 
 Notes:
 1. Roles are statically defined.  UI needs to be implemented to dynamically assign permission(s) to a Role
-2. 'admin', 'moderator', 'user' role identifiers should NOT be changed (unless you update the associated code) because they are referenced when creating users and creating rooms.  
-3. edit, delete message permissions are at either the global or room scope.  i.e. role with edit-message with GLOBAL scope can edit ANY message regardless of the room type.  However, role with edit-message with room scope can only edit messages for the room.  The global scope is associated with the admin role while the "room-scoped" permission is assigned to the room "moderator" (room creator).  If we want a middle ground that allows for edit-message for only channel/group/direct, then we need to create individual edit-c-message, edit-p-message, edit-d-message permissions. 
+2. 'admin', 'moderator', 'user' role identifiers should NOT be changed (unless you update the associated code) because they are referenced when creating users and creating rooms.
+3. edit, delete message permissions are at either the global or room scope.  i.e. role with edit-message with GLOBAL scope can edit ANY message regardless of the room type.  However, role with edit-message with room scope can only edit messages for the room.  The global scope is associated with the admin role while the "room-scoped" permission is assigned to the room "moderator" (room creator).  If we want a middle ground that allows for edit-message for only channel/group/direct, then we need to create individual edit-c-message, edit-p-message, edit-d-message permissions.
diff --git a/packages/rocketchat-authorization/client/hasPermission.coffee b/packages/rocketchat-authorization/client/hasPermission.coffee
index 9d636b9552e7bc47ebb78e80fbb66b60af6a75c1..015ec854ee72935b6bc854010e417cc3f31b1973 100644
--- a/packages/rocketchat-authorization/client/hasPermission.coffee
+++ b/packages/rocketchat-authorization/client/hasPermission.coffee
@@ -1,25 +1,29 @@
-atLeastOne = (toFind, toSearch) ->
-	console.log 'toFind: ', toFind if window.rocketDebug
-	console.log 'toSearch: ', toSearch if window.rocketDebug
-	return  not _.isEmpty(_.intersection(toFind, toSearch))
-
-all = (toFind, toSearch) ->
-	toFind = _.uniq(toFind)
-	toSearch = _.uniq(toSearch)
-	return _.isEmpty( _.difference( toFind, toSearch))
+atLeastOne = (permissions, scope) ->
+	return _.some permissions, (permissionId) ->
+		permission = ChatPermissions.findOne permissionId
+		return _.some permission.roles, (roleName) ->
+			role = RocketChat.models.Roles.findOne roleName
+			roleScope = role?.scope
+			return RocketChat.models[roleScope]?.isUserInRole?(Meteor.userId(), roleName, scope)
+
+all = (permissions, scope) ->
+	return _.every permissions, (permissionId) ->
+		permission = ChatPermissions.findOne permissionId
+		return _.some permission.roles, (roleName) ->
+			role = RocketChat.models.Roles.findOne roleName
+			roleScope = role?.scope
+			return RocketChat.models[roleScope]?.isUserInRole?(Meteor.userId(), roleName, scope)
 
 Template.registerHelper 'hasPermission', (permission, scope) ->
-	unless _.isString( scope )
-		scope = Roles.GLOBAL_GROUP
-	return hasPermission( permission, scope, atLeastOne)
+	return hasPermission(permission, scope, atLeastOne)
 
-RocketChat.authz.hasAllPermission = (permissions, scope=Roles.GLOBAL_GROUP) ->
-	return hasPermission( permissions, scope, all )
+RocketChat.authz.hasAllPermission = (permissions, scope) ->
+	return hasPermission(permissions, scope, all)
 
-RocketChat.authz.hasAtLeastOnePermission = (permissions, scope=Roles.GLOBAL_GROUP) ->
+RocketChat.authz.hasAtLeastOnePermission = (permissions, scope) ->
 	return hasPermission(permissions, scope, atLeastOne)
 
-hasPermission = (permissions, scope=Roles.GLOBAL_GROUP, strategy) ->
+hasPermission = (permissions, scope, strategy) ->
 	userId = Meteor.userId()
 
 	unless userId
@@ -30,10 +34,4 @@ hasPermission = (permissions, scope=Roles.GLOBAL_GROUP, strategy) ->
 
 	permissions = [].concat permissions
 
-	roleNames = Roles.getRolesForUser(userId, scope)
-
-	userPermissions = []
-	for roleName in roleNames
-		userPermissions = userPermissions.concat(_.pluck(ChatPermissions.find({roles : roleName }).fetch(), '_id'))
-
-	return strategy( permissions, userPermissions)
+	return strategy(permissions, scope)
diff --git a/packages/rocketchat-authorization/client/hasRole.coffee b/packages/rocketchat-authorization/client/hasRole.coffee
index 3140a74bfe635cfc05d6ec20b8c59f4eb84f67bd..aff335e48b2fd0f7ae37fce3f2d00bb98796124c 100644
--- a/packages/rocketchat-authorization/client/hasRole.coffee
+++ b/packages/rocketchat-authorization/client/hasRole.coffee
@@ -1,8 +1,3 @@
-RocketChat.authz.hasRole = (userId, roleName, scope=Roles.GLOBAL_GROUP) ->
-	unless Meteor.userId()
-		return false
-
-	roleName = [].concat roleName
-
-	# per alanning:roles, returns true if user is in ANY roles
-	return Roles.userIsInRole(userId, roleName, scope)
+RocketChat.authz.hasRole = (userId, roleNames, scope) ->
+	roleNames = [].concat roleNames
+	return RocketChat.models.Roles.isUserInRoles(userId, roleNames, scope) # true if user is in ANY role
diff --git a/packages/rocketchat-authorization/client/collection.coffee b/packages/rocketchat-authorization/client/lib/ChatPermissions.coffee
similarity index 96%
rename from packages/rocketchat-authorization/client/collection.coffee
rename to packages/rocketchat-authorization/client/lib/ChatPermissions.coffee
index b719f7f9ed648c4d5df0d16de2fd541787017d97..e9adaae10f2f65de5c9d31f3283895af25ec4649 100644
--- a/packages/rocketchat-authorization/client/collection.coffee
+++ b/packages/rocketchat-authorization/client/lib/ChatPermissions.coffee
@@ -1 +1 @@
-@ChatPermissions = new Meteor.Collection 'rocketchat_permissions'
\ No newline at end of file
+@ChatPermissions = new Meteor.Collection 'rocketchat_permissions'
diff --git a/packages/rocketchat-authorization/client/lib/models/Roles.coffee b/packages/rocketchat-authorization/client/lib/models/Roles.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..5d94d584c613bbc6d950efde4d3c28314197c5e9
--- /dev/null
+++ b/packages/rocketchat-authorization/client/lib/models/Roles.coffee
@@ -0,0 +1,14 @@
+RocketChat.models.Roles = new Meteor.Collection 'rocketchat_roles'
+
+RocketChat.models.Roles.findUsersInRole = (name, scope, options) ->
+	role = @findOne name
+	roleScope = role?.scope or 'Users'
+	RocketChat.models[roleScope]?.findUsersInRoles?(name, scope, options)
+
+RocketChat.models.Roles.isUserInRoles = (userId, roles, scope) ->
+	roles = [].concat roles
+	_.some roles, (roleName) =>
+		role = @findOne roleName
+		roleScope = role?.scope or 'Users'
+		return RocketChat.models[roleScope]?.isUserInRole?(userId, roleName, scope)
+
diff --git a/packages/rocketchat-authorization/client/lib/models/Subscriptions.js b/packages/rocketchat-authorization/client/lib/models/Subscriptions.js
new file mode 100644
index 0000000000000000000000000000000000000000..7ff02a801037048cd704df777f0a559dce497751
--- /dev/null
+++ b/packages/rocketchat-authorization/client/lib/models/Subscriptions.js
@@ -0,0 +1,35 @@
+Meteor.subscribe('scopedRoles', 'Subscriptions');
+
+if (_.isUndefined(RocketChat.models.Subscriptions)) {
+	RocketChat.models.Subscriptions = {}
+}
+
+RocketChat.models.Subscriptions.isUserInRole = function(userId, roleName, roomId) {
+	query = {
+		rid: roomId,
+		roles: roleName
+	};
+
+	return !_.isUndefined(this.findOne(query));
+}
+
+RocketChat.models.Subscriptions.findUsersInRoles = function(roles, scope, options) {
+	roles = [].concat(roles);
+
+	var query = {
+		roles: { $in: roles }
+	}
+
+	if (scope) {
+		query.rid = scope;
+	}
+
+	subscriptions = this.find(query).fetch();
+
+	users = _.compact(_.map(subscriptions, function(subscription) {
+		if ('undefined' !== typeof subscription.u && 'undefined' !== typeof subscription.u._id)
+			return subscription.u._id
+	}));
+
+	return RocketChat.models.Users.find({ _id: { $in: users } }, options);
+}
diff --git a/packages/rocketchat-authorization/client/lib/models/Users.js b/packages/rocketchat-authorization/client/lib/models/Users.js
new file mode 100644
index 0000000000000000000000000000000000000000..e7f61495105807867555a801164b9265caf04dcc
--- /dev/null
+++ b/packages/rocketchat-authorization/client/lib/models/Users.js
@@ -0,0 +1,24 @@
+Meteor.subscribe('scopedRoles', 'Users');
+
+if (_.isUndefined(RocketChat.models.Users)) {
+	RocketChat.models.Users = {}
+}
+
+RocketChat.models.Users.isUserInRole = function(userId, roleName) {
+	query = {
+		_id: userId,
+		roles: roleName
+	};
+
+	return !_.isUndefined(this.findOne(query));
+}
+
+RocketChat.models.Users.findUsersInRoles = function(roles, scope, options) {
+	roles = [].concat(roles);
+
+	var query = {
+		roles: { $in: roles }
+	}
+
+	return this.find(query, options);
+}
diff --git a/packages/rocketchat-authorization/client/route.coffee b/packages/rocketchat-authorization/client/route.coffee
index fe115fedcff8994742bb5ebcf9d73c7a88c44ae1..fce94d5ad7d8122e5eaab6275d8195f744308fd9 100644
--- a/packages/rocketchat-authorization/client/route.coffee
+++ b/packages/rocketchat-authorization/client/route.coffee
@@ -1,6 +1,7 @@
 FlowRouter.route '/admin/permissions',
 	name: 'admin-permissions'
 	action: (params) ->
+		RocketChat.TabBar.showGroup 'admin-permissions'
 		BlazeLayout.render 'main',
 			center: 'pageContainer'
 			pageTitle: t('Permissions')
@@ -9,6 +10,7 @@ FlowRouter.route '/admin/permissions',
 FlowRouter.route '/admin/permissions/:name?/edit',
 	name: 'admin-permissions-edit'
 	action: (params) ->
+		RocketChat.TabBar.showGroup 'admin-permissions'
 		BlazeLayout.render 'main',
 			center: 'pageContainer'
 			pageTitle: t('Role_Editing')
@@ -17,6 +19,7 @@ FlowRouter.route '/admin/permissions/:name?/edit',
 FlowRouter.route '/admin/permissions/new',
 	name: 'admin-permissions-new'
 	action: (params) ->
+		RocketChat.TabBar.showGroup 'admin-permissions'
 		BlazeLayout.render 'main',
 			center: 'pageContainer'
 			pageTitle: t('Role_Editing')
diff --git a/packages/rocketchat-authorization/client/startup.coffee b/packages/rocketchat-authorization/client/startup.coffee
index 144f7ea88f9ae3f0735cec28551a19b7085bcc5e..61f0527598d0fe448a263d6f5c9d82ca8d390b88 100644
--- a/packages/rocketchat-authorization/client/startup.coffee
+++ b/packages/rocketchat-authorization/client/startup.coffee
@@ -1,3 +1,5 @@
+Meteor.subscribe 'roles'
+
 RocketChat.authz.subscription = Meteor.subscribe 'permissions'
 
 RocketChat.AdminBox.addOption
diff --git a/packages/rocketchat-authorization/client/views/permissions.coffee b/packages/rocketchat-authorization/client/views/permissions.coffee
index 0e134582401e8e84e1224610ec2572324770ec6c..af92f2c126605ba8bacee8042285ef1fd42c6d01 100644
--- a/packages/rocketchat-authorization/client/views/permissions.coffee
+++ b/packages/rocketchat-authorization/client/views/permissions.coffee
@@ -8,7 +8,7 @@ Template.permissions.helpers
 
 	granted: (roles) ->
 		if roles?
-			return 'checked' if roles.indexOf(@name) isnt -1
+			return 'checked' if roles.indexOf(@_id) isnt -1
 
 	hasPermission: ->
 		return RocketChat.authz.hasAllPermission 'access-permissions'
@@ -31,18 +31,14 @@ Template.permissions.onCreated ->
 		added: {}
 		removed: {}
 
-	subs = @subscribe 'roles'
-
 	Tracker.autorun =>
-		if subs.ready()
-			@roles.set Roles.getAllRoles().fetch()
+		@roles.set RocketChat.models.Roles.find().fetch()
 
 	Tracker.autorun =>
-		if subs.ready()
-			ChatPermissions.find().observeChanges
-				added: (id, fields) =>
-					@permissionByRole[id] = fields.roles
-				changed: (id, fields) =>
-					@permissionByRole[id] = fields.roles
-				removed: (id) =>
-					delete @permissionByRole[id]
+		ChatPermissions.find().observeChanges
+			added: (id, fields) =>
+				@permissionByRole[id] = fields.roles
+			changed: (id, fields) =>
+				@permissionByRole[id] = fields.roles
+			removed: (id) =>
+				delete @permissionByRole[id]
diff --git a/packages/rocketchat-authorization/client/views/permissions.html b/packages/rocketchat-authorization/client/views/permissions.html
index f95b309f24a35ed785388c21c8971469c6462fa3..c895fea4c2de67b038350d2e55c73b41b3e1c2b8 100644
--- a/packages/rocketchat-authorization/client/views/permissions.html
+++ b/packages/rocketchat-authorization/client/views/permissions.html
@@ -9,8 +9,8 @@
 						<td>&nbsp;</td>
 						{{#each role}}
 							<td title="{{description}}">
-								<a href="{{pathFor "admin-permissions-edit" name=name}}">
-									{{name}}
+								<a href="{{pathFor "admin-permissions-edit" name=_id}}">
+									{{_id}}
 									<i class="icon-edit"></i>
 								</a>
 							</td>
@@ -23,7 +23,7 @@
 							<td>{{_id}}</td>
 							{{#each role}}
 								<td>
-									<input type="checkbox" name="perm[{{_id}}][{{../_id}}]" class="role-permission" value="1" checked="{{granted ../roles ../_id}}" data-role="{{name}}" data-permission="{{../_id}}">
+									<input type="checkbox" name="perm[{{_id}}][{{../_id}}]" class="role-permission" value="1" checked="{{granted ../roles}}" data-role="{{_id}}" data-permission="{{../_id}}">
 								</td>
 							{{/each}}
 						</tr>
diff --git a/packages/rocketchat-authorization/client/views/permissionsRole.coffee b/packages/rocketchat-authorization/client/views/permissionsRole.coffee
index bb754ced89c9a40911c5882ca11318aa6b5dbda2..739fa26afada48c8d0a1c6b219db572a6e36e3ba 100644
--- a/packages/rocketchat-authorization/client/views/permissionsRole.coffee
+++ b/packages/rocketchat-authorization/client/views/permissionsRole.coffee
@@ -1,6 +1,6 @@
 Template.permissionsRole.helpers
 	role: ->
-		return Meteor.roles.findOne({ name: FlowRouter.getParam('name') }) or {}
+		return RocketChat.models.Roles.findOne({ _id: FlowRouter.getParam('name') }) or {}
 
 	userInRole: ->
 		return Template.instance().usersInRole
@@ -108,4 +108,4 @@ Template.permissionsRole.onCreated ->
 	@subscribe 'roles', FlowRouter.getParam('name')
 	@subscribe 'usersInRole', FlowRouter.getParam('name')
 
-	@usersInRole = Roles.getUsersInRole(FlowRouter.getParam('name'), Roles.GLOBAL_GROUP, { sort: { username: 1 } })
+	@usersInRole = RocketChat.models.Roles.findUsersInRole(FlowRouter.getParam('name'), null, { sort: { username: 1 } })
diff --git a/packages/rocketchat-authorization/client/views/permissionsRole.html b/packages/rocketchat-authorization/client/views/permissionsRole.html
index a824390e886680a18e37f6fc3df8c3021b91c77f..18382fdb3c6a805a096fbfc4c7eec6e780c0b20c 100644
--- a/packages/rocketchat-authorization/client/views/permissionsRole.html
+++ b/packages/rocketchat-authorization/client/views/permissionsRole.html
@@ -7,7 +7,7 @@
 				<form id="form-role" class="inline form-role">
 					<label>{{_ "Role"}} :</label>
 						{{#if editing}}
-							<span>{{name}}</span>
+							<span>{{_id}}</span>
 						{{else}}
 							<input type="text" name="name" value="">
 						{{/if}}
diff --git a/packages/rocketchat-authorization/i18n/ar.i18n.json b/packages/rocketchat-authorization/i18n/ar.i18n.json
index 6983bb7d0fe6b96f79c382ca414d36096ea9fa28..2c88e2e3004ffb2d106dce330f6ca296ec6c380e 100644
--- a/packages/rocketchat-authorization/i18n/ar.i18n.json
+++ b/packages/rocketchat-authorization/i18n/ar.i18n.json
@@ -1,6 +1,9 @@
 {
   "Add_user" : "إضافة مستخدم",
-  "Save" : "حفظ",
+  "Back_to_permissions" : "العودة إلى التصريحات",
+  "Permissions" : "التصريحات",
+  "Saving" : "جاري الحفظ",
   "User_added" : "وأضاف العضو <em>__user_added__</em>.",
-  "User_removed" : "ازيل المستخدم"
+  "User_not_found" : "لم يتم العثور على المستخدم",
+  "User_removed" : "تم إزالة المستخدم"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/cs.i18n.json b/packages/rocketchat-authorization/i18n/cs.i18n.json
index 84eb3ce32fd3bf86f83bacec57592ef2c02834a6..6f31cf5a2e622e523ae008338072897b8e56c993 100644
--- a/packages/rocketchat-authorization/i18n/cs.i18n.json
+++ b/packages/rocketchat-authorization/i18n/cs.i18n.json
@@ -1,3 +1 @@
-{
-  "Save" : "Uložit"
-}
\ No newline at end of file
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/de.i18n.json b/packages/rocketchat-authorization/i18n/de.i18n.json
index e13943efa3ec9db703c2ce789ae03adfde2ee8ee..18f0ee3d48151fad65d81b01595626e11459bd2e 100644
--- a/packages/rocketchat-authorization/i18n/de.i18n.json
+++ b/packages/rocketchat-authorization/i18n/de.i18n.json
@@ -1,4 +1,17 @@
 {
-  "Save" : "Speichern",
-  "User_added" : "Benutzer <em>__user_added__</em> wurde hinzugefügt."
+  "Add_user" : "Benutzer hinzufügen",
+  "Back_to_permissions" : "Zurück zu den Berechtigungen",
+  "Cannot_delete_a_protected_role" : "Eine geschützte Rolle kann nicht gelöscht werden.",
+  "Cannot_delete_role_because_its_in_use" : "Die Rolle kann nicht gelöscht werden, da sie gerade verwendet wird.",
+  "New_role" : "Neue Rolle",
+  "Permissions" : "Berechtigungen",
+  "Role" : "Rolle",
+  "Role_Editing" : "Rolle bearbeiten",
+  "Role_removed" : "Die Rolle wurde entfernt.",
+  "Saving" : "Speichern",
+  "There_are_no_users_in_this_role" : "Es sind dieser Rolle keine Benutzer zugeordnet.",
+  "User_added" : "Der Benutzer <em>__user_added__</em> wurde hinzugefügt.",
+  "User_not_found" : "Der Benutzer konnte nicht gefunden werden.",
+  "User_removed" : "Der Benutzer wurde gelöscht.",
+  "Users_in_role" : "Zugeordnete Nutzer"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/el.i18n.json b/packages/rocketchat-authorization/i18n/el.i18n.json
index c0b916f189e931069994ed8e3ff4a6b2747c1591..8743d1a9706733366823026e3578d4aa5f18ccbe 100644
--- a/packages/rocketchat-authorization/i18n/el.i18n.json
+++ b/packages/rocketchat-authorization/i18n/el.i18n.json
@@ -1,4 +1,3 @@
 {
-  "Save" : "Αποθήκευση",
   "User_added" : "Ο χρήστης <em>__user_added__</em> πρστέθηκε."
 }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/en.i18n.json b/packages/rocketchat-authorization/i18n/en.i18n.json
index 46367ea01760d684267a330592b5e7a5db6562be..1a2b7b7080a40e46b23aa9d96d3140d2253082bf 100644
--- a/packages/rocketchat-authorization/i18n/en.i18n.json
+++ b/packages/rocketchat-authorization/i18n/en.i18n.json
@@ -5,11 +5,9 @@
   "Cannot_delete_role_because_its_in_use" : "Cannot delete role because it's in use",
   "New_role" : "New role",
   "Permissions" : "Permissions",
-  "Removed" : "Removed",
   "Role" : "Role",
   "Role_Editing" : "Role Editing",
   "Role_removed" : "Role removed",
-  "Save" : "Save",
   "Saving" : "Saving",
   "There_are_no_users_in_this_role" : "There are no users in this role.",
   "User_added" : "User added",
diff --git a/packages/rocketchat-authorization/i18n/es.i18n.json b/packages/rocketchat-authorization/i18n/es.i18n.json
index 9ace70c0a3c24d88767a4a4db23afc81d4456558..1c2eaf558856daec42aeeab8da7ed71cb31b1bd6 100644
--- a/packages/rocketchat-authorization/i18n/es.i18n.json
+++ b/packages/rocketchat-authorization/i18n/es.i18n.json
@@ -1,4 +1,3 @@
 {
-  "Save" : "Guardar",
   "User_added" : "Usuario <em>__user_added__</em> añadido."
 }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/fi.i18n.json b/packages/rocketchat-authorization/i18n/fi.i18n.json
index 041ed788cf19116c74c25ac5ed863e2063c915be..989d23b26efa529528cade8803c79e5dd2ea6ff4 100644
--- a/packages/rocketchat-authorization/i18n/fi.i18n.json
+++ b/packages/rocketchat-authorization/i18n/fi.i18n.json
@@ -5,11 +5,9 @@
   "Cannot_delete_role_because_its_in_use" : "Et voi poistaa roolia, koska se on käytössä",
   "New_role" : "Uusi rooli",
   "Permissions" : "Oikeudet",
-  "Removed" : "Poistettu",
   "Role" : "Rooli",
   "Role_Editing" : "Roolin muokkaaminen",
   "Role_removed" : "Rooli poistettu",
-  "Save" : "Tallenna",
   "Saving" : "Tallennetaan",
   "There_are_no_users_in_this_role" : "Roolissa ei ole käyttäjiä",
   "User_added" : "Käyttäjä <em>__user_added__</em> lisätty.",
diff --git a/packages/rocketchat-authorization/i18n/fr.i18n.json b/packages/rocketchat-authorization/i18n/fr.i18n.json
index ee7fabae8a33b2c7f4d2d4ce4f64acb0a99ae003..adcc0c34d11babd5196f78dcf70d8c8432d65792 100644
--- a/packages/rocketchat-authorization/i18n/fr.i18n.json
+++ b/packages/rocketchat-authorization/i18n/fr.i18n.json
@@ -1,4 +1,3 @@
 {
-  "Save" : "Enregistrer",
   "User_added" : "L'utilisateur <em>__user_added__</em> a été ajouté."
 }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/he.i18n.json b/packages/rocketchat-authorization/i18n/he.i18n.json
index ed313b293643423fffd0a9707c0ea69f31b30c77..e8843caf9e5cedb512349c220bd3437c2a8fe8a5 100644
--- a/packages/rocketchat-authorization/i18n/he.i18n.json
+++ b/packages/rocketchat-authorization/i18n/he.i18n.json
@@ -1,4 +1,16 @@
 {
-  "Save" : "שמור",
-  "User_added" : "המשתמש <em>__user_added__</em> נוסף."
+  "Add_user" : "הוספת משתמש",
+  "Back_to_permissions" : "חזרה להרשאות",
+  "Cannot_delete_a_protected_role" : "לא ניתן למחוק תפקיד מוגן.",
+  "New_role" : "תפקיד חדש",
+  "Permissions" : "הרשאות",
+  "Role" : "תפקיד",
+  "Role_Editing" : "עריכת תפקידים",
+  "Role_removed" : "התפקיד הוסר",
+  "Saving" : "בשמירה",
+  "There_are_no_users_in_this_role" : "אין משתמשים בתפקיד זה.",
+  "User_added" : "המשתמש נוסף.",
+  "User_not_found" : "המשתמש לא נמצא",
+  "User_removed" : "המשתמש הוסר",
+  "Users_in_role" : "משתמשים בתפקיד"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/hr.i18n.json b/packages/rocketchat-authorization/i18n/hr.i18n.json
index 6b72824ca23dddd03050c4809b61a3e9f91ba347..4bf37f94d0c0c95b23a2bffc5d4cf9be52f329f4 100644
--- a/packages/rocketchat-authorization/i18n/hr.i18n.json
+++ b/packages/rocketchat-authorization/i18n/hr.i18n.json
@@ -1,4 +1,12 @@
 {
-  "Save" : "Sačuvaj",
-  "User_added" : "Korisnik <em>__user_added__</em> je dodan."
+  "Add_user" : "Dodaj korisnika",
+  "Back_to_permissions" : "Povratak na dozvole",
+  "Permissions" : "Dopuštenja",
+  "Role" : "Uloga",
+  "Saving" : "Spremanje",
+  "There_are_no_users_in_this_role" : "Nema korisnika u toj ulozi.",
+  "User_added" : "Korisnik <em>__user_added__</em> je dodan.",
+  "User_not_found" : "Korisnik nije pronađen",
+  "User_removed" : "Korisnik je uklonjen",
+  "Users_in_role" : "Korisnici u ulozi"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/hu.i18n.json b/packages/rocketchat-authorization/i18n/hu.i18n.json
index 9f88a36530aa4e058b431eae3d2f153539d5e016..cd097103a5a5d7ecbd442a46666a61c022d02752 100644
--- a/packages/rocketchat-authorization/i18n/hu.i18n.json
+++ b/packages/rocketchat-authorization/i18n/hu.i18n.json
@@ -1,4 +1,3 @@
 {
-  "Save" : "Mentés",
   "User_added" : "<em>__user_added__</em> hozzáadva."
 }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/it.i18n.json b/packages/rocketchat-authorization/i18n/it.i18n.json
index 73b11372f508b416d763bb1d488d65eb0295e3f6..d95b3cf085c7e2dd2059a1240b7ffbd789ee2d1f 100644
--- a/packages/rocketchat-authorization/i18n/it.i18n.json
+++ b/packages/rocketchat-authorization/i18n/it.i18n.json
@@ -1,4 +1,3 @@
 {
-  "Save" : "Salva",
   "User_added" : "Utente <em>__user_added__</em> aggiunto."
 }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/ja.i18n.json b/packages/rocketchat-authorization/i18n/ja.i18n.json
index 846240cce4b7e32e8acb22f221141c4bd68fe83f..63994876ab03cf777c34854ae723c4bd1710302f 100644
--- a/packages/rocketchat-authorization/i18n/ja.i18n.json
+++ b/packages/rocketchat-authorization/i18n/ja.i18n.json
@@ -1,4 +1,3 @@
 {
-  "Save" : "保存",
   "User_added" : "ユーザ <em>%s</em> 追加しました。"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/km.i18n.json b/packages/rocketchat-authorization/i18n/km.i18n.json
index d3ce4c6f879897f08abb7b90eb81c4fdfb1bee4e..f252b47a08b7e90c65acbd805fa368227ca1d422 100644
--- a/packages/rocketchat-authorization/i18n/km.i18n.json
+++ b/packages/rocketchat-authorization/i18n/km.i18n.json
@@ -1,4 +1,3 @@
 {
-  "Save" : "រក្សាទុក",
   "User_added" : "អ្នក​ប្រើ <em>__user_added__</em> បាន​បន្ថែម"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/ko.i18n.json b/packages/rocketchat-authorization/i18n/ko.i18n.json
index a7ed67a8ddfe3ca48e3f757a65b0ea272c63845d..d55848ec9451d7fd6f8aa6ad566c78fa6ddde8c1 100644
--- a/packages/rocketchat-authorization/i18n/ko.i18n.json
+++ b/packages/rocketchat-authorization/i18n/ko.i18n.json
@@ -1,4 +1,9 @@
 {
-  "Save" : "저장",
-  "User_added" : "사용자 <em>__user_added__</em> 추가함."
+  "Add_user" : "사용자 추가",
+  "New_role" : "새로운 역할",
+  "Permissions" : "권한",
+  "Saving" : "저장 중",
+  "User_added" : "사용자 추가함.",
+  "User_not_found" : "사용자를 찾을 수 없음",
+  "User_removed" : "사용자 제거됨"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/ku.i18n.json b/packages/rocketchat-authorization/i18n/ku.i18n.json
index 1e7dd6a08761b8632da8fa06be4dceeeb7d76f97..1b1b8096a8ed607d0917f6bdbe2b5866802b9c8d 100644
--- a/packages/rocketchat-authorization/i18n/ku.i18n.json
+++ b/packages/rocketchat-authorization/i18n/ku.i18n.json
@@ -1,4 +1,3 @@
 {
-  "Save" : "پاشەکەوت",
   "User_added" : "بەکارهێنەر زیادکرا"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/ms-MY.i18n.json b/packages/rocketchat-authorization/i18n/ms-MY.i18n.json
index 07811f70be04c1889430ed918fe26cb187b5ecec..e34b443be0e01d2f39f5a0e8784204d572d458c9 100644
--- a/packages/rocketchat-authorization/i18n/ms-MY.i18n.json
+++ b/packages/rocketchat-authorization/i18n/ms-MY.i18n.json
@@ -1,4 +1,3 @@
 {
-  "Save" : "Simpan",
   "User_added" : "Pengguna <em>__user_added__</em> ditambah."
 }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/nl.i18n.json b/packages/rocketchat-authorization/i18n/nl.i18n.json
index 039425c06c54f54afa4372f2df33ec3a7603a134..5b85b6b098437eef4f38719c42424a55ee658f13 100644
--- a/packages/rocketchat-authorization/i18n/nl.i18n.json
+++ b/packages/rocketchat-authorization/i18n/nl.i18n.json
@@ -1,4 +1,17 @@
 {
-  "Save" : "Bewaren",
-  "User_added" : "Gebruiker toegevoegd"
+  "Add_user" : "Gebruikers toevoegen",
+  "Back_to_permissions" : "Terug naar machtigingen",
+  "Cannot_delete_a_protected_role" : "Kan een beschermde rol niet verwijderen",
+  "Cannot_delete_role_because_its_in_use" : "Kan rol niet verwijderen omdat het in gebruik is",
+  "New_role" : "Nieuwe rol",
+  "Permissions" : "Machtigingen",
+  "Role" : "Rol",
+  "Role_Editing" : "Rol bewerken",
+  "Role_removed" : "Rol verwijderd",
+  "Saving" : "Opslaan",
+  "There_are_no_users_in_this_role" : "Er zijn geen gebruikers met deze rol.",
+  "User_added" : "Gebruiker toegevoegd",
+  "User_not_found" : "Gebruiker niet gevonden",
+  "User_removed" : "Gebruiker verwijderd",
+  "Users_in_role" : "Gebruikers met rol"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/pl.i18n.json b/packages/rocketchat-authorization/i18n/pl.i18n.json
index 14ea715b8ec344eb2c36abfbe1308d98e0163d6b..a022338c789a63ed9cac7a61b4387c206c0c906e 100644
--- a/packages/rocketchat-authorization/i18n/pl.i18n.json
+++ b/packages/rocketchat-authorization/i18n/pl.i18n.json
@@ -1,4 +1,14 @@
 {
-  "Save" : "Zapisz",
-  "User_added" : "Użytkownik <em>__user_added__</em> dodany."
+  "Add_user" : "Dodaj użytkownika",
+  "Back_to_permissions" : "Powrót do uprawnień",
+  "New_role" : "Nowa rola",
+  "Permissions" : "Uprawnienia",
+  "Role" : "Rola",
+  "Role_Editing" : "Edycja ról",
+  "Role_removed" : "Rola usunięta",
+  "Saving" : "Zapisywanie",
+  "There_are_no_users_in_this_role" : "Ta rola nie ma przypisanych użytkowników.",
+  "User_added" : "Użytkownik <em>__user_added__</em> dodany.",
+  "User_not_found" : "Użytkownik nie znaleziony",
+  "User_removed" : "Użytkownik usunięty"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/pt.i18n.json b/packages/rocketchat-authorization/i18n/pt.i18n.json
index 8664e27746f77f8e8839dc0f90f657faa55874e0..b0bb242a6c7940a34c9e1248426cce8ee73f9f11 100644
--- a/packages/rocketchat-authorization/i18n/pt.i18n.json
+++ b/packages/rocketchat-authorization/i18n/pt.i18n.json
@@ -5,11 +5,9 @@
   "Cannot_delete_role_because_its_in_use" : "Não é possível remover o papel pois ele está em uso",
   "New_role" : "Novo papel",
   "Permissions" : "Permissões",
-  "Removed" : "Removido",
   "Role" : "Papel",
   "Role_Editing" : "Edição de Papel",
   "Role_removed" : "Papel Removido",
-  "Save" : "Salvar",
   "Saving" : "Salvando",
   "There_are_no_users_in_this_role" : "Não há usuários neste papel.",
   "User_added" : "Usuário adicionado",
diff --git a/packages/rocketchat-authorization/i18n/ro.i18n.json b/packages/rocketchat-authorization/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..30f9bb1036b9134561dc413fdc4bc710893fff14
--- /dev/null
+++ b/packages/rocketchat-authorization/i18n/ro.i18n.json
@@ -0,0 +1,17 @@
+{
+  "Add_user" : "Adaugă utilizator",
+  "Back_to_permissions" : "ÃŽnapoi la permisiuni",
+  "Cannot_delete_a_protected_role" : "Nu se poate șterge un rol protejat",
+  "Cannot_delete_role_because_its_in_use" : "Nu se poate șterge rol, deoarece este în uz",
+  "New_role" : "Rol nou",
+  "Permissions" : "Permisiuni",
+  "Role" : "Rol",
+  "Role_Editing" : "Editare rol",
+  "Role_removed" : "Rol eliminat",
+  "Saving" : "Salvare...",
+  "There_are_no_users_in_this_role" : "Nu există utilizatori în acest rol.",
+  "User_added" : "Utilizator adăugat",
+  "User_not_found" : "Utilizatorul nu a fost găsit",
+  "User_removed" : "Utilizator eliminat",
+  "Users_in_role" : "Utilizatorii în rol"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/ru.i18n.json b/packages/rocketchat-authorization/i18n/ru.i18n.json
index a1e844169a3c83204f292adf5b73e6f0e95700fa..60691f938cd8b5d987939b8a11063ac222961448 100644
--- a/packages/rocketchat-authorization/i18n/ru.i18n.json
+++ b/packages/rocketchat-authorization/i18n/ru.i18n.json
@@ -1,4 +1,6 @@
 {
-  "Save" : "Сохранить",
-  "User_added" : "Пользователь <em>__user_added__</em> добавлен."
+  "Back_to_permissions" : "Назад к настройкам прав",
+  "Permissions" : "Настройка прав",
+  "User_added" : "Пользователь <em>__user_added__</em> добавлен.",
+  "Users_in_role" : "Пользователи с ролью"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/sq.i18n.json b/packages/rocketchat-authorization/i18n/sq.i18n.json
index b01a59cc8c1c69ffbcff4e8cc7847288eac34f22..6f31cf5a2e622e523ae008338072897b8e56c993 100644
--- a/packages/rocketchat-authorization/i18n/sq.i18n.json
+++ b/packages/rocketchat-authorization/i18n/sq.i18n.json
@@ -1,3 +1 @@
-{
-  "Save" : "Ruaj"
-}
\ No newline at end of file
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/sr.i18n.json b/packages/rocketchat-authorization/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..e50b8a1469c67ec05d1aae09406761858e436fd7
--- /dev/null
+++ b/packages/rocketchat-authorization/i18n/sr.i18n.json
@@ -0,0 +1,3 @@
+{
+  "User_added" : "Корисник/ца додат(а)"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/sv.i18n.json b/packages/rocketchat-authorization/i18n/sv.i18n.json
index 7bc9d5f5301627b9b75bf2caa789874a33ed6ec6..6f31cf5a2e622e523ae008338072897b8e56c993 100644
--- a/packages/rocketchat-authorization/i18n/sv.i18n.json
+++ b/packages/rocketchat-authorization/i18n/sv.i18n.json
@@ -1,3 +1 @@
-{
-  "Save" : "Spara"
-}
\ No newline at end of file
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/ta-IN.i18n.json b/packages/rocketchat-authorization/i18n/ta-IN.i18n.json
index 24a652c5f05464348f2d514454ff580d9cbe18c8..6feacff35ebcd68a7eff867c68e3fc6d4fc4069f 100644
--- a/packages/rocketchat-authorization/i18n/ta-IN.i18n.json
+++ b/packages/rocketchat-authorization/i18n/ta-IN.i18n.json
@@ -1,4 +1,3 @@
 {
-  "Save" : "சேமி",
   "User_added" : "பயனர் <em>__user_added__</em>சேர்க்கப்பட்டார்."
 }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/tr.i18n.json b/packages/rocketchat-authorization/i18n/tr.i18n.json
index 87c7ba45b61ec480889819f621606f03d370a515..c8fe5872ecd52eda415482f7e4ce815b7f645965 100644
--- a/packages/rocketchat-authorization/i18n/tr.i18n.json
+++ b/packages/rocketchat-authorization/i18n/tr.i18n.json
@@ -1,4 +1,3 @@
 {
-  "Save" : "Kaydet",
   "User_added" : "<em>__user_added__</em> eklendi."
 }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/ug.i18n.json b/packages/rocketchat-authorization/i18n/ug.i18n.json
index 64384b7a94a0c1c27eac392feabd7dff4b0ffe99..e2d8791b127d5760237c1c95288369ee92339bf1 100644
--- a/packages/rocketchat-authorization/i18n/ug.i18n.json
+++ b/packages/rocketchat-authorization/i18n/ug.i18n.json
@@ -1,4 +1,3 @@
 {
-  "Save" : "ساقلاش",
   "User_added" : "<em>__user_added__</em> ئەزا قوشۇلدى."
 }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/uk.i18n.json b/packages/rocketchat-authorization/i18n/uk.i18n.json
index c1ac4e32dd601f0d27952ea909d8688f3de22a7b..0bfea7a4c0c90967bc4a888146ee10bdf8eeeb0f 100644
--- a/packages/rocketchat-authorization/i18n/uk.i18n.json
+++ b/packages/rocketchat-authorization/i18n/uk.i18n.json
@@ -1,4 +1,3 @@
 {
-  "Save" : "Зберегти",
   "User_added" : "Користувач <em>__user_added__</em> доданий."
 }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/i18n/zh.i18n.json b/packages/rocketchat-authorization/i18n/zh.i18n.json
index 5b7a5b62c1e6572b97337da89338e7bf6fc3a12e..0504f9957b455f5b4e0dec9f11f06ebc21028402 100644
--- a/packages/rocketchat-authorization/i18n/zh.i18n.json
+++ b/packages/rocketchat-authorization/i18n/zh.i18n.json
@@ -1,4 +1,3 @@
 {
-  "Save" : "保存",
   "User_added" : "已添加用户 <em>__user_added__</em> 。"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/package.js b/packages/rocketchat-authorization/package.js
index 90a13112d928751706bd7e62d8e7cc3cfacdb660..69682e47db333201648a31e4c0ff64e69936b27d 100644
--- a/packages/rocketchat-authorization/package.js
+++ b/packages/rocketchat-authorization/package.js
@@ -11,18 +11,22 @@ Package.onUse(function(api) {
   api.use([
     'coffeescript',
     'underscore',
-    'rocketchat:lib@0.0.1',
-    'alanning:roles@1.2.12'
+    'rocketchat:lib'
     ]);
 
-  api.use('mongo', 'client');
+  api.use('mongo', ['client', 'server']);
   api.use('kadira:flow-router', 'client');
   api.use('less@2.5.1', 'client');
+  api.use('tracker', 'client');
 
   api.use('templating', 'client');
 
   api.addFiles('lib/rocketchat.coffee', ['server','client']);
-  api.addFiles('client/collection.coffee', ['client']);
+  api.addFiles('client/lib/ChatPermissions.coffee', ['client']);
+  api.addFiles('client/lib/models/Roles.coffee', ['client']);
+  api.addFiles('client/lib/models/Users.js', ['client']);
+  api.addFiles('client/lib/models/Subscriptions.js', ['client']);
+
   api.addFiles('client/startup.coffee', ['client']);
   api.addFiles('client/hasPermission.coffee', ['client']);
   api.addFiles('client/hasRole.coffee', ['client']);
@@ -39,19 +43,22 @@ Package.onUse(function(api) {
   api.addFiles('client/stylesheets/permissions.less', 'client');
 
   api.addFiles('server/models/Permissions.coffee', ['server']);
+  api.addFiles('server/models/Roles.coffee', ['server']);
+  api.addFiles('server/models/Base.js', ['server']);
+  api.addFiles('server/models/Users.js', ['server']);
+  api.addFiles('server/models/Subscriptions.js', ['server']);
 
-  api.addFiles('server/functions/addUsersToRoles.coffee', ['server']);
-  api.addFiles('server/functions/getPermissionsForRole.coffee', ['server']);
+  api.addFiles('server/functions/addUserRoles.coffee', ['server']);
   api.addFiles('server/functions/getRoles.coffee', ['server']);
-  api.addFiles('server/functions/getRolesForUser.coffee', ['server']);
   api.addFiles('server/functions/getUsersInRole.coffee', ['server']);
   api.addFiles('server/functions/hasPermission.coffee', ['server']);
   api.addFiles('server/functions/hasRole.coffee', ['server']);
-  api.addFiles('server/functions/removeUsersFromRoles.coffee', ['server']);
+  api.addFiles('server/functions/removeUserFromRoles.coffee', ['server']);
 
   // publications
-  api.addFiles('server/publication.coffee', ['server']);
+  api.addFiles('server/publications/permissions.js', 'server');
   api.addFiles('server/publications/roles.coffee', 'server');
+  api.addFiles('server/publications/scopedRoles.js', 'server');
   api.addFiles('server/publications/usersInRole.coffee', 'server');
 
   // methods
@@ -71,6 +78,6 @@ Package.onUse(function(api) {
       return 'i18n/' + filename;
     }
   }));
-  api.use('tap:i18n', ['client', 'server']);
-  api.addFiles(tapi18nFiles, ['client', 'server']);
+  api.use('tap:i18n');
+  api.addFiles(tapi18nFiles);
 });
diff --git a/packages/rocketchat-authorization/server/functions/addUserRoles.coffee b/packages/rocketchat-authorization/server/functions/addUserRoles.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..c715153ce326174249ddba7290f2051551558997
--- /dev/null
+++ b/packages/rocketchat-authorization/server/functions/addUserRoles.coffee
@@ -0,0 +1,19 @@
+RocketChat.authz.addUserRoles = (userId, roleNames, scope) ->
+	if not userId or not roleNames
+		return false
+
+	user = RocketChat.models.Users.findOneById(userId)
+	if not user
+		throw new Meteor.Error 'invalid-user'
+
+	roleNames = [].concat roleNames
+
+	existingRoleNames = _.pluck(RocketChat.authz.getRoles(), '_id')
+	invalidRoleNames = _.difference(roleNames, existingRoleNames)
+	unless _.isEmpty(invalidRoleNames)
+		for role in invalidRoleNames
+			RocketChat.models.Roles.createOrUpdate role
+
+	RocketChat.models.Roles.addUserRoles(userId, roleNames, scope)
+
+	return true
diff --git a/packages/rocketchat-authorization/server/functions/addUsersToRoles.coffee b/packages/rocketchat-authorization/server/functions/addUsersToRoles.coffee
deleted file mode 100644
index 3af878e6814adf10ef689e91cabe3eb8508bb1c3..0000000000000000000000000000000000000000
--- a/packages/rocketchat-authorization/server/functions/addUsersToRoles.coffee
+++ /dev/null
@@ -1,28 +0,0 @@
-RocketChat.authz.addUsersToRoles = (userIds, roleNames, scope ) ->
-	console.log '[methods] addUserToRoles -> '.green, 'arguments:', arguments
-	if not userIds or not roleNames
-		return false
-
-	unless _.isArray(userIds)
-		userIds = [userIds]
-
-	users = Meteor.users.find({_id: {$in : userIds}}).fetch()
-	unless userIds.length is users.length
-		throw new Meteor.Error 'invalid-user'
-
-	unless _.isArray(roleNames)
-		roleNames = [roleNames]
-
-	existingRoleNames = _.pluck(RocketChat.authz.getRoles().fetch(), 'name')
-	invalidRoleNames = _.difference( roleNames, existingRoleNames)
-	unless _.isEmpty(invalidRoleNames)
-		# throw new Meteor.Error 'invalid-role'
-		for role in invalidRoleNames
-			Roles.createRole role
-
-	unless _.isString(scope)
-		scope = Roles.GLOBAL_GROUP
-
-	Roles.addUsersToRoles( userIds, roleNames, scope)
-
-	return true
diff --git a/packages/rocketchat-authorization/server/functions/getPermissionsForRole.coffee b/packages/rocketchat-authorization/server/functions/getPermissionsForRole.coffee
deleted file mode 100644
index 7023d120265bdf8e1e41d5062538f4ae116d90ea..0000000000000000000000000000000000000000
--- a/packages/rocketchat-authorization/server/functions/getPermissionsForRole.coffee
+++ /dev/null
@@ -1,9 +0,0 @@
-RocketChat.authz.getPermissionsForRole = (roleName) ->
-	unless roleName
-		throw new Meteor.Error 'invalid-role'
-
-	roleNames = _.pluck(RocketChat.authz.getRoles().fetch(), 'name')
-	unless roleName in roleNames
-		throw new Meteor.Error 'invalid-role', "Role #{roleName} not found"
-
-	return _.pluck(RocketChat.models.Permissions.findByRole( roleName ).fetch(), '_id')
diff --git a/packages/rocketchat-authorization/server/functions/getRoles.coffee b/packages/rocketchat-authorization/server/functions/getRoles.coffee
index 37c3d2537fdb438dcc9afc654e5eb1d941ef69af..895dcc532c1913c7fdb53e8800c8d079ecc4f8e8 100644
--- a/packages/rocketchat-authorization/server/functions/getRoles.coffee
+++ b/packages/rocketchat-authorization/server/functions/getRoles.coffee
@@ -1,2 +1,2 @@
 RocketChat.authz.getRoles = ->
-	return Roles.getAllRoles()
\ No newline at end of file
+	return RocketChat.models.Roles.find().fetch()
diff --git a/packages/rocketchat-authorization/server/functions/getRolesForUser.coffee b/packages/rocketchat-authorization/server/functions/getRolesForUser.coffee
deleted file mode 100644
index 40f8564a28eaf39aa1bc64178b7e0be4fa02b1cd..0000000000000000000000000000000000000000
--- a/packages/rocketchat-authorization/server/functions/getRolesForUser.coffee
+++ /dev/null
@@ -1,7 +0,0 @@
-RocketChat.authz.getRolesForUser = (userId, scope) ->
-	console.log '[methods] getRolesForUser -> '.green, 'arguments:', arguments
-	# returns roles for the given scope as well as the global scope
-	unless scope
-		scope = Roles.GLOBAL_GROUP
-
-	return Roles.getRolesForUser(userId, scope) 
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/server/functions/getUsersInRole.coffee b/packages/rocketchat-authorization/server/functions/getUsersInRole.coffee
index ee416c3e90255a1dddb77cb42ec78b055676126e..b8fc11a51fbae3c0462bab59d41e59392782e547 100644
--- a/packages/rocketchat-authorization/server/functions/getUsersInRole.coffee
+++ b/packages/rocketchat-authorization/server/functions/getUsersInRole.coffee
@@ -1,6 +1,2 @@
 RocketChat.authz.getUsersInRole = (roleName, scope, options) ->
-	# alanning:roles doc says this is an expensive operation
-	unless _.isString(scope)
-		scope = Roles.GLOBAL_GROUP
-
-	return Roles.getUsersInRole(roleName, scope, options)
+	return RocketChat.models.Roles.findUsersInRole(roleName, scope, options)
diff --git a/packages/rocketchat-authorization/server/functions/hasPermission.coffee b/packages/rocketchat-authorization/server/functions/hasPermission.coffee
index f0d2d3ca2e92327ddd41a49cf760d4a3806f9a56..7ae014453d0e994254bfa534be5054163f970e60 100644
--- a/packages/rocketchat-authorization/server/functions/hasPermission.coffee
+++ b/packages/rocketchat-authorization/server/functions/hasPermission.coffee
@@ -1,12 +1,3 @@
 RocketChat.authz.hasPermission = (userId, permissionId, scope) ->
-	console.log '[methods] hasPermission -> '.green, 'arguments:', arguments
-
-	# get user's roles
-	roles = RocketChat.authz.getRolesForUser(userId, scope)
-
-	# get permissions for user's roles
-	permissions = []
-	for role in roles
-		permissions = permissions.concat( RocketChat.authz.getPermissionsForRole( role ))
-	# may contain duplicate, but doesn't matter
-	return permissionId in permissions
\ No newline at end of file
+	permission = RocketChat.models.Permissions.findOne permissionId
+	return RocketChat.models.Roles.isUserInRoles(userId, permission.roles, scope)
diff --git a/packages/rocketchat-authorization/server/functions/hasRole.coffee b/packages/rocketchat-authorization/server/functions/hasRole.coffee
index 83d32ea862a3000591167a5cefe5f1d1bcaf198c..aff335e48b2fd0f7ae37fce3f2d00bb98796124c 100644
--- a/packages/rocketchat-authorization/server/functions/hasRole.coffee
+++ b/packages/rocketchat-authorization/server/functions/hasRole.coffee
@@ -1,4 +1,3 @@
-RocketChat.authz.hasRole = (userId, roleName, scope) ->
-	console.log '[methods] hasRoles -> '.green, 'arguments:', arguments
-	# per alanning:roles, returns true if user is in ANY roles
-	return Roles.userIsInRole(userId, [roleName], scope)
\ No newline at end of file
+RocketChat.authz.hasRole = (userId, roleNames, scope) ->
+	roleNames = [].concat roleNames
+	return RocketChat.models.Roles.isUserInRoles(userId, roleNames, scope) # true if user is in ANY role
diff --git a/packages/rocketchat-authorization/server/functions/removeUserFromRoles.coffee b/packages/rocketchat-authorization/server/functions/removeUserFromRoles.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..64df765f67fc7711960861e2f4b8543287b8afce
--- /dev/null
+++ b/packages/rocketchat-authorization/server/functions/removeUserFromRoles.coffee
@@ -0,0 +1,18 @@
+RocketChat.authz.removeUserFromRoles = (userId, roleNames, scope) ->
+	if not userId or not roleNames
+		return false
+
+	user = RocketChat.models.Users.findOneById(userId)
+	if not user?
+		throw new Meteor.Error 'invalid-user'
+
+	roleNames = [].concat roleNames
+
+	existingRoleNames = _.pluck(RocketChat.authz.getRoles(), 'name')
+	invalidRoleNames = _.difference(roleNames, existingRoleNames)
+	unless _.isEmpty(invalidRoleNames)
+		throw new Meteor.Error 'invalid-role'
+
+	RocketChat.models.Roles.removeUserRoles(userId, roleNames, scope)
+
+	return true
diff --git a/packages/rocketchat-authorization/server/functions/removeUsersFromRoles.coffee b/packages/rocketchat-authorization/server/functions/removeUsersFromRoles.coffee
deleted file mode 100644
index a3f7c794d898a711815f3488eafae4f30b135248..0000000000000000000000000000000000000000
--- a/packages/rocketchat-authorization/server/functions/removeUsersFromRoles.coffee
+++ /dev/null
@@ -1,26 +0,0 @@
-RocketChat.authz.removeUsersFromRoles = (userIds, roleNames, scope ) ->
-	console.log '[methods] removeUsersFromRoles -> '.green, 'arguments:', arguments
-	if not userIds or not roleNames
-		return false
-
-	unless _.isArray(userIds)
-		userIds = [userIds]
-
-	users = Meteor.users.find({_id: {$in : userIds}}).fetch()
-	unless userIds.length is users.length
-		throw new Meteor.Error 'invalid-user'
-
-	unless _.isArray(roleNames)
-		roleNames = [roleNames]
-
-	existingRoleNames = _.pluck(RocketChat.authz.getRoles().fetch(), 'name')
-	invalidRoleNames = _.difference( roleNames, existingRoleNames)
-	unless _.isEmpty(invalidRoleNames)
-		throw new Meteor.Error 'invalid-role'
-
-	unless _.isString(scope)
-		scope = Roles.GLOBAL_GROUP
-
-	Roles.removeUsersFromRoles( userIds, roleNames, scope)
-
-	return true
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/server/methods/addPermissionToRole.coffee b/packages/rocketchat-authorization/server/methods/addPermissionToRole.coffee
index a6d52621a7dbcdde74464f1f130a7f8518201ff3..6924414101c3ff901e644bc3f8d8a6160d8befb5 100644
--- a/packages/rocketchat-authorization/server/methods/addPermissionToRole.coffee
+++ b/packages/rocketchat-authorization/server/methods/addPermissionToRole.coffee
@@ -3,6 +3,4 @@ Meteor.methods
 		if not Meteor.userId() or not RocketChat.authz.hasPermission Meteor.userId(), 'access-permissions'
 			throw new Meteor.Error "not-authorized"
 
-		console.log '[methods] authorization:addPermissionToRole -> '.green, 'arguments:', arguments
-
 		RocketChat.models.Permissions.addRole permission, role
diff --git a/packages/rocketchat-authorization/server/methods/addUserToRole.coffee b/packages/rocketchat-authorization/server/methods/addUserToRole.coffee
index 98583682d75c41acd69d1ea279b6a6ffba1c63c6..74ba6bbea53017285a33b185a525663ef2bd96ba 100644
--- a/packages/rocketchat-authorization/server/methods/addUserToRole.coffee
+++ b/packages/rocketchat-authorization/server/methods/addUserToRole.coffee
@@ -1,17 +1,14 @@
 Meteor.methods
-	'authorization:addUserToRole': (roleName, username) ->
+	'authorization:addUserToRole': (roleName, username, scope) ->
 		if not Meteor.userId() or not RocketChat.authz.hasPermission Meteor.userId(), 'access-permissions'
 			throw new Meteor.Error "not-authorized"
 
-		console.log('[methods] authorization:addUserToRole -> '.green, 'arguments:', arguments);
-
 		if not roleName or not _.isString(roleName) or not username or not _.isString(username)
 			throw new Meteor.Error 'invalid-arguments'
 
-		user = Meteor.users.findOne { username: username }, { fields: { _id: 1 } }
+		user = RocketChat.models.Users.findOneByUsername username, { fields: { _id: 1 } }
 
 		if not user?._id?
 			throw new Meteor.Error 'user-not-found', 'User_not_found'
 
-		# return Roles.addUsersToRoles user._id, roleName
-		return Roles.addUsersToRoles user._id, roleName, Roles.GLOBAL_GROUP
+		return RocketChat.models.Roles.addUserRoles user._id, roleName, scope
diff --git a/packages/rocketchat-authorization/server/methods/deleteRole.coffee b/packages/rocketchat-authorization/server/methods/deleteRole.coffee
index ab6e554c11234c0bf6e5e1f8df51596e2a63aa65..39ca53a350289761cca1c9725c2ebe8d70cf6dd4 100644
--- a/packages/rocketchat-authorization/server/methods/deleteRole.coffee
+++ b/packages/rocketchat-authorization/server/methods/deleteRole.coffee
@@ -1,18 +1,19 @@
 Meteor.methods
-	'authorization:deleteRole': (_id) ->
+	'authorization:deleteRole': (roleName) ->
 		if not Meteor.userId() or not RocketChat.authz.hasPermission Meteor.userId(), 'access-permissions'
 			throw new Meteor.Error "not-authorized"
 
-		console.log '[methods] authorization:deleteRole -> '.green, 'arguments:', arguments
-
-		role = Meteor.roles.findOne _id
+		role = RocketChat.models.Roles.findOne roleName
+		if not role?
+			throw new Meteor.Error 'invalid-role'
 
 		if role.protected
 			throw new Meteor.Error 'protected-role', 'Cannot_delete_a_protected_role'
 
-		someone = Meteor.users.findOne { "roles.#{Roles.GLOBAL_GROUP}": role.name }
+		roleScope = role.scope or 'Users'
+		existingUsers = RocketChat.models[roleScope]?.findUsersInRoles?(roleName)
 
-		if someone?
+		if existingUsers?.count() > 0
 			throw new Meteor.Error 'role-in-use', 'Cannot_delete_role_because_its_in_use'
 
-		return Roles.deleteRole role.name
+		return RocketChat.models.Roles.remove role.name
diff --git a/packages/rocketchat-authorization/server/methods/removeRoleFromPermission.coffee b/packages/rocketchat-authorization/server/methods/removeRoleFromPermission.coffee
index 9efde6b9d17d8ce9f74f4aec942f0cb69e0d163c..ff5def0ad66c35f17b1f4c4a6df0598b159a9245 100644
--- a/packages/rocketchat-authorization/server/methods/removeRoleFromPermission.coffee
+++ b/packages/rocketchat-authorization/server/methods/removeRoleFromPermission.coffee
@@ -3,6 +3,4 @@ Meteor.methods
 		if not Meteor.userId() or not RocketChat.authz.hasPermission Meteor.userId(), 'access-permissions'
 			throw new Meteor.Error "not-authorized"
 
-		console.log '[methods] authorization:removeRoleFromPermission -> '.green, 'arguments:', arguments
-
 		RocketChat.models.Permissions.removeRole permission, role
diff --git a/packages/rocketchat-authorization/server/methods/removeUserFromRole.coffee b/packages/rocketchat-authorization/server/methods/removeUserFromRole.coffee
index 26d47a63b1a80ff61edfc2de22668c105c4f2881..26da340af6f32bfd70bab9179e3aebff25a58734 100644
--- a/packages/rocketchat-authorization/server/methods/removeUserFromRole.coffee
+++ b/packages/rocketchat-authorization/server/methods/removeUserFromRole.coffee
@@ -3,8 +3,6 @@ Meteor.methods
 		if not Meteor.userId() or not RocketChat.authz.hasPermission Meteor.userId(), 'access-permissions'
 			throw new Meteor.Error "not-authorized"
 
-		console.log('[methods] authorization:removeUserFromRole -> '.green, 'arguments:', arguments);
-
 		if not roleName or not _.isString(roleName) or not username or not _.isString(username)
 			throw new Meteor.Error 'invalid-arguments'
 
@@ -13,4 +11,4 @@ Meteor.methods
 		if not user?._id?
 			throw new Meteor.Error 'user-not-found'
 
-		return Roles.removeUsersFromRoles user._id, roleName, Roles.GLOBAL_GROUP
+		return RocketChat.models.Roles.removeUserRoles user._id, roleName
diff --git a/packages/rocketchat-authorization/server/methods/saveRole.coffee b/packages/rocketchat-authorization/server/methods/saveRole.coffee
index 8df33ff81a556c2daee3dcc5a5d23b68de0ff809..874fe0eaa6d0bc3de8ba8c3d1e178e857b42069a 100644
--- a/packages/rocketchat-authorization/server/methods/saveRole.coffee
+++ b/packages/rocketchat-authorization/server/methods/saveRole.coffee
@@ -3,15 +3,7 @@ Meteor.methods
 		if not Meteor.userId() or not RocketChat.authz.hasPermission Meteor.userId(), 'access-permissions'
 			throw new Meteor.Error "not-authorized"
 
-		console.log '[methods] authorization:saveRole -> '.green, 'arguments:', arguments
+		if not roleData.name?
+			throw new Meteor.Error 'invalid-data', 'Role name is required'
 
-		saveData =
-			description: roleData.description
-
-		if not _id? and roleData.name?
-			saveData.name = roleData.name
-
-		if _id?
-			return Meteor.roles.update _id, { $set: saveData }
-		else
-			return Meteor.roles.insert saveData
+		return RocketChat.models.Roles.createOrUpdate roleData.name, 'Users', roleData.description
diff --git a/packages/rocketchat-authorization/server/models/Base.js b/packages/rocketchat-authorization/server/models/Base.js
new file mode 100644
index 0000000000000000000000000000000000000000..5977c6446677641d03f7e66ada585774895224d0
--- /dev/null
+++ b/packages/rocketchat-authorization/server/models/Base.js
@@ -0,0 +1,38 @@
+RocketChat.models._Base.prototype.roleBaseQuery = function(userId, scope) { return {} }
+
+RocketChat.models._Base.prototype.findRolesByUserId = function(userId, options) {
+	var query = this.roleBaseQuery(userId);
+	return this.find(query, { fields: { roles: 1 } });
+}
+
+RocketChat.models._Base.prototype.isUserInRole = function(userId, roleName, scope) {
+	var query = this.roleBaseQuery(userId, scope);
+	query.roles = roleName;
+	return !_.isUndefined(this.findOne(query));
+}
+
+RocketChat.models._Base.prototype.addRolesByUserId = function(userId, roles, scope) {
+	var roles = [].concat(roles);
+	var query = this.roleBaseQuery(userId, scope);
+	var update = {
+		$addToSet: {
+			roles: { $each: roles }
+		}
+	}
+	return this.update(query, update);
+}
+
+RocketChat.models._Base.prototype.removeRolesByUserId = function(userId, roles, scope) {
+	var roles = [].concat(roles);
+	var query = this.roleBaseQuery(userId, scope);
+	var update = {
+		$pullAll: {
+			roles: roles
+		}
+	}
+	return this.update(query, update);
+}
+
+RocketChat.models._Base.prototype.findUsersInRoles = function() {
+	throw new Meteor.Error('overwrite-function', 'You must overwrite this function in the extended classes');
+}
diff --git a/packages/rocketchat-authorization/server/models/Permissions.coffee b/packages/rocketchat-authorization/server/models/Permissions.coffee
index 3e1c6eef96a5e025b65cbbad6fe3929ea2e7a8fc..ec763d94b7122a1d14dcde4db00e4f26b850b792 100644
--- a/packages/rocketchat-authorization/server/models/Permissions.coffee
+++ b/packages/rocketchat-authorization/server/models/Permissions.coffee
@@ -2,7 +2,6 @@ RocketChat.models.Permissions = new class extends RocketChat.models._Base
 	constructor: ->
 		@_initModel 'permissions'
 
-
 	# FIND
 	findByRole: (role, options) ->
 		query =
diff --git a/packages/rocketchat-authorization/server/models/Roles.coffee b/packages/rocketchat-authorization/server/models/Roles.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..8489afa1d47ac77c94b8acc537d88bab2faa09d8
--- /dev/null
+++ b/packages/rocketchat-authorization/server/models/Roles.coffee
@@ -0,0 +1,43 @@
+RocketChat.models.Roles = new class extends RocketChat.models._Base
+	constructor: ->
+		@_initModel 'roles'
+		@tryEnsureIndex { 'name': 1 }
+		@tryEnsureIndex { 'scope': 1 }
+
+	findUsersInRole: (name, scope, options) ->
+		role = @findOne name
+		roleScope = role?.scope or 'Users'
+		RocketChat.models[roleScope]?.findUsersInRoles?(name, scope, options)
+
+	isUserInRoles: (userId, roles, scope) ->
+		roles = [].concat roles
+		_.some roles, (roleName) =>
+			role = @findOne roleName
+			roleScope = role?.scope or 'Users'
+			return RocketChat.models[roleScope]?.isUserInRole?(userId, roleName, scope)
+
+	createOrUpdate: (name, scope, description, protectedRole) ->
+		scope ?= 'Users'
+		updateData = {}
+		updateData.name = name
+		updateData.scope = scope
+		if description?
+			updateData.description = description
+		if protectedRole?
+			updateData.protected = protectedRole
+
+		@upsert { _id: name }, { $set: updateData }
+
+	addUserRoles: (userId, roles, scope) ->
+		roles = [].concat roles
+		for roleName in roles
+			role = @findOne roleName
+			roleScope = role?.scope or 'Users'
+			RocketChat.models[roleScope]?.addRolesByUserId?(userId, roleName, scope)
+
+	removeUserRoles: (userId, roles, scope) ->
+		roles = [].concat roles
+		for roleName in roles
+			role = @findOne roleName
+			roleScope = role?.scope or 'Users'
+			RocketChat.models[roleScope]?.removeRolesByUserId?(userId, roleName, scope)
diff --git a/packages/rocketchat-authorization/server/models/Subscriptions.js b/packages/rocketchat-authorization/server/models/Subscriptions.js
new file mode 100644
index 0000000000000000000000000000000000000000..9c7d4a16fc760f753d6109bc14d64932d245aa05
--- /dev/null
+++ b/packages/rocketchat-authorization/server/models/Subscriptions.js
@@ -0,0 +1,28 @@
+RocketChat.models.Subscriptions.roleBaseQuery = function(userId, scope) {
+	var query = { "u._id": userId }
+	if (!_.isUndefined(scope)) {
+		query.rid = scope;
+	}
+	return query;
+}
+
+RocketChat.models.Subscriptions.findUsersInRoles = function(roles, scope, options) {
+	roles = [].concat(roles);
+
+	var query = {
+		roles: { $in: roles }
+	}
+
+	if (scope) {
+		query.rid = scope;
+	}
+
+	subscriptions = this.find(query).fetch();
+
+	users = _.compact(_.map(subscriptions, function(subscription) {
+		if ('undefined' !== typeof subscription.u && 'undefined' !== typeof subscription.u._id)
+			return subscription.u._id
+	}));
+
+	return RocketChat.models.Users.find({ _id: { $in: users } }, options);
+}
diff --git a/packages/rocketchat-authorization/server/models/Users.js b/packages/rocketchat-authorization/server/models/Users.js
new file mode 100644
index 0000000000000000000000000000000000000000..315ab7e9acf9500536ff5c9ca491bc380d1f3970
--- /dev/null
+++ b/packages/rocketchat-authorization/server/models/Users.js
@@ -0,0 +1,13 @@
+RocketChat.models.Users.roleBaseQuery = function(userId, scope) {
+	return { _id: userId }
+}
+
+RocketChat.models.Users.findUsersInRoles = function(roles, scope, options) {
+	roles = [].concat(roles);
+
+	var query = {
+		roles: { $in: roles }
+	}
+
+	return this.find(query, options);
+}
diff --git a/packages/rocketchat-authorization/server/publication.coffee b/packages/rocketchat-authorization/server/publication.coffee
deleted file mode 100644
index 8f6e008e14c17c2c5da24bd2c4b52071452e8fd6..0000000000000000000000000000000000000000
--- a/packages/rocketchat-authorization/server/publication.coffee
+++ /dev/null
@@ -1,3 +0,0 @@
-Meteor.publish 'permissions', ->
-	console.log '[publish] permissions'.green
-	return RocketChat.models.Permissions.find {}
diff --git a/packages/rocketchat-authorization/server/publications/permissions.js b/packages/rocketchat-authorization/server/publications/permissions.js
new file mode 100644
index 0000000000000000000000000000000000000000..0872d3b4db046cc84791c55c1e576b7399bd4218
--- /dev/null
+++ b/packages/rocketchat-authorization/server/publications/permissions.js
@@ -0,0 +1,3 @@
+Meteor.publish('permissions', function () {
+	return RocketChat.models.Permissions.find({});
+});
diff --git a/packages/rocketchat-authorization/server/publications/roles.coffee b/packages/rocketchat-authorization/server/publications/roles.coffee
index 6357a62510e7c6a4635d19a169531248d04a0145..b3eafb56d3e50b2a485ab95413f4a4064755d776 100644
--- a/packages/rocketchat-authorization/server/publications/roles.coffee
+++ b/packages/rocketchat-authorization/server/publications/roles.coffee
@@ -2,7 +2,5 @@ Meteor.publish 'roles', ->
 	unless @userId
 		return @ready()
 
-	if not RocketChat.authz.hasPermission @userId, 'access-permissions'
-		throw new Meteor.Error "not-authorized"
+	return RocketChat.models.Roles.find()
 
-	return RocketChat.authz.getRoles()
diff --git a/packages/rocketchat-authorization/server/publications/scopedRoles.js b/packages/rocketchat-authorization/server/publications/scopedRoles.js
new file mode 100644
index 0000000000000000000000000000000000000000..bd6247697b0abb90c100593ea93c9aa097bdaf58
--- /dev/null
+++ b/packages/rocketchat-authorization/server/publications/scopedRoles.js
@@ -0,0 +1,11 @@
+/**
+ * Publish logged-in user's roles so client-side checks can work.
+ */
+Meteor.publish('scopedRoles', function (scope) {
+	if (!this.userId || _.isUndefined(RocketChat.models[scope]) || !_.isFunction(RocketChat.models[scope].findRolesByUserId)) {
+		this.ready()
+		return
+	}
+
+	return RocketChat.models[scope].findRolesByUserId(this.userId);
+});
diff --git a/packages/rocketchat-authorization/server/startup.coffee b/packages/rocketchat-authorization/server/startup.coffee
index 905a43410e67a7471e24aeceb5a5a5a5bf0c36c7..7febc408c37ea789fcf0026dc4491a4d7a747545 100644
--- a/packages/rocketchat-authorization/server/startup.coffee
+++ b/packages/rocketchat-authorization/server/startup.coffee
@@ -7,7 +7,7 @@ Meteor.startup ->
 	permissions = [
 
 		{ _id: 'view-statistics',
-		roles : ['admin', 'temp-role']}
+		roles : ['admin']}
 
 		{ _id: 'view-privileged-setting',
 		roles : ['admin']}
@@ -27,11 +27,14 @@ Meteor.startup ->
 		{ _id: 'edit-other-user-info',
 		roles : ['admin']}
 
+		{ _id: 'edit-other-user-password',
+		roles : ['admin']}
+
 		{ _id: 'assign-admin-role',
 		roles : ['admin']}
 
 		{ _id: 'edit-other-user-active-status',
-		roles : ['admin', 'site-moderator']}
+		roles : ['admin']}
 
 		{ _id: 'delete-user',
 		roles : ['admin']}
@@ -46,31 +49,43 @@ Meteor.startup ->
 		roles : ['admin']}
 
 		{ _id: 'create-c',
-		roles : ['admin', 'site-moderator', 'user']}
+		roles : ['admin', 'user']}
 
 		{ _id: 'delete-c',
-		roles : ['admin', 'site-moderator']}
+		roles : ['admin']}
 
 		{ _id: 'edit-room',
-		roles : ['admin', 'site-moderator', 'moderator']}
+		roles : ['admin', 'moderator', 'owner']}
 
 		{ _id: 'edit-message',
-		roles : ['admin', 'site-moderator', 'moderator']}
+		roles : ['admin', 'moderator', 'owner']}
 
 		{ _id: 'delete-message',
-		roles : ['admin', 'site-moderator', 'moderator']}
+		roles : ['admin', 'moderator', 'owner']}
+
+		{ _id: 'remove-user',
+		roles : ['admin', 'moderator', 'owner']}
+
+		{ _id: 'mute-user',
+		roles : ['admin', 'moderator', 'owner']}
 
 		{ _id: 'ban-user',
-		roles : ['admin', 'site-moderator', 'moderator']}
+		roles : ['admin', 'moderator', 'owner']}
+
+		{ _id: 'set-moderator',
+		roles : ['admin', 'owner']}
+
+		{ _id: 'set-owner',
+		roles : ['admin']}
 
 		{ _id: 'create-p',
-		roles : ['admin', 'site-moderator', 'user']}
+		roles : ['admin', 'user']}
 
 		{ _id: 'delete-p',
-		roles : ['admin', 'site-moderator']}
+		roles : ['admin']}
 
 		{ _id: 'delete-d',
-		roles : ['admin', 'site-moderator']}
+		roles : ['admin']}
 
 		{ _id: 'bulk-register-user',
 		roles : ['admin']}
@@ -79,13 +94,13 @@ Meteor.startup ->
 		roles : ['admin']}
 
 		{ _id: 'view-c-room',
-		roles : ['admin', 'site-moderator', 'user']}
+		roles : ['admin', 'user']}
 
 		{ _id: 'view-p-room',
-		roles : ['admin', 'site-moderator', 'user']}
+		roles : ['admin', 'user']}
 
 		{ _id: 'view-d-room',
-		roles : ['admin', 'site-moderator', 'user']}
+		roles : ['admin', 'user']}
 
 		{ _id: 'access-permissions',
 		roles : ['admin']}
@@ -94,17 +109,22 @@ Meteor.startup ->
 		roles : ['admin']}
 
 		{ _id: 'manage-integrations',
+		roles : ['admin', 'bot']}
+
+		{ _id: 'manage-oauth-apps',
 		roles : ['admin']}
 	]
 
-	#alanning:roles
-	roles = _.pluck(Roles.getAllRoles().fetch(), 'name');
-
 	for permission in permissions
-		RocketChat.models.Permissions.upsert( permission._id, {$setOnInsert : permission })
-		for role in permission.roles
-			unless role in roles
-				Roles.createRole role
-				roles.push(role)
-
+		RocketChat.models.Permissions.upsert( permission._id, {$set: permission })
+
+	defaultRoles = [
+		{ name: 'admin', scope: 'Users' }
+		{ name: 'moderator', scope: 'Subscriptions' }
+		{ name: 'owner', scope: 'Subscriptions' }
+		{ name: 'user', scope: 'Users' }
+		{ name: 'bot', scope: 'Users' }
+	]
 
+	for role in defaultRoles
+		RocketChat.models.Roles.createOrUpdate role.name, role.scope
diff --git a/packages/rocketchat-autolinker/package.js b/packages/rocketchat-autolinker/package.js
index af2c141991583727bce93cf9f1195b00d03bf955..26e5d0a3f02adaa5fc72b759d10bc76ed8b5fc40 100644
--- a/packages/rocketchat-autolinker/package.js
+++ b/packages/rocketchat-autolinker/package.js
@@ -11,7 +11,7 @@ Package.onUse(function(api) {
 	api.use([
 		'coffeescript',
 		'konecty:autolinker',
-		'rocketchat:lib@0.0.1'
+		'rocketchat:lib'
 	]);
 
 	api.addFiles('autolinker.coffee', ['server','client']);
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..c55e6956b7b2068df6f4cacb5a4448c7f21aba33
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/client/lib/startup.coffee
@@ -0,0 +1,13 @@
+Meteor.startup ->
+	RocketChat.ChannelSettings.addOption
+		id: 'mail-messages'
+		template: 'channelSettingsMailMessages'
+		validation: ->
+			return RocketChat.authz.hasAllPermission('mail-messages')
+
+	RocketChat.callbacks.add 'roomExit', (mainNode) ->
+		messagesBox = $('.messages-box')
+		if messagesBox.get(0)?
+			instance = Blaze.getView(messagesBox.get(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..d78a9c41f42654c68c5ee85bcd94586f0701d5cd
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/client/views/mailMessagesInstructions.coffee
@@ -0,0 +1,123 @@
+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(', ')
+	autocompleteSettings: ->
+		return {
+			limit: 10
+			# inputDelay: 300
+			rules: [
+				{
+					# @TODO maybe change this 'collection' and/or template
+					collection: 'CachedChannelList'
+					subscription: 'userAutocomplete'
+					field: 'username'
+					template: Template.userSearch
+					noMatchTemplate: Template.userSearchEmpty
+					matchAll: true
+					filter:
+						exceptions: Template.instance().selectedUsers.get()
+					selector: (match) ->
+						return { username: match }
+					sort: 'username'
+				}
+			]
+		}
+	selectedUsers: ->
+		return Template.instance().selectedUsers.get()
+
+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_emails]').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_emails]').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 if not t.selectedUsers.get().length
+			t.$('.error-missing-to').show()
+			error = true
+
+		if error
+			$btn.html(oldBtnValue)
+		else
+			data =
+				rid: Session.get('openedRoom')
+				to_users: t.selectedUsers.get()
+				to_emails: t.$('input[name=to_emails]').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)
+
+				console.log(result)
+				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')
+
+	'autocompleteselect #to_users': (event, instance, doc) ->
+		instance.selectedUsers.set instance.selectedUsers.get().concat doc.username
+		event.currentTarget.value = ''
+		event.currentTarget.focus()
+
+	'click .remove-to-user': (e, instance) ->
+		self = @
+
+		users = Template.instance().selectedUsers.get()
+		users = _.reject Template.instance().selectedUsers.get(), (_id) ->
+			return _id is self.valueOf()
+
+		Template.instance().selectedUsers.set(users)
+
+		$('#to_users').focus()
+
+Template.mailMessagesInstructions.onCreated ->
+	@autoCompleteCollection = new Mongo.Collection null
+	@selectedUsers = new ReactiveVar []
+	@erroredEmails = new ReactiveVar []
+
+	@reset = =>
+		@selectedUsers.set []
+		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..c2a8dd37da01142ca3b30e91802a0ebec590b519
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/client/views/mailMessagesInstructions.html
@@ -0,0 +1,55 @@
+<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_users"}}</label>
+						<div>
+							{{> inputAutocomplete settings=autocompleteSettings id="to_users" name="to_users" class="search" autocomplete="off"}}
+							<ul class="selected-users">
+								{{#each selectedUsers}}
+									<li>{{.}} <i class="icon-cancel remove-to-user"></i></li>
+								{{/each}}
+							</ul>
+						</div>
+					</div>
+					<div class="input-line double-col">
+						<label>{{_ "Additional_emails"}}</label>
+						<div>
+							<input type="text" name="to_emails" 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/ar.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/ar.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..ad10bc3dc16ab6b133aaa18e8c5cb787782522ac
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/ar.i18n.json
@@ -0,0 +1,6 @@
+{
+  "Choose_messages" : "اختر الرسائل",
+  "From" : "من",
+  "Sending" : "جار الإرسال...",
+  "Subject" : "الموضوع"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/cs.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/cs.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/cs.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/de.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/de.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..5e5f1ba3fb4b86c58741e9d04639c4ef333e924c
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/de.i18n.json
@@ -0,0 +1,16 @@
+{
+  "Additional_emails" : "Zusätzliche E-Mails",
+  "Body" : "Body",
+  "Choose_messages" : "Nachrichten auswählen",
+  "From" : "Absender",
+  "Mail_Message_Invalid_emails" : "Sie haben eine oder mehrere ungültige E-Mail-Adressen angegeben: %s",
+  "Mail_Message_Missing_to" : "Sie müssen einen/mehrere Benutzer auswählen oder einen/mehrere E-Mail-Adressen durch Kommata getrennt angeben.",
+  "Mail_Message_No_messages_selected_select_all" : "Sie haben keine Nachrichten ausgewählt. Möchten Sie <a href='#' class='select-all'>alle</a> sichtbaren Nachrichten auswählen?",
+  "Mail_Messages" : "Nachrichten per E-Mail senden",
+  "Mail_Messages_Instructions" : "Wählen Sie aus, welche Nachrichten Sie per E-Mail senden möchten, indem Sie die Nachrichten anklicken. ",
+  "Mail_Messages_Subject" : "Hier ist ein ausgewählter Teil aus %s Nachrichten",
+  "Sending" : "Senden...",
+  "Subject" : "Betreff",
+  "To_users" : "An die Benutzer",
+  "Your_email_has_been_queued_for_sending" : "Ihre E-Mail wird in Kürze gesendet werden."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/el.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/el.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/el.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
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..9383ba9a910b3124ff149e4b4bb289c4092a5338
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/en.i18n.json
@@ -0,0 +1,16 @@
+{
+  "Additional_emails" : "Additional E-mails",
+  "Body" : "Body",
+  "Choose_messages" : "Choose messages",
+  "From" : "From",
+  "Mail_Message_Invalid_emails" : "You have provided one or more invalid e-mails: %s",
+  "Mail_Message_Missing_to" : "You must select one or more users or provide one or more 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",
+  "Sending" : "Sending...",
+  "Subject" : "Subject",
+  "To_users" : "To Users",
+  "Your_email_has_been_queued_for_sending" : "Your email has been queued for sending"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/es.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/es.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/es.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/fa.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/fa.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/fa.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/fi.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/fi.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..062abf850411e79abafad617ecb6c74ad8e11e19
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/fi.i18n.json
@@ -0,0 +1,16 @@
+{
+  "Additional_emails" : "Lisäsähköpostit",
+  "Body" : "Runko",
+  "Choose_messages" : "Valitse viestit",
+  "From" : "Lähettäjä",
+  "Mail_Message_Invalid_emails" : "Olet antanut virheellisiä sähköposteja: %s",
+  "Mail_Message_Missing_to" : "Sinun tulee valita yksi tai useampi käyttäjä tai yksi tai useampi sähköpostiosoite, pilkuilla eroteltuna.",
+  "Mail_Message_No_messages_selected_select_all" : "Et ole valinnut yhtään viestiä. Haluaisitko <a href='#' class='select-all'>valita kaikki</a> näkyvät viestit?",
+  "Mail_Messages" : "Lähetä viestit sähköpostitse",
+  "Mail_Messages_Instructions" : "Valitse, mitkä viestit haluat lähettää sähköpostitse klikkaamalla viestejä",
+  "Mail_Messages_Subject" : "Tässä muutama viesti (%s viestiä)",
+  "Sending" : "Lähetetään...",
+  "Subject" : "Aihe",
+  "To_users" : "Käyttäjille",
+  "Your_email_has_been_queued_for_sending" : "Sähköpostisi on lähetysjonossa"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/fr.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/fr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..3092354611af32f7fc2388898cc9fbadc16424ea
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/fr.i18n.json
@@ -0,0 +1,14 @@
+{
+  "Body" : "Corps",
+  "Choose_messages" : "Choisissez des messages",
+  "From" : "De",
+  "Mail_Message_Invalid_emails" : "Vous avez fourni un ou plusieurs e-mails invalides : %s",
+  "Mail_Message_Missing_to" : "Vous devez sélectionner un ou plusieurs utilisateurs ou fournir une ou plusieurs adresses e-mail, séparées par des virgules.",
+  "Mail_Message_No_messages_selected_select_all" : "Vous n'avez sélectionné aucun message. Voudriez-vous <a href='#' class='select-all'>sélectionner tous</a> les messages visibles ?",
+  "Mail_Messages" : "Messages électroniques",
+  "Mail_Messages_Instructions" : "Choisissez les messages que vous souhaitez envoyer par e-mail en cliquant dessus",
+  "Mail_Messages_Subject" : "Voici une sélection des messages \"%s\"",
+  "Sending" : "Envoi...",
+  "Subject" : "Sujet",
+  "Your_email_has_been_queued_for_sending" : "Votre email a été mis en boite d'envoi"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/he.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/he.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..0ee4017b43ee20d0b34a6bf8e68d5151965ef4f8
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/he.i18n.json
@@ -0,0 +1,4 @@
+{
+  "Choose_messages" : "בחירת הודעות",
+  "To_users" : "למשתמשים"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/hr.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/hr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6bbb424d86f3fcdfd0de9426c0a1ab642384ec10
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/hr.i18n.json
@@ -0,0 +1,8 @@
+{
+  "Additional_emails" : "Dodatni E-mailovi",
+  "Choose_messages" : "Odaberite poruke",
+  "From" : "Od",
+  "Sending" : "Slanje ...",
+  "Subject" : "Naslov",
+  "To_users" : "Za korisnike"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/hu.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/hu.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/hu.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/it.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/it.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/it.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/ja.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/ja.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/ja.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/km.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/km.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/km.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/ko.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/ko.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/ko.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/ku.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/ku.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/ku.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/lo.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/lo.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/lo.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/ms-MY.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/ms-MY.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/ms-MY.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/nl.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/nl.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..ab0b7fd7daac13b4b7c14b4d18eeca711394c64e
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/nl.i18n.json
@@ -0,0 +1,13 @@
+{
+  "Additional_emails" : "Extra e-mails",
+  "Body" : "Body",
+  "Choose_messages" : "Kies berichten",
+  "From" : "Afzender",
+  "Mail_Message_Missing_to" : "U moet een of meer gebruikers selecteren of één of meer e-mailadressen invullen, gescheiden door komma's.",
+  "Mail_Message_No_messages_selected_select_all" : "Je hebt geen bericten geslecteerd. Zou je <a href='#' class='select-all'>alle zichtbare berichten</a> willen selecteren?",
+  "Mail_Messages" : "Mailberichten",
+  "Sending" : "Verzenden ...",
+  "Subject" : "Onderwerp",
+  "To_users" : "Aan Gebruikers",
+  "Your_email_has_been_queued_for_sending" : "Uw e-mail staat in de wachtrij voor het verzenden"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/pl.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/pl.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..ba59cee84fe5cdfc13b736527ef1125f7ae8811d
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/pl.i18n.json
@@ -0,0 +1,4 @@
+{
+  "Choose_messages" : "Wybierz wiadomości",
+  "Mail_Messages" : "Wysyłanie wiadomości przez email"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/pt.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/pt.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/pt.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/ro.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..a51eb8444692ecfe7d72a9f72aeaccace8df4e97
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/ro.i18n.json
@@ -0,0 +1,16 @@
+{
+  "Additional_emails" : "E-mail-uri suplimentare",
+  "Body" : "Corp",
+  "Choose_messages" : "Alege mesaje",
+  "From" : "De la",
+  "Mail_Message_Invalid_emails" : "Ați furnizat unul sau mai multe e-mailuri invalide: %s",
+  "Mail_Message_Missing_to" : "Trebuie să furnizați una sau mai multe adrese de e-mail pentru 'Către', separate prin virgulă.",
+  "Mail_Message_No_messages_selected_select_all" : "Nu ați selectat niciun mesaj. Aţi dori să <a href='#' class='select-all'>selctați toate</a> mesajele vizibile?",
+  "Mail_Messages" : "Mesaje Email",
+  "Mail_Messages_Instructions" : "Alegeți ce mesaje doriți să trimiteți prin e-mail făcând clic pe ele",
+  "Mail_Messages_Subject" : "Iată o parte din %s mesaje",
+  "Sending" : "Se trimite ...",
+  "Subject" : "Subiect",
+  "To_users" : "Către utilizatori",
+  "Your_email_has_been_queued_for_sending" : "Emailul dumneavoastră a fost pus pe lista de trimis"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/ru.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/ru.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..3cb700b27ab69f66d6cac571cbfd81679864541e
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/ru.i18n.json
@@ -0,0 +1,4 @@
+{
+  "Mail_Message_Missing_to" : "Вы должны выбрать одного или нескольких пользователей или указать один или несколько адресов электронной почты, разделенных запятыми.",
+  "To_users" : "Пользователям"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/sq.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/sq.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/sq.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/sr.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/sr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/sv.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/sv.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/sv.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/ta-IN.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/ta-IN.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/ta-IN.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/tr.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/tr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/tr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/ug.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/ug.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/ug.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/uk.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/uk.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/uk.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings-mail-messages/i18n/zh.i18n.json b/packages/rocketchat-channel-settings-mail-messages/i18n/zh.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/i18n/zh.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
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..76b23988382597a520d55b8e1b96bd5c653fab16
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/package.js
@@ -0,0 +1,50 @@
+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',
+		'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');
+	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..f1c07f4bb78ea7f1a2aa7b7d6ef6a8bed332aad4
--- /dev/null
+++ b/packages/rocketchat-channel-settings-mail-messages/server/methods/mailMessages.coffee
@@ -0,0 +1,57 @@
+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_users: [ String ], to_emails: 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 = _.compact(data.to_emails.trim().split(','))
+		missing = []
+		if data.to_users.length > 0
+			for username in data.to_users
+				user = RocketChat.models.Users.findOneByUsername(username)
+				if user?.emails?[0]?.address
+					emails.push user.emails[0].address
+				else
+					missing.push username
+		console.log emails
+		for email in emails
+			unless rfcMailPatternWithName.test email.trim()
+				throw new Meteor.Error('invalid-email', "[methods] mailMessages -> Invalid e-mail #{email}")
+
+		user = Meteor.user()
+		name = user.name
+		email = user.emails?[0]?.address
+
+		data.language = data.language.split('-').shift().toLowerCase()
+
+		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 { success: true, missing: missing }
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/startup/tabBar.coffee b/packages/rocketchat-channel-settings/client/startup/tabBar.coffee
index 17d1680317e5f51238544bf6c4a08cc9e7a6cc61..0381dcf755f790744300c330195adc650d9a7c25 100644
--- a/packages/rocketchat-channel-settings/client/startup/tabBar.coffee
+++ b/packages/rocketchat-channel-settings/client/startup/tabBar.coffee
@@ -1,12 +1,8 @@
 Meteor.startup ->
-
-	RocketChat.callbacks.add 'enter-room', (subscription) ->
-
-		if RocketChat.authz.hasAtLeastOnePermission('edit-room', subscription?.rid)
-			RocketChat.TabBar.addButton
-				id: 'channel-settings'
-				i18nTitle: 'Channel_Settings'
-				icon: 'octicon octicon-gear'
-				template: 'channelSettings'
-				order: 0
-	, RocketChat.callbacks.priority.MEDIUM, 'enter-room-tabbar-channel-settings'
+	RocketChat.TabBar.addButton
+		groups: ['channel', 'privategroup', 'directmessage']
+		id: 'channel-settings'
+		i18nTitle: 'Room_Info'
+		icon: 'octicon octicon-info'
+		template: 'channelSettings'
+		order: 0
diff --git a/packages/rocketchat-channel-settings/client/startup/trackSettingsChange.coffee b/packages/rocketchat-channel-settings/client/startup/trackSettingsChange.coffee
index b3618dd7232e96c9c775de28896c58df47feef05..4594215267d1c7eb2488293012ac53e6ae23b7f5 100644
--- a/packages/rocketchat-channel-settings/client/startup/trackSettingsChange.coffee
+++ b/packages/rocketchat-channel-settings/client/startup/trackSettingsChange.coffee
@@ -13,3 +13,15 @@ Meteor.startup ->
 		return msg
 
 	RocketChat.callbacks.add 'streamMessage', roomSettingsChangedCallback, RocketChat.callbacks.priority.HIGH
+
+	roomNameChangedCallback = (msg) ->
+		Tracker.nonreactive ->
+			if msg.t is 'r'
+				if Session.get('openedRoom') is msg.rid
+					type = if FlowRouter.current().route.name is 'channel' then 'c' else 'p'
+					RoomManager.close type + FlowRouter.getParam('name')
+					FlowRouter.go FlowRouter.current().route.name, name: msg.msg
+
+		return msg
+
+	RocketChat.callbacks.add 'streamMessage', roomNameChangedCallback, RocketChat.callbacks.priority.HIGH
diff --git a/packages/rocketchat-channel-settings/client/stylesheets/channel-settings.less b/packages/rocketchat-channel-settings/client/stylesheets/channel-settings.less
index 0227c11170d8da36077c2baffa8c113f2edd2ce1..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;
+				}
 			}
 		}
 
@@ -13,5 +27,9 @@
 			margin-top: 30px;
 			text-align: center;
 		}
+
+		[data-edit] {
+			cursor: pointer;
+		}
 	}
 }
diff --git a/packages/rocketchat-channel-settings/client/views/channelSettings.coffee b/packages/rocketchat-channel-settings/client/views/channelSettings.coffee
index 4f9f5d344c5d991fad19f382913407cb7ea7e37b..30529f9a8091ef7ff082cd6366ad5b25e14989ea 100644
--- a/packages/rocketchat-channel-settings/client/views/channelSettings.coffee
+++ b/packages/rocketchat-channel-settings/client/views/channelSettings.coffee
@@ -1,23 +1,109 @@
 Template.channelSettings.helpers
+	canEdit: ->
+		return RocketChat.authz.hasAllPermission('edit-room', @rid)
+	editing: (field) ->
+		return Template.instance().editing.get() is field
 	notDirect: ->
 		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'
+			return t('Channel')
+		else if roomType is 'p'
+			return t('Private_Group')
+	roomName: ->
+		return ChatRoom.findOne(@rid)?.name
+	roomTopic: ->
+		return ChatRoom.findOne(@rid)?.topic
+	archived: ->
+		return ChatRoom.findOne(@rid)?.archived
 
 Template.channelSettings.events
+	'keydown input[type=text]': (e, t) ->
+		if e.keyCode is 13
+			e.preventDefault()
+			t.saveSetting()
+
+	'click [data-edit]': (e, t) ->
+		e.preventDefault()
+		t.editing.set($(e.currentTarget).data('edit'))
+		setTimeout (-> t.$('input.editing').focus().select()), 100
+
+	'click .cancel': (e, t) ->
+		e.preventDefault()
+		t.editing.set()
+
 	'click .save': (e, t) ->
 		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'
 
-		settings =
-			roomType: t.$('input[name=roomType]:checked').val()
+	'click .unarchive': (e, t) ->
+		e.preventDefault()
 
-		Meteor.call 'saveRoomSettings', t.data.rid, settings, (err, results) ->
+		Meteor.call 'unarchiveRoom', t.data.rid, true, (err, results) ->
 			return toastr.error err.reason if err
-			toastr.success TAPi18n.__ 'Settings_updated'
+			toastr.success TAPi18n.__ 'Room_unarchived'
+
+Template.channelSettings.onCreated ->
+	@editing = new ReactiveVar
+
+	@validateRoomType = =>
+		type = @$('input[name=roomType]:checked').val()
+		if type not in ['c', 'p']
+			toastr.error t('Invalid_room_type', type)
+		return true
+
+	@validateRoomName = =>
+		rid = Template.currentData()?.rid
+		room = ChatRoom.findOne rid
+
+		if not RocketChat.authz.hasAllPermission('edit-room', @rid) or room.t not in ['c', 'p']
+			toastr.error t('Not_allowed')
+			return false
+
+		name = $('input[name=roomName]').val()
+		if not /^[0-9a-z-_]+$/.test name
+			toastr.error t('Invalid_room_name', name)
+			return false
+
+		return true
 
+	@validateRoomTopic = =>
+		return true
 
-			# switch room.t
-			# 	when 'c'
-			# 		FlowRouter.go 'channel', name: name
-			# 	when 'p'
-			# 		FlowRouter.go 'group', name: name
+	@saveSetting = =>
+		switch @editing.get()
+			when 'roomName'
+				if @validateRoomName()
+					Meteor.call 'saveRoomSettings', @data?.rid, 'roomName', @$('input[name=roomName]').val(), (err, result) ->
+						if err
+							if err.error in [ 'duplicate-name', 'name-invalid' ]
+								return toastr.error TAPi18n.__(err.reason, err.details.channelName)
+							return toastr.error TAPi18n.__(err.reason)
+						toastr.success TAPi18n.__ 'Room_name_changed_successfully'
+			when 'roomTopic'
+				if @validateRoomTopic()
+					Meteor.call 'saveRoomSettings', @data?.rid, 'roomTopic', @$('input[name=roomTopic]').val(), (err, result) ->
+						if err
+							return toastr.error TAPi18n.__(err.reason)
+						toastr.success TAPi18n.__ 'Room_topic_changed_successfully'
+			when 'roomType'
+				if @validateRoomType()
+					Meteor.call 'saveRoomSettings', @data?.rid, 'roomType', @$('input[name=roomType]:checked').val(), (err, result) ->
+						if err
+							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.__ 'Room_type_changed_successfully'
+		@editing.set()
diff --git a/packages/rocketchat-channel-settings/client/views/channelSettings.html b/packages/rocketchat-channel-settings/client/views/channelSettings.html
index c72ecae4ad66d4f22d6ecb136fc607766b3e11ab..8a326bd49117b25d98d02235dbe8fc83efd3ea35 100644
--- a/packages/rocketchat-channel-settings/client/views/channelSettings.html
+++ b/packages/rocketchat-channel-settings/client/views/channelSettings.html
@@ -1,25 +1,63 @@
 <template name="channelSettings">
-	<div class="control">
-		<div class="header">
-			<h2>{{_ "Room_Settings"}}</h2>
-		</div>
-	</div>
-	<div class="channel-settings scrollable">
-		<form>
-			<fieldset>
-				{{#if notDirect}}
-					<div class="input-line double-col">
-						<label>{{_ "Room_Type"}}</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>
-							<label><input type="radio" name="roomType" value="c" checked="{{$eq roomType 'c'}}" /> {{_ "Channel"}}</label>
-							<label><input type="radio" name="roomType" value="p" checked="{{$eq roomType 'p'}}" /> {{_ "Private_Group"}}</label>
+							{{#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}}
+								<span>{{roomTopic}}{{#if canEdit}} <i class="octicon octicon-pencil" data-edit="roomTopic"></i>{{/if}}</span>
+							{{/if}}
 						</div>
-					</div>
-				{{/if}}
-			</fieldset>
-			<div class="submit">
-				<button class="button save"><i class="icon-send"></i><span>{{_ "Save_changes"}}</span></button>
-			</div>
-		</form>
+					</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}}
+								<button class="button archive"><span>{{_ "Archive"}}</span></button>
+							{{/if}}
+						</li>
+					{{/if}}
+					{{#each channelSettings}}
+						{{> Template.dynamic template=template data=data}}
+					{{/each}}
+				</ul>
+			</form>
+		</div>
 	</div>
 </template>
diff --git a/packages/rocketchat-channel-settings/i18n/ar.i18n.json b/packages/rocketchat-channel-settings/i18n/ar.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..5f097c9f5662c2a8c494b36aba45d2682910f13b 100644
--- a/packages/rocketchat-channel-settings/i18n/ar.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/ar.i18n.json
@@ -1 +1,13 @@
-{ }
\ No newline at end of file
+{
+  "Archive_Unarchive" : "أرشفة/إلغاء الأرشفة",
+  "Channel" : "قناة",
+  "Private_Group" : "مجموعة خاصة",
+  "Save" : "حفظ",
+  "Topic" : "الموضوع",
+  "Type" : "النوع",
+  "Room_Info" : "معلومات الغرفة",
+  "room_changed_privacy" : "تم تغيير نوع الغرفة إلى: <em>__room_type__</em> بواسطة <em>__user_by__</em>",
+  "room_changed_topic" : "تم تغيير موضوع الغرفة إلى: <em>__room_topic__</em> بواسطة <em>__user_by__</em>",
+  "Room_topic_changed_successfully" : "تغيير موضوع الغرفة بنجاح",
+  "Room_type_changed_successfully" : "تم تغيير نوع الغرفة بنجاح"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/cs.i18n.json b/packages/rocketchat-channel-settings/i18n/cs.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..84eb3ce32fd3bf86f83bacec57592ef2c02834a6 100644
--- a/packages/rocketchat-channel-settings/i18n/cs.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/cs.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Save" : "Uložit"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/de.i18n.json b/packages/rocketchat-channel-settings/i18n/de.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..05456b08e2c3027f8d7092fdd6e7fce4605b4579 100644
--- a/packages/rocketchat-channel-settings/i18n/de.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/de.i18n.json
@@ -1 +1,13 @@
-{ }
\ No newline at end of file
+{
+  "Archive_Unarchive" : "Archivieren / Wiederherstellen",
+  "Channel" : "Kanal",
+  "Private_Group" : "Private Gruppe",
+  "Save" : "Speichern",
+  "Topic" : "Thema",
+  "Type" : "Typ",
+  "Room_Info" : "Raum",
+  "room_changed_privacy" : "Der Raum wurde von <em>__user_by__</em> zum/r <em>__room_type__</em> geändert.",
+  "room_changed_topic" : "Das Thema des Raums wurde von <em>__user_by__</em> zu <em>__room_topic__</em> geändert.",
+  "Room_topic_changed_successfully" : "Das Thema des Raums wurde erfolgreich geändert.",
+  "Room_type_changed_successfully" : "Der Raumtyp wurde erfolgreich geändert."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/el.i18n.json b/packages/rocketchat-channel-settings/i18n/el.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..8fe65b233818b01708c5b9c246d5ae5e3e7802f3 100644
--- a/packages/rocketchat-channel-settings/i18n/el.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/el.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Save" : "Αποθήκευση"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/en.i18n.json b/packages/rocketchat-channel-settings/i18n/en.i18n.json
index 3d4dda12e16da9238fc1f18adf40e503e6355d7a..7fa82c45dcbbfa018c5c71972d23202fc3bdd7c5 100644
--- a/packages/rocketchat-channel-settings/i18n/en.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/en.i18n.json
@@ -1,8 +1,13 @@
 {
+  "Archive_Unarchive" : "Archive / Unarchive",
   "Channel" : "Channel",
   "Private_Group" : "Private Group",
-  "Room_Type" : "Room Type",
-  "Room_Settings" : "Room Settings",
+  "Save" : "Save",
+  "Topic" : "Topic",
+  "Type" : "Type",
+  "Room_Info" : "Room Info",
   "room_changed_privacy" : "Room type changed to: <em>__room_type__</em> by <em>__user_by__</em>",
-  "room_changed_topic" : "Room topic changed to: <em>__room_topic__</em> by <em>__user_by__</em>"
+  "room_changed_topic" : "Room topic changed to: <em>__room_topic__</em> by <em>__user_by__</em>",
+  "Room_topic_changed_successfully" : "Room topic changed successfully",
+  "Room_type_changed_successfully" : "Room type changed successfully"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/es.i18n.json b/packages/rocketchat-channel-settings/i18n/es.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..05a125952ddf75c6d3713c92e893b4f71702c53c 100644
--- a/packages/rocketchat-channel-settings/i18n/es.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/es.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Save" : "Guardar"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/fi.i18n.json b/packages/rocketchat-channel-settings/i18n/fi.i18n.json
index ba9ae6c0008e97ce45f36604c628821967fd3187..578c094a27a4fa584c3934f44a2b94e1d1a732de 100644
--- a/packages/rocketchat-channel-settings/i18n/fi.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/fi.i18n.json
@@ -1,8 +1,13 @@
 {
+  "Archive_Unarchive" : "Arkistoi / palauta arkistosta",
   "Channel" : "Kanava",
   "Private_Group" : "Privaattiryhmä",
-  "Room_Type" : "Huoneen tyyppi",
-  "Room_Settings" : "Huoneen asetukset",
+  "Save" : "Tallenna",
+  "Topic" : "Aihe",
+  "Type" : "Tyyppi",
+  "Room_Info" : "Huoneen info",
   "room_changed_privacy" : "Huoneen tyyppi vaihdettu <em>__room_type__</em> käyttäjän <em>__user_by__</em> toimesta",
-  "room_changed_topic" : "Huoneen aihe vaihdettu <em>__room_topic__</em> käyttäjän <em>__user_by__</em> toimesta"
+  "room_changed_topic" : "Huoneen aihe vaihdettu <em>__room_topic__</em> käyttäjän <em>__user_by__</em> toimesta",
+  "Room_topic_changed_successfully" : "Huoneen aihe vaihdettu",
+  "Room_type_changed_successfully" : "Huoneen tyyppi vaihdettu"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/fr.i18n.json b/packages/rocketchat-channel-settings/i18n/fr.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..0e4908b96a1840117e148840bcfbe949719bc9e6 100644
--- a/packages/rocketchat-channel-settings/i18n/fr.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/fr.i18n.json
@@ -1 +1,13 @@
-{ }
\ No newline at end of file
+{
+  "Archive_Unarchive" : "Archiver / Désarchiver",
+  "Channel" : "Canal",
+  "Private_Group" : "Groupe privé",
+  "Save" : "Enregistrer",
+  "Topic" : "Sujet",
+  "Type" : "Type",
+  "Room_Info" : "Infos sur le salon",
+  "room_changed_privacy" : "Type du salon changé pour : <em>__room_type__</em> par <em>__user_by__</em>",
+  "room_changed_topic" : "Sujet du salon changé pour : <em>__room_topic__</em> by <em>__user_by__</em>",
+  "Room_topic_changed_successfully" : "Sujet du salon changé avec succès",
+  "Room_type_changed_successfully" : "Type de salon modifié avec succès"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/he.i18n.json b/packages/rocketchat-channel-settings/i18n/he.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..68f6f6ea7b8ffeb93add18059c6408310d136299 100644
--- a/packages/rocketchat-channel-settings/i18n/he.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/he.i18n.json
@@ -1 +1,10 @@
-{ }
\ No newline at end of file
+{
+  "Channel" : "ערוץ",
+  "Private_Group" : "קבוצה פרטית",
+  "Save" : "שמירה",
+  "Topic" : "נושא",
+  "Type" : "סוג",
+  "Room_Info" : "פרטי החדר",
+  "Room_topic_changed_successfully" : "נושא החדר שונה בהצלחה",
+  "Room_type_changed_successfully" : "סוג החדר שונה בהצלחה"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/hr.i18n.json b/packages/rocketchat-channel-settings/i18n/hr.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..3ee66adf8f1d484d9204bf61fd6f5e6c35161388 100644
--- a/packages/rocketchat-channel-settings/i18n/hr.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/hr.i18n.json
@@ -1 +1,6 @@
-{ }
\ No newline at end of file
+{
+  "Archive_Unarchive" : "Arhiviraj / Dearhiviraj",
+  "Private_Group" : "Privatna Grupa",
+  "Save" : "Sačuvaj",
+  "Type" : "Vrsta"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/hu.i18n.json b/packages/rocketchat-channel-settings/i18n/hu.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..f9fac2321e01af9b6198ace4523c6726294586ab 100644
--- a/packages/rocketchat-channel-settings/i18n/hu.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/hu.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Save" : "Mentés"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/it.i18n.json b/packages/rocketchat-channel-settings/i18n/it.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..48008e60a7dd308345a23013d476c2e7a8d9623e 100644
--- a/packages/rocketchat-channel-settings/i18n/it.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/it.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Save" : "Salva"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/ja.i18n.json b/packages/rocketchat-channel-settings/i18n/ja.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..70cdb7bff67d54f64c0a9c94c0fd863c34d25608 100644
--- a/packages/rocketchat-channel-settings/i18n/ja.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/ja.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Save" : "保存"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/km.i18n.json b/packages/rocketchat-channel-settings/i18n/km.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..598c01accce2c59cbb52ceedadc9e63a1bcf04e8 100644
--- a/packages/rocketchat-channel-settings/i18n/km.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/km.i18n.json
@@ -1 +1,5 @@
-{ }
\ No newline at end of file
+{
+  "Channel" : "ប៉ុស្តិ៍",
+  "Private_Group" : "ក្រុម​ឯកជន",
+  "Save" : "រក្សាទុក"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/ko.i18n.json b/packages/rocketchat-channel-settings/i18n/ko.i18n.json
index dc45aca964f9600eddad3957b45132488d8299a4..3c26cdb50935b8bf2cbde763085319d4edbd4e6d 100644
--- a/packages/rocketchat-channel-settings/i18n/ko.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/ko.i18n.json
@@ -1,8 +1,7 @@
 {
   "Channel" : "채널",
-  "Private_Group" : "개인 그룹",
-  "Room_Type" : "방 종류",
-  "Room_Settings" : "방 설정",
+  "Private_Group" : "비밀 그룹",
+  "Save" : "저장",
   "room_changed_privacy" : "방 종류가 <em>__user_by__</em>에서 <em>__room_type__</em>로 변경되었습니다.",
   "room_changed_topic" : "방 주제가 <em>__user_by__</em>에서 <em>__room_topic__</em>로 변경되었습니다."
 }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/ku.i18n.json b/packages/rocketchat-channel-settings/i18n/ku.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..5647eb663afa42df873882847dbb3d06dee2a4da 100644
--- a/packages/rocketchat-channel-settings/i18n/ku.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/ku.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Save" : "پاشەکەوت"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/ms-MY.i18n.json b/packages/rocketchat-channel-settings/i18n/ms-MY.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..c672c3727d8c51951e6e1e77048bbca1510c703d 100644
--- a/packages/rocketchat-channel-settings/i18n/ms-MY.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/ms-MY.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Save" : "Simpan"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/nl.i18n.json b/packages/rocketchat-channel-settings/i18n/nl.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..80b675a4377832ac8ff97b91e91d416a4f6c2006 100644
--- a/packages/rocketchat-channel-settings/i18n/nl.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/nl.i18n.json
@@ -1 +1,11 @@
-{ }
\ No newline at end of file
+{
+  "Archive_Unarchive" : "Archief / Uit archief",
+  "Channel" : "Kanaal",
+  "Private_Group" : "Privé-groep",
+  "Save" : "Bewaren",
+  "Topic" : "Onderwerp",
+  "Type" : "Type",
+  "Room_Info" : "Kamer info",
+  "Room_topic_changed_successfully" : "Kamer onderwerp succesvol gewijzigd",
+  "Room_type_changed_successfully" : "Kamertype met succes gewijzigd"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/pl.i18n.json b/packages/rocketchat-channel-settings/i18n/pl.i18n.json
index f93465d0f99a65709e2769fca20a31ac0348626b..8200c8c1f595a08debf524a53d30ba7a668c4b3f 100644
--- a/packages/rocketchat-channel-settings/i18n/pl.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/pl.i18n.json
@@ -1,8 +1,12 @@
 {
+  "Archive_Unarchive" : "Przeniesienie do archiwum",
   "Channel" : "Kanał",
   "Private_Group" : "Grupa Prywatna",
-  "Room_Type" : "Rodzaj pokoju",
-  "Room_Settings" : "Ustawienia pokoju",
+  "Save" : "Zapisz",
+  "Topic" : "Temat",
+  "Type" : "Rodzaj",
+  "Room_Info" : "Ustawienia pokoju",
   "room_changed_privacy" : "<em>__user_by__</em> zmienił(a) rodzaj pokoju na: <em>__room_type__</em>",
-  "room_changed_topic" : "<em>__user_by__</em> zmienił(a) temat pokoju na: <em>__room_topic__</em>"
+  "room_changed_topic" : "<em>__user_by__</em> zmienił(a) temat pokoju na: <em>__room_topic__</em>",
+  "Room_topic_changed_successfully" : "Temat pokoju został zmieniony"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/pt.i18n.json b/packages/rocketchat-channel-settings/i18n/pt.i18n.json
index f9d1b2c38ccf01f824d5f21b433ec0b805cba3ac..e41c8a68b54079d32238da76ab2e144095a48f52 100644
--- a/packages/rocketchat-channel-settings/i18n/pt.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/pt.i18n.json
@@ -1,6 +1,5 @@
 {
   "Channel" : "Canal",
   "Private_Group" : "Grupo Privado",
-  "Room_Type" : "Tipo de sala",
-  "Room_Settings" : "Configurações da Sala"
+  "Save" : "Salvar"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/ro.i18n.json b/packages/rocketchat-channel-settings/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..f730f467410be933be53c7a85c360ef985b0264f
--- /dev/null
+++ b/packages/rocketchat-channel-settings/i18n/ro.i18n.json
@@ -0,0 +1,13 @@
+{
+  "Archive_Unarchive" : "Arhivează / Dezarhivează",
+  "Channel" : "Canal",
+  "Private_Group" : "Grup privat",
+  "Save" : "Salvează",
+  "Topic" : "Subiect",
+  "Type" : "Tip",
+  "Room_Info" : "Info cameră",
+  "room_changed_privacy" : "Tipul camerei schimbat în: <em>__room_type__</em> de către <em>__user_by__</em>",
+  "room_changed_topic" : "Subiectul camerei schimbat în: <em>__room_topic__</em> de către <em>__user_by__</em>",
+  "Room_topic_changed_successfully" : "Subiectul camerei a fost schimbat cu succes.",
+  "Room_type_changed_successfully" : "Tipul de cameră a fost schimbat cu succes"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/ru.i18n.json b/packages/rocketchat-channel-settings/i18n/ru.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..99a76b5c0d7db6d52b44433ae2d27962d2f12b43 100644
--- a/packages/rocketchat-channel-settings/i18n/ru.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/ru.i18n.json
@@ -1 +1,9 @@
-{ }
\ No newline at end of file
+{
+  "Archive_Unarchive" : "Удалить / Восстановить",
+  "Save" : "Сохранить",
+  "Topic" : "Тема",
+  "Type" : "Тип",
+  "room_changed_privacy" : "Тип чата изменен на: <em>__room_type__</em> by <em>__user_by__</em>",
+  "Room_topic_changed_successfully" : "Тема чата успешно изменена",
+  "Room_type_changed_successfully" : "Тип чата успешно изменен"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/sq.i18n.json b/packages/rocketchat-channel-settings/i18n/sq.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..b01a59cc8c1c69ffbcff4e8cc7847288eac34f22 100644
--- a/packages/rocketchat-channel-settings/i18n/sq.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/sq.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Save" : "Ruaj"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/sr.i18n.json b/packages/rocketchat-channel-settings/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..dabebdbb00a1a9747ffd90bffe5a9d083edfadf9
--- /dev/null
+++ b/packages/rocketchat-channel-settings/i18n/sr.i18n.json
@@ -0,0 +1,3 @@
+{
+  "Save" : "Сачувај"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/sv.i18n.json b/packages/rocketchat-channel-settings/i18n/sv.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..7bc9d5f5301627b9b75bf2caa789874a33ed6ec6 100644
--- a/packages/rocketchat-channel-settings/i18n/sv.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/sv.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Save" : "Spara"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/ta-IN.i18n.json b/packages/rocketchat-channel-settings/i18n/ta-IN.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..9a9ac953658e09a14c6ceaa86e434da65066c643 100644
--- a/packages/rocketchat-channel-settings/i18n/ta-IN.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/ta-IN.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Save" : "சேமி"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/tr.i18n.json b/packages/rocketchat-channel-settings/i18n/tr.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..17b9fac70d281ea1fa9090c4ce67a72bc1f7ec7f 100644
--- a/packages/rocketchat-channel-settings/i18n/tr.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/tr.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Save" : "Kaydet"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/ug.i18n.json b/packages/rocketchat-channel-settings/i18n/ug.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..54117dbd0a54a794770392fe7a6150d54a5ccbf7 100644
--- a/packages/rocketchat-channel-settings/i18n/ug.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/ug.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Save" : "ساقلاش"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/uk.i18n.json b/packages/rocketchat-channel-settings/i18n/uk.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..73f4e68da7668356f36d635b8dc2bfd042497323 100644
--- a/packages/rocketchat-channel-settings/i18n/uk.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/uk.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Save" : "Зберегти"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/i18n/zh.i18n.json b/packages/rocketchat-channel-settings/i18n/zh.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..70cdb7bff67d54f64c0a9c94c0fd863c34d25608 100644
--- a/packages/rocketchat-channel-settings/i18n/zh.i18n.json
+++ b/packages/rocketchat-channel-settings/i18n/zh.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Save" : "保存"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-channel-settings/package.js b/packages/rocketchat-channel-settings/package.js
index 06b8f3fe128ac6140841c36bb2827c5a803c48f6..a551aa5cde919f05b295b32b0f6db009a83c8bb1 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'
+		'rocketchat:lib'
 	]);
 
 	api.addFiles([
+		'client/lib/ChannelSettings.coffee',
 		'client/startup/messageTypes.coffee',
 		'client/startup/tabBar.coffee',
 		'client/startup/trackSettingsChange.coffee',
@@ -25,7 +28,9 @@ Package.onUse(function(api) {
 	], 'client');
 
 	api.addFiles([
-		'server/functions/changeRoomType.coffee',
+		'server/functions/saveRoomType.coffee',
+		'server/functions/saveRoomTopic.coffee',
+		'server/functions/saveRoomName.coffee',
 		'server/methods/saveRoomSettings.coffee',
 		'server/models/Messages.coffee'
 	], 'server');
@@ -38,8 +43,7 @@ Package.onUse(function(api) {
 			return 'i18n/' + filename;
 		}
 	}));
-	api.use('tap:i18n@1.6.1');
-	api.imply('tap:i18n');
+	api.use('tap:i18n');
 	api.addFiles(tapi18nFiles);
 });
 
diff --git a/packages/rocketchat-channel-settings/server/functions/changeRoomType.coffee b/packages/rocketchat-channel-settings/server/functions/changeRoomType.coffee
deleted file mode 100644
index e9c89567302e183d11b51dec04818c0dacdde7c5..0000000000000000000000000000000000000000
--- a/packages/rocketchat-channel-settings/server/functions/changeRoomType.coffee
+++ /dev/null
@@ -1,47 +0,0 @@
-RocketChat.changeRoomType = (rid, roomType) ->
-	console.log '[function] RocketChat.changeRoomType'.green, rid, roomType
-
-	unless Match.test rid, String
-		throw new Meteor.Error 'invalid-rid'
-
-	if roomType not in ['c', 'p']
-		throw new Meteor.Error 'invalid-room-type'
-
-	return RocketChat.models.Rooms.setTypeById(rid, roomType) and RocketChat.models.Subscriptions.updateTypeByRoomId(rid, roomType)
-
-
-	# username = s.trim username
-	# if not user or not username
-	# 	return false
-
-	# if not /^[0-9a-zA-Z-_.]+$/.test username
-	# 	return false
-
-	# # User already has desired username, return
-	# if user.username is username
-	# 	return user
-
-	# # Check username availability
-	# unless RocketChat.checkUsernameAvailability username
-	# 	return false
-
-	# previousUsername = user.username
-
-	# # Username is available; if coming from old username, update all references
-	# if previousUsername
-	# 	RocketChat.models.Messages.updateAllUsernamesByUserId user._id, username
-
-	# 	RocketChat.models.Messages.findByMention(previousUsername).forEach (msg) ->
-	# 		updatedMsg = msg.msg.replace(new RegExp("@#{previousUsername}", "ig"), "@#{username}")
-	# 		RocketChat.models.Messages.updateUsernameAndMessageOfMentionByIdAndOldUsername msg._id, previousUsername, username, updatedMsg
-
-	# 	RocketChat.models.Rooms.replaceUsername previousUsername, username
-	# 	RocketChat.models.Rooms.replaceUsernameOfUserByUserId user._id, username
-
-	# 	RocketChat.models.Subscriptions.setUserUsernameByUserId user._id, username
-	# 	RocketChat.models.Subscriptions.setNameForDirectRoomsWithOldName previousUsername, username
-
-	# # Set new username
-	# Meteor.users.update { _id: user._id }, { $set: { username: username } }
-	# user.username = username
-	# return user
diff --git a/packages/rocketchat-channel-settings/server/functions/saveRoomName.coffee b/packages/rocketchat-channel-settings/server/functions/saveRoomName.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..9833b88764b271b3dadbae28f68b7ddce0041ec6
--- /dev/null
+++ b/packages/rocketchat-channel-settings/server/functions/saveRoomName.coffee
@@ -0,0 +1,29 @@
+RocketChat.saveRoomName = (rid, name) ->
+	if not Meteor.userId()
+		throw new Meteor.Error('invalid-user', "[methods] sendMessage -> Invalid user")
+
+	room = RocketChat.models.Rooms.findOneById rid
+
+	if room.t not in ['c', 'p']
+		throw new Meteor.Error 403, 'Not allowed'
+
+	unless RocketChat.authz.hasPermission(Meteor.userId(), 'edit-room', rid)
+	#if room.u._id isnt Meteor.userId() and not hasPermission
+		throw new Meteor.Error 403, 'Not allowed'
+
+	if not /^[0-9a-z-_]+$/.test name
+		throw new Meteor.Error 'name-invalid', 'Invalid_room_name', { channelName: name }
+
+	name = _.slugify name
+
+	if name is room.name
+		return
+
+	# avoid duplicate names
+	if RocketChat.models.Rooms.findOneByName name
+		throw new Meteor.Error 'duplicate-name', 'Duplicate_channel_name', { channelName: name }
+
+	RocketChat.models.Rooms.setNameById rid, name
+	RocketChat.models.Subscriptions.updateNameByRoomId rid, name
+
+	return name
diff --git a/packages/rocketchat-channel-settings/server/functions/saveRoomTopic.coffee b/packages/rocketchat-channel-settings/server/functions/saveRoomTopic.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..6f3a7f24020e4c8335184157a1ec0135be872cac
--- /dev/null
+++ b/packages/rocketchat-channel-settings/server/functions/saveRoomTopic.coffee
@@ -0,0 +1,5 @@
+RocketChat.saveRoomTopic = (rid, roomTopic) ->
+	unless Match.test rid, String
+		throw new Meteor.Error 'invalid-rid'
+
+	return RocketChat.models.Rooms.setTopicById(rid, roomTopic)
diff --git a/packages/rocketchat-channel-settings/server/functions/saveRoomType.coffee b/packages/rocketchat-channel-settings/server/functions/saveRoomType.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..d990a4b3aeeb2ccd84f219f8573eccd8278175c9
--- /dev/null
+++ b/packages/rocketchat-channel-settings/server/functions/saveRoomType.coffee
@@ -0,0 +1,8 @@
+RocketChat.saveRoomType = (rid, roomType) ->
+	unless Match.test rid, String
+		throw new Meteor.Error 'invalid-rid'
+
+	if roomType not in ['c', 'p']
+		throw new Meteor.Error 'invalid-room-type', 'Invalid_room_type', { roomType: roomType }
+
+	return RocketChat.models.Rooms.setTypeById(rid, roomType) and RocketChat.models.Subscriptions.updateTypeByRoomId(rid, roomType)
diff --git a/packages/rocketchat-channel-settings/server/methods/saveRoomSettings.coffee b/packages/rocketchat-channel-settings/server/methods/saveRoomSettings.coffee
index 6375bf5f289180ce9e3732a313febb8522c65e56..2b4d8f95e7873e0de8bd02eccbcc18bd4add98e0 100644
--- a/packages/rocketchat-channel-settings/server/methods/saveRoomSettings.coffee
+++ b/packages/rocketchat-channel-settings/server/methods/saveRoomSettings.coffee
@@ -1,26 +1,31 @@
 Meteor.methods
-	saveRoomSettings: (rid, settings) ->
-		console.log '[method] saveRoomSettings'.green, rid, settings
-
+	saveRoomSettings: (rid, setting, value) ->
 		unless Match.test rid, String
-			throw new Meteor.Error 'invalid-rid'
+			throw new Meteor.Error 'invalid-rid', 'Invalid room'
 
-		unless Match.test settings, Match.ObjectIncluding { roomType: String }
-			throw new Meteor.Error 'invalid-settings'
+		if setting not in ['roomName', 'roomTopic', 'roomType']
+			throw new Meteor.Error 'invalid-settings', 'Invalid settings provided'
 
 		unless RocketChat.authz.hasPermission(Meteor.userId(), 'edit-room', rid)
 			throw new Meteor.Error 503, 'Not authorized'
 
 		room = RocketChat.models.Rooms.findOneById rid
 		if room?
-			if settings.roomType isnt room.t
-				RocketChat.changeRoomType(rid, settings.roomType)
-
-				if settings.roomType is 'c'
-					message = TAPi18n.__('Channel')
-				else
-					message = TAPi18n.__('Private_Group')
-
-				RocketChat.models.Messages.createRoomSettingsChangedWithTypeRoomIdMessageAndUser 'room_changed_privacy', rid, message, Meteor.user()
+			switch setting
+				when 'roomName'
+					name = RocketChat.saveRoomName rid, value
+					RocketChat.models.Messages.createRoomRenamedWithRoomIdRoomNameAndUser rid, name, Meteor.user()
+				when 'roomTopic'
+					if value isnt room.topic
+						RocketChat.saveRoomTopic(rid, value)
+						RocketChat.models.Messages.createRoomSettingsChangedWithTypeRoomIdMessageAndUser 'room_changed_topic', rid, value, Meteor.user()
+				when 'roomType'
+					if value isnt room.t
+						RocketChat.saveRoomType(rid, value)
+						if value is 'c'
+							message = TAPi18n.__('Channel')
+						else
+							message = TAPi18n.__('Private_Group')
+						RocketChat.models.Messages.createRoomSettingsChangedWithTypeRoomIdMessageAndUser 'room_changed_privacy', rid, message, Meteor.user()
 
 		return true
diff --git a/packages/rocketchat-channel-settings/server/models/Messages.coffee b/packages/rocketchat-channel-settings/server/models/Messages.coffee
index 0a8e900e45d40835d506b73c468240b2d9208a8c..9a72fcd32bb0dbabffc7287513ba36505240a9fa 100644
--- a/packages/rocketchat-channel-settings/server/models/Messages.coffee
+++ b/packages/rocketchat-channel-settings/server/models/Messages.coffee
@@ -1,2 +1,5 @@
 RocketChat.models.Messages.createRoomSettingsChangedWithTypeRoomIdMessageAndUser = (type, roomId, message, user, extraData) ->
 	return @createWithTypeRoomIdMessageAndUser type, roomId, message, user, extraData
+
+RocketChat.models.Messages.createRoomRenamedWithRoomIdRoomNameAndUser = (roomId, roomName, user, extraData) ->
+	return @createWithTypeRoomIdMessageAndUser 'r', roomId, roomName, user, extraData
diff --git a/packages/rocketchat-chatops/client/tabBar.coffee b/packages/rocketchat-chatops/client/tabBar.coffee
index 5daff0a8915cdbaf5a5ad42b1e2ef07df2d92794..c6e65f4895a7a7324019b30f03e47d2d9b7539b8 100644
--- a/packages/rocketchat-chatops/client/tabBar.coffee
+++ b/packages/rocketchat-chatops/client/tabBar.coffee
@@ -1,18 +1,9 @@
 Meteor.startup ->
-
-	RocketChat.callbacks.add 'enter-room', ->
-		#if Meteor.user()?.services?.github?.id or Meteor.user()?.services?.gitlab?.id
-		# console.log 'Adding chatops to tabbar'
-		# RocketChat.TabBar.addButton
-		# 	id: 'chatops-button'
-		# 	i18nTitle: 'rocketchat-chatops:Chatops_Title'
-		# 	icon: 'icon-code'
-		# 	template: 'chatops'
-		# 	order: 4
-
+	Tracker.autorun ->
 		if RocketChat.settings.get('Chatops_Enabled')
 			console.log 'Adding chatops to tabbar'
 			RocketChat.TabBar.addButton
+				groups: ['channel', 'privategroup', 'directmessage']
 				id: 'chatops-button2'
 				i18nTitle: 'rocketchat-chatops:Chatops_Title'
 				icon: 'octicon octicon-hubot'
@@ -21,10 +12,13 @@ Meteor.startup ->
 
 			console.log 'Adding chatops to tabbar'
 			RocketChat.TabBar.addButton
+				groups: ['channel', 'privategroup', 'directmessage']
 				id: 'chatops-button3'
 				i18nTitle: 'rocketchat-chatops:Chatops_Title'
 				icon: 'octicon octicon-inbox'
 				template: 'chatops_droneflight'
 				width: 675
 				order: 5
-	, RocketChat.callbacks.priority.MEDIUM, 'enter-room-tabbar-chatops'
+		else
+			RocketChat.TabBar.removeButton 'chatops-button2'
+			RocketChat.TabBar.removeButton 'chatops-button3'
diff --git a/packages/rocketchat-chatops/i18n/de.i18n.json b/packages/rocketchat-chatops/i18n/de.i18n.json
index 92a7ee53ca898e035c2156f30738da47bb329274..0bb37873b18de0c319cfcd3ea1c5399359385822 100644
--- a/packages/rocketchat-chatops/i18n/de.i18n.json
+++ b/packages/rocketchat-chatops/i18n/de.i18n.json
@@ -1,4 +1,5 @@
 {
-  "Chatops_Enabled" : "Chatops aktivieren",
-  "Chatops_Username" : "Chatops Benutzername"
+  "Chatops_Enabled" : "ChatOps aktivieren",
+  "Chatops_Title" : "ChatOps-Panel",
+  "Chatops_Username" : "ChatOps-Benutzername"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-chatops/i18n/fr.i18n.json b/packages/rocketchat-chatops/i18n/fr.i18n.json
index 36d9014b31a06258d4c0d4e00eb925a754ef3644..c504b432ac9b0092462b82e5054abbd6433179d8 100644
--- a/packages/rocketchat-chatops/i18n/fr.i18n.json
+++ b/packages/rocketchat-chatops/i18n/fr.i18n.json
@@ -1,4 +1,5 @@
 {
   "Chatops_Enabled" : "Activer Chatops",
-  "Chatops_Title" : "Panneau de contrôle des Chatops"
+  "Chatops_Title" : "Panneau de contrôle des Chatops",
+  "Chatops_Username" : "Nom d'utilisateur Chatops"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-chatops/i18n/ko.i18n.json b/packages/rocketchat-chatops/i18n/ko.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..8d0449b61f8563070a47a52da0d6f45dd3ebb24c 100644
--- a/packages/rocketchat-chatops/i18n/ko.i18n.json
+++ b/packages/rocketchat-chatops/i18n/ko.i18n.json
@@ -1 +1,5 @@
-{ }
\ No newline at end of file
+{
+  "Chatops_Enabled" : "Cahtops 사용",
+  "Chatops_Title" : "Chatops 패널",
+  "Chatops_Username" : "Chatops 사용자 이름"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-chatops/i18n/nl.i18n.json b/packages/rocketchat-chatops/i18n/nl.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..c4049dda949957b2d3f2c23f6145115aa762c3d9 100644
--- a/packages/rocketchat-chatops/i18n/nl.i18n.json
+++ b/packages/rocketchat-chatops/i18n/nl.i18n.json
@@ -1 +1,5 @@
-{ }
\ No newline at end of file
+{
+  "Chatops_Enabled" : "Chatops Inschakelen",
+  "Chatops_Title" : "Chatops Panel",
+  "Chatops_Username" : "Chatops Gebruikersnaam"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-chatops/i18n/ro.i18n.json b/packages/rocketchat-chatops/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..62627119a9f934a79a984925609d4aa1c3338b7a
--- /dev/null
+++ b/packages/rocketchat-chatops/i18n/ro.i18n.json
@@ -0,0 +1,5 @@
+{
+  "Chatops_Enabled" : "Activați Chatops",
+  "Chatops_Title" : "Chatops Panel",
+  "Chatops_Username" : "Nume de ultilizator Chatops"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-chatops/i18n/sr.i18n.json b/packages/rocketchat-chatops/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-chatops/i18n/sr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-chatops/package.js b/packages/rocketchat-chatops/package.js
index 2b8585bce635164996c91a9f81b676c173c766c2..17a2828094504fcc5e3cf832122c2bc5296ac83e 100644
--- a/packages/rocketchat-chatops/package.js
+++ b/packages/rocketchat-chatops/package.js
@@ -10,7 +10,7 @@ Package.onUse(function(api) {
 
 	api.use([
 		'coffeescript',
-		'rocketchat:lib@0.0.1',
+		'rocketchat:lib',
 		'dburles:google-maps@1.1.5'
 	]);
 
@@ -23,8 +23,7 @@ Package.onUse(function(api) {
 			return 'i18n/' + filename;
 		}
 	}));
-	api.use(["tap:i18n@1.5.1"], ["client", "server"]);
-	api.imply('tap:i18n');
+	api.use('tap:i18n');
 	api.addFiles("package-tap.i18n", ["client", "server"]);
 
 	api.addFiles([
@@ -45,7 +44,7 @@ Package.onUse(function(api) {
 	], 'server');
 
 	// TAPi18n -- needs to be added last
-	api.addFiles(tapi18nFiles, ["client", "server"]);
+	api.addFiles(tapi18nFiles);
 });
 
 Package.onTest(function(api) {
diff --git a/packages/rocketchat-colors/package.js b/packages/rocketchat-colors/package.js
index 45899a9b7da18f0b359d07cab32aec230b4500ca..48b47b04ffea9b7c6f7f4ee96ab3055f10bbc4e1 100644
--- a/packages/rocketchat-colors/package.js
+++ b/packages/rocketchat-colors/package.js
@@ -10,7 +10,7 @@ Package.onUse(function(api) {
 
 	api.use([
 		'coffeescript',
-		'rocketchat:lib@0.0.1'
+		'rocketchat:lib'
 	]);
 
 	api.addFiles('client.coffee', 'client');
diff --git a/packages/rocketchat-cors/cors.coffee b/packages/rocketchat-cors/cors.coffee
index f360cd6501482360d7e914168c4f9f7b05721cd0..b7b557fbb82f5df5e639ee72987bcb3b3cc4fda1 100644
--- a/packages/rocketchat-cors/cors.coffee
+++ b/packages/rocketchat-cors/cors.coffee
@@ -1,9 +1,44 @@
 # Adding CORS headers so we can use CDNs for static content
 
+# Try to parse all request bodies as JSON
+WebApp.rawConnectHandlers.use (req, res, next) ->
+	if req._body
+		return next()
+
+	if req.headers['transfer-encoding'] is undefined and isNaN(req.headers['content-length'])
+		return next()
+
+	if req.headers['content-type'] not in ['', undefined]
+		return next()
+
+	buf = ''
+	req.setEncoding('utf8')
+	req.on 'data', (chunk) -> buf += chunk
+	req.on 'end', ->
+		if RocketChat?.debugLevel? and RocketChat.debugLevel is 'debug'
+			console.log '[request]'.green, req.method, req.url, '\nheaders ->', req.headers, '\nbody ->', buf
+
+		try
+			req.body = JSON.parse(buf)
+		catch err
+			req.body = buf
+
+		req._body = true
+		next()
+
+
 WebApp.rawConnectHandlers.use (req, res, next) ->
 	res.setHeader("Access-Control-Allow-Origin", "*")
 	res.setHeader("X-Rocket-Chat-Version", VERSION)
 	res.setHeader("Access-Control-Expose-Headers",  "X-Rocket-Chat-Version")
+
+	# Block next handlers to override CORS with value http://meteor.local
+	setHeader = res.setHeader
+	res.setHeader = (key, val) ->
+		if key.toLowerCase() is 'access-control-allow-origin' and val is 'http://meteor.local'
+			return
+		return setHeader.apply @, arguments
+
 	return next()
 
 _staticFilesMiddleware = WebAppInternals.staticFilesMiddleware
@@ -12,3 +47,42 @@ WebAppInternals._staticFilesMiddleware = (staticFiles, req, res, next) ->
 	res.setHeader("X-Rocket-Chat-Version", VERSION)
 	res.setHeader("Access-Control-Expose-Headers",  "X-Rocket-Chat-Version")
 	_staticFilesMiddleware(staticFiles, req, res, next)
+
+
+url = Npm.require("url")
+
+httpServer = WebApp.httpServer
+oldHttpServerListeners = httpServer.listeners('request').slice(0)
+httpServer.removeAllListeners('request')
+
+httpServer.addListener 'request', (req, res) ->
+	args = arguments
+	next = ->
+		for oldListener in oldHttpServerListeners
+			oldListener.apply(httpServer, args)
+
+	if RocketChat.settings.get('Force_SSL') isnt true
+		next()
+		return
+
+	remoteAddress = req.connection.remoteAddress or req.socket.remoteAddress
+
+	localhostRegexp = /^\s*(127\.0\.0\.1|::1)\s*$/
+	localhostTest = (x) ->
+		return localhostRegexp.test(x)
+
+	isLocal = localhostRegexp.test(remoteAddress) and (not req.headers['x-forwarded-for'] or _.all(req.headers['x-forwarded-for'].split(','), localhostTest))
+
+	isSsl = req.connection.pair or (req.headers['x-forwarded-proto'] and req.headers['x-forwarded-proto'].indexOf('https') isnt -1)
+
+	if not isLocal and not isSsl
+		host = req.headers['host'] or url.parse(Meteor.absoluteUrl()).hostname
+
+		host = host.replace(/:\d+$/, '')
+
+		res.writeHead 302,
+			'Location': 'https://' + host + req.url
+		res.end()
+		return
+
+	next()
diff --git a/packages/rocketchat-emojione/package.js b/packages/rocketchat-emojione/package.js
index 761d9d0ff8753afae6e5f894bc2e8dee6ceb5d00..a89c2d31b66a7724901cdb9ff1527ff0d7026084 100644
--- a/packages/rocketchat-emojione/package.js
+++ b/packages/rocketchat-emojione/package.js
@@ -11,7 +11,7 @@ Package.onUse(function(api) {
 	api.use([
 		'coffeescript',
 		'emojione:emojione',
-		'rocketchat:lib@0.0.1'
+		'rocketchat:lib'
 	]);
 
 	api.addFiles('emojione.coffee', ['server','client']);
diff --git a/packages/rocketchat-file/file.server.coffee b/packages/rocketchat-file/file.server.coffee
index 00aa21319db99271c07db37013a2836cf57b02d1..b974aff0ba499b0a3a8e62db2ec684a593628aaa 100644
--- a/packages/rocketchat-file/file.server.coffee
+++ b/packages/rocketchat-file/file.server.coffee
@@ -4,12 +4,58 @@ fs = Npm.require('fs')
 path = Npm.require('path')
 mkdirp = Npm.require('mkdirp')
 gm = Npm.require('gm')
+exec = Npm.require('child_process').exec
 
 # Fix problem with usernames being converted to object id
 Grid.prototype.tryParseObjectId = -> false
 
 RocketChatFile =
 	gm: gm
+	enabled: undefined
+	enable: ->
+		RocketChatFile.enabled = true
+		RocketChat.settings.updateOptionsById 'Accounts_AvatarResize', {alert: undefined}
+	disable: ->
+		RocketChatFile.enabled = false
+		RocketChat.settings.updateOptionsById 'Accounts_AvatarResize', {alert: 'The_image_resize_will_not_work_because_we_can_not_detect_ImageMagick_or_GraphicsMagick_installed_in_your_server'}
+
+
+detectGM = ->
+	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 =
+					enabled: true
+					version: stdout
+			else
+				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-file/package.js b/packages/rocketchat-file/package.js
index 7ed4a9d40ff39550d4d451c9ac218b5ca5e93012..4efed24a52bd07e1f774fe234307931e42dc5c51 100644
--- a/packages/rocketchat-file/package.js
+++ b/packages/rocketchat-file/package.js
@@ -8,11 +8,13 @@ Package.describe({
 Package.onUse(function(api) {
 	api.versionsFrom('1.0');
 
-	api.use(['coffeescript']);
+	api.use('rocketchat:lib');
+	api.use('rocketchat:version');
+	api.use('coffeescript');
 
-	api.addFiles('file.server.coffee', ['server']);
+	api.addFiles('file.server.coffee', 'server');
 
-	api.export(['RocketChatFile'], ['server']);
+	api.export('RocketChatFile', 'server');
 });
 
 Npm.depends({
diff --git a/packages/rocketchat-github-enterprise/i18n/ar.i18n.json b/packages/rocketchat-github-enterprise/i18n/ar.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..16216ec3e867f35f1f5c4938426f50a7d6a57d06 100644
--- a/packages/rocketchat-github-enterprise/i18n/ar.i18n.json
+++ b/packages/rocketchat-github-enterprise/i18n/ar.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Github_Enterprise_Url_No_Trail" : "مثال: http://domain.com (باستثناء زائدة مائل)"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-github-enterprise/i18n/de.i18n.json b/packages/rocketchat-github-enterprise/i18n/de.i18n.json
index 22bde54918df56bffe2a74ba84e20aaa15543b54..aecb8bb77fc6c7a00ae49695ac963903b4975f6e 100644
--- a/packages/rocketchat-github-enterprise/i18n/de.i18n.json
+++ b/packages/rocketchat-github-enterprise/i18n/de.i18n.json
@@ -1,7 +1,7 @@
 {
-  "Accounts_OAuth_GitHub_Enterprise" : "OAuth aktiviert",
-  "API_GitHub_Enterprise_URL" : "GitHub Enterprise",
+  "Accounts_OAuth_GitHub_Enterprise" : "OAuth aktivieren",
+  "API_GitHub_Enterprise_URL" : "Server-URL",
   "Accounts_OAuth_GitHub_Enterprise_id" : "Client-ID",
-  "Accounts_OAuth_GitHub_Enterprise_secret" : "Client Secret",
-  "Github_Enterprise_Url_No_Trail" : "Beispiel: http://domain.com (ohne Schrägstrich)"
+  "Accounts_OAuth_GitHub_Enterprise_secret" : "Client-Secret",
+  "Github_Enterprise_Url_No_Trail" : "Beispiel: http://domain.com (ohne Schrägstrich am Ende)"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-github-enterprise/i18n/fr.i18n.json b/packages/rocketchat-github-enterprise/i18n/fr.i18n.json
index 06dd996c99c061aa3c02f3520b909ab4d0619fe2..dfaef650cc119f54b0f8ea74b933ca0f0d7c858f 100644
--- a/packages/rocketchat-github-enterprise/i18n/fr.i18n.json
+++ b/packages/rocketchat-github-enterprise/i18n/fr.i18n.json
@@ -1,3 +1,6 @@
 {
-  "API_GitHub_Enterprise_URL" : "GitHub Enterprise"
+  "Accounts_OAuth_GitHub_Enterprise" : "OAuth activé",
+  "API_GitHub_Enterprise_URL" : "URL du serveur",
+  "Accounts_OAuth_GitHub_Enterprise_id" : "ID client",
+  "Github_Enterprise_Url_No_Trail" : "Exemple: http://domain.com (sans slash final)"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-github-enterprise/i18n/ko.i18n.json b/packages/rocketchat-github-enterprise/i18n/ko.i18n.json
index bf2ee2cce6ab419414cf43f438b6af95061eecf4..29d25e822d56b469a7fa5e2cdb994eebe5dea4cf 100644
--- a/packages/rocketchat-github-enterprise/i18n/ko.i18n.json
+++ b/packages/rocketchat-github-enterprise/i18n/ko.i18n.json
@@ -1,4 +1,7 @@
 {
-  "API_GitHub_Enterprise_URL" : "GitHub Enterprise",
+  "Accounts_OAuth_GitHub_Enterprise" : "OAuth 활성화",
+  "API_GitHub_Enterprise_URL" : "Server URL",
+  "Accounts_OAuth_GitHub_Enterprise_id" : "Client ID",
+  "Accounts_OAuth_GitHub_Enterprise_secret" : "Client 암호",
   "Github_Enterprise_Url_No_Trail" : "예: http://domain.com (마지막 슬래시 제외)"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-github-enterprise/i18n/nl.i18n.json b/packages/rocketchat-github-enterprise/i18n/nl.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..1163d7a6d0b518013569b6bda53af05061743756 100644
--- a/packages/rocketchat-github-enterprise/i18n/nl.i18n.json
+++ b/packages/rocketchat-github-enterprise/i18n/nl.i18n.json
@@ -1 +1,7 @@
-{ }
\ No newline at end of file
+{
+  "Accounts_OAuth_GitHub_Enterprise" : "OAuth Ingeschakeld",
+  "API_GitHub_Enterprise_URL" : "Server URL",
+  "Accounts_OAuth_GitHub_Enterprise_id" : "Client Id",
+  "Accounts_OAuth_GitHub_Enterprise_secret" : "Client Secret",
+  "Github_Enterprise_Url_No_Trail" : "Voorbeeld: http://domain.com (exclusief slash)"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-github-enterprise/i18n/ro.i18n.json b/packages/rocketchat-github-enterprise/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..f685667cfd40ce637679005fb697571dda29d4bb
--- /dev/null
+++ b/packages/rocketchat-github-enterprise/i18n/ro.i18n.json
@@ -0,0 +1,7 @@
+{
+  "Accounts_OAuth_GitHub_Enterprise" : "OAuth Activat",
+  "API_GitHub_Enterprise_URL" : "URL-ul serverului",
+  "Accounts_OAuth_GitHub_Enterprise_id" : "Client ID",
+  "Accounts_OAuth_GitHub_Enterprise_secret" : "Client Secret",
+  "Github_Enterprise_Url_No_Trail" : "Exemplu: http://domain.com (fără '/' la final)"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-github-enterprise/i18n/ru.i18n.json b/packages/rocketchat-github-enterprise/i18n/ru.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..d3a57474db49292f4f4a9608b770f401d6cd2413 100644
--- a/packages/rocketchat-github-enterprise/i18n/ru.i18n.json
+++ b/packages/rocketchat-github-enterprise/i18n/ru.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Accounts_OAuth_GitHub_Enterprise" : "OAuth включен"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-github-enterprise/i18n/sr.i18n.json b/packages/rocketchat-github-enterprise/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-github-enterprise/i18n/sr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-github-enterprise/package.js b/packages/rocketchat-github-enterprise/package.js
index cca18ff40e338f42fad8a6cc3b8feab427283fa6..cbb6321723bb063387b2cc0f5d5be5c073ef37a4 100644
--- a/packages/rocketchat-github-enterprise/package.js
+++ b/packages/rocketchat-github-enterprise/package.js
@@ -8,14 +8,14 @@ Package.onUse(function(api) {
     api.versionsFrom('1.0');
 
     api.use('coffeescript');
-    api.use('rocketchat:lib@0.0.1');
+    api.use('rocketchat:lib');
     api.use('rocketchat:custom-oauth');
 
     api.addFiles('startup.coffee', 'server');
     api.addFiles('github-enterprise-login-button.css', 'client');
     api.addFiles('common.coffee');
 
-	// TAPi18n
+    // TAPi18n
     api.use('templating', 'client');
     var _ = Npm.require('underscore');
     var fs = Npm.require('fs');
@@ -24,9 +24,8 @@ Package.onUse(function(api) {
             return 'i18n/' + filename;
         }
     }));
-    api.use('tap:i18n@1.6.1', ['client', 'server']);
-    api.imply('tap:i18n');
-    api.addFiles(tapi18nFiles, ['client', 'server']);
+    api.use('tap:i18n');
+    api.addFiles(tapi18nFiles);
 
 });
 
diff --git a/packages/rocketchat-gitlab/i18n/de.i18n.json b/packages/rocketchat-gitlab/i18n/de.i18n.json
index ce7e0675b85ead87704432aa7c33ef23e85d788a..3e6c591d6961e9c73b7401bcf1999efc2e5a5aaf 100644
--- a/packages/rocketchat-gitlab/i18n/de.i18n.json
+++ b/packages/rocketchat-gitlab/i18n/de.i18n.json
@@ -1,3 +1,3 @@
 {
-  "API_Gitlab_URL" : "Git"
+  "API_Gitlab_URL" : "GitLab-URL"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-gitlab/i18n/ro.i18n.json b/packages/rocketchat-gitlab/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..aa29615cd108029974531adf38285605c00aeacb
--- /dev/null
+++ b/packages/rocketchat-gitlab/i18n/ro.i18n.json
@@ -0,0 +1,3 @@
+{
+  "API_Gitlab_URL" : "GitLab URL"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-gitlab/i18n/sr.i18n.json b/packages/rocketchat-gitlab/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-gitlab/i18n/sr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-gitlab/package.js b/packages/rocketchat-gitlab/package.js
index c8a0e62d3a8da2d1b7faf49d77b275c251f96c4d..8e1b7250e60e7377ae994fd90fd1a144fe78739c 100644
--- a/packages/rocketchat-gitlab/package.js
+++ b/packages/rocketchat-gitlab/package.js
@@ -8,7 +8,7 @@ Package.onUse(function(api) {
     api.versionsFrom('1.0');
 
     api.use('coffeescript');
-    api.use('rocketchat:lib@0.0.1');
+    api.use('rocketchat:lib');
     api.use('rocketchat:custom-oauth');
 
     api.addFiles("common.coffee");
@@ -24,9 +24,8 @@ Package.onUse(function(api) {
             return 'i18n/' + filename;
         }
     }));
-    api.use('tap:i18n@1.6.1', ['client', 'server']);
-    api.imply('tap:i18n');
-    api.addFiles(tapi18nFiles, ['client', 'server']);
+    api.use('tap:i18n');
+    api.addFiles(tapi18nFiles);
 });
 
 Package.onTest(function(api) {
diff --git a/packages/rocketchat-highlight/highlight.coffee b/packages/rocketchat-highlight/highlight.coffee
index c98270151ae158ae6bed9c622e2eb7c684b33e58..57944340bcdd13626f59043605de4047084eb5f6 100644
--- a/packages/rocketchat-highlight/highlight.coffee
+++ b/packages/rocketchat-highlight/highlight.coffee
@@ -8,6 +8,7 @@ class Highlight
 	constructor: (message) ->
 
 		if s.trim message.html
+			message.tokens ?= []
 
 			# Count occurencies of ```
 			count = (message.html.match(/```/g) || []).length
@@ -40,7 +41,15 @@ class Highlight
 							result = hljs.highlightAuto code
 						else
 							result = hljs.highlight lang, code
-						msgParts[index] = "<pre><code class='hljs " + result.language + "'><span class='copyonly'>```<br></span>" + result.value + "<span class='copyonly'><br>```</span></code></pre>"
+
+						token = "$#{Random.id()}$"
+
+						message.tokens.push
+							highlight: true
+							token: token
+							text: "<pre><code class='hljs " + result.language + "'><span class='copyonly'>```<br></span>" + result.value + "<span class='copyonly'><br>```</span></code></pre>"
+
+						msgParts[index] = token
 					else
 						msgParts[index] = part
 
diff --git a/packages/rocketchat-highlight/package.js b/packages/rocketchat-highlight/package.js
index a8587bff10e4d8c2ea192cbf807d5f445f8ab894..40c87c3567127f8d31ec7c8f0b289495538005a6 100644
--- a/packages/rocketchat-highlight/package.js
+++ b/packages/rocketchat-highlight/package.js
@@ -11,7 +11,7 @@ Package.onUse(function(api) {
 	api.use([
 		'coffeescript',
 		'simple:highlight.js',
-		'rocketchat:lib@0.0.1'
+		'rocketchat:lib'
 	]);
 
 	api.addFiles('highlight.coffee', ['server','client']);
diff --git a/packages/rocketchat-hubot/i18n/de.i18n.json b/packages/rocketchat-hubot/i18n/de.i18n.json
index e077ae8144f46dd433d8ac9da10cbae0e3d51bf5..a840ae5c5dbda7844ee08ee03de522581a9db4e3 100644
--- a/packages/rocketchat-hubot/i18n/de.i18n.json
+++ b/packages/rocketchat-hubot/i18n/de.i18n.json
@@ -1,5 +1,5 @@
 {
-  "RocketBot_Enabled" : "RocketBot aktivieren",
-  "RocketBot_Name" : "RocketBot Name",
-  "RocketBot_Name_Description" : "RocketBot Name muss einen registrierten Benutzernamen auf dem Server haben."
+  "RocketBot_Enabled" : "RocketBot aktiviert",
+  "RocketBot_Name" : "Name des RocketBots",
+  "RocketBot_Name_Description" : "Der Name des RocketBots muss den Namen eines registrierten Benutzers auf dem Server besitzen."
 }
\ No newline at end of file
diff --git a/packages/rocketchat-hubot/i18n/nl.i18n.json b/packages/rocketchat-hubot/i18n/nl.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..4c365fdd09d5b8c8aa2e26229e151eda2bfc2a13 100644
--- a/packages/rocketchat-hubot/i18n/nl.i18n.json
+++ b/packages/rocketchat-hubot/i18n/nl.i18n.json
@@ -1 +1,5 @@
-{ }
\ No newline at end of file
+{
+  "RocketBot_Enabled" : "RocketBot Ingeschakeld",
+  "RocketBot_Name" : "RocketBot Naam",
+  "RocketBot_Name_Description" : "RocketBot naam moet een geldige gebruikersnaam zijn op uw server."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-hubot/i18n/ro.i18n.json b/packages/rocketchat-hubot/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..473424bfab99513383223c60c11d5e100c93ddf8
--- /dev/null
+++ b/packages/rocketchat-hubot/i18n/ro.i18n.json
@@ -0,0 +1,5 @@
+{
+  "RocketBot_Enabled" : "RocketBot Activat",
+  "RocketBot_Name" : "Nume RocketBot",
+  "RocketBot_Name_Description" : "Numele RocketBot trebuie să fie un nume de utilizator valid înregistrat pe server."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-hubot/i18n/ru.i18n.json b/packages/rocketchat-hubot/i18n/ru.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..48f9516bddb851eb1549359f481911735f9f0aff 100644
--- a/packages/rocketchat-hubot/i18n/ru.i18n.json
+++ b/packages/rocketchat-hubot/i18n/ru.i18n.json
@@ -1 +1,5 @@
-{ }
\ No newline at end of file
+{
+  "RocketBot_Enabled" : "RocketBot включен",
+  "RocketBot_Name" : "Имя RocketBot-а",
+  "RocketBot_Name_Description" : "Имя RocketBot должно быть действительным именем пользователя зарегистрированным на вашем сервере."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-hubot/i18n/sr.i18n.json b/packages/rocketchat-hubot/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-hubot/i18n/sr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-hubot/package.js b/packages/rocketchat-hubot/package.js
index 62d91694a3fd877f3ca269e2eaae2ee6fff1c8c6..55074e51a4848746345befe54e7e9044db779dc3 100644
--- a/packages/rocketchat-hubot/package.js
+++ b/packages/rocketchat-hubot/package.js
@@ -11,7 +11,7 @@ Package.onUse(function(api) {
 	api.use([
 		'coffeescript',
 		'tracker',
-		'rocketchat:lib@0.0.1'
+		'rocketchat:lib'
 	]);
 
 	api.addFiles([
@@ -28,9 +28,8 @@ Package.onUse(function(api) {
 			return 'i18n/' + filename;
 		}
 	}));
-	api.use('tap:i18n@1.6.1', ['client', 'server']);
-	api.imply('tap:i18n');
-	api.addFiles(tapi18nFiles, ['client', 'server']);
+	api.use('tap:i18n');
+	api.addFiles(tapi18nFiles);
 
 	api.export('Hubot', ['server']);
 	api.export('HubotScripts', ['server']);
diff --git a/packages/rocketchat-integrations/client/route.coffee b/packages/rocketchat-integrations/client/route.coffee
index 4a87624ca342cf6c04ad4ca88d3d1d33c291f9ad..c5c6311d662191fb29693c9936d14b776df89d2f 100644
--- a/packages/rocketchat-integrations/client/route.coffee
+++ b/packages/rocketchat-integrations/client/route.coffee
@@ -1,26 +1,37 @@
 FlowRouter.route '/admin/integrations',
 	name: 'admin-integrations'
 	action: (params) ->
+		RocketChat.TabBar.showGroup 'admin-integrations'
 		BlazeLayout.render 'main',
 			center: 'pageSettingsContainer'
 			pageTitle: t('Integrations')
 			pageTemplate: 'integrations'
 
-
 FlowRouter.route '/admin/integrations/new',
 	name: 'admin-integrations-new'
 	action: (params) ->
+		RocketChat.TabBar.showGroup 'admin-integrations'
 		BlazeLayout.render 'main',
 			center: 'pageSettingsContainer'
 			pageTitle: t('Integration_New')
 			pageTemplate: 'integrationsNew'
 
-
 FlowRouter.route '/admin/integrations/incoming/:id?',
 	name: 'admin-integrations-incoming'
 	action: (params) ->
+		RocketChat.TabBar.showGroup 'admin-integrations'
 		BlazeLayout.render 'main',
 			center: 'pageSettingsContainer'
 			pageTitle: t('Integration_Incoming_WebHook')
 			pageTemplate: 'integrationsIncoming'
 			params: params
+
+FlowRouter.route '/admin/integrations/outgoing/:id?',
+	name: 'admin-integrations-outgoing'
+	action: (params) ->
+		RocketChat.TabBar.showGroup 'admin-integrations'
+		BlazeLayout.render 'main',
+			center: 'pageSettingsContainer'
+			pageTitle: t('Integration_Outgoing_WebHook')
+			pageTemplate: 'integrationsOutgoing'
+			params: params
diff --git a/packages/rocketchat-integrations/client/views/integrations.html b/packages/rocketchat-integrations/client/views/integrations.html
index d1075af7756bea42043c72e9c7769fcfca3a82c3..52f196b1c8b25055769d996bdac25db78a90f03b 100644
--- a/packages/rocketchat-integrations/client/views/integrations.html
+++ b/packages/rocketchat-integrations/client/views/integrations.html
@@ -7,25 +7,45 @@
 				<div class="section">
 					<div class="admin-integrations-new-panel">
 						{{#each integrations}}
-							<a href="{{pathFor "admin-integrations-incoming" id=_id}}">
-								<div class="admin-integrations-new-item">
-									<i class="icon-login"></i>
-									<div class="admin-integrations-new-item-body">
-										<div class="admin-integrations-new-item-title">
-											Incoming WebHook {{#if name}}- {{name}}{{/if}}
-										</div>
-										<div class="admin-integrations-new-item-description">
-											{{{_ "Post_to_s_as_s" channel username}}}
-										</div>
-										<div class="admin-integrations-new-item-description">
-											{{{_ "Created_at_s_by_s" (dateFormated _createdAt) _createdBy.username}}}
+							{{#if $eq type 'webhook-incoming'}}
+								<a href="{{pathFor "admin-integrations-incoming" id=_id}}">
+									<div class="admin-integrations-new-item">
+										<i class="icon-login"></i>
+										<div class="admin-integrations-new-item-body">
+											<div class="admin-integrations-new-item-title">
+												Incoming WebHook {{#if name}}- {{name}}{{/if}}
+											</div>
+											<div class="admin-integrations-new-item-description">
+												{{{_ "Post_to_s_as_s" channel username}}}
+											</div>
+											<div class="admin-integrations-new-item-description">
+												{{{_ "Created_at_s_by_s" (dateFormated _createdAt) _createdBy.username}}}
+											</div>
 										</div>
+										<i class="icon-angle-right"></i>
 									</div>
-									<i class="icon-angle-right"></i>
-								</div>
-							</a>
+								</a>
+							{{/if}}
 						{{else}}
-							<h1>{{_ "There_is_no_integrations"}}</h1>
+							<h1>{{_ "There_are_no_integrations"}}</h1>
+						{{/each}}
+						{{#each integrations}}
+							{{#if $eq type 'webhook-outgoing'}}
+								<a href="{{pathFor "admin-integrations-outgoing" id=_id}}">
+									<div class="admin-integrations-new-item">
+										<i class="icon-login"></i>
+										<div class="admin-integrations-new-item-body">
+											<div class="admin-integrations-new-item-title">
+												Outgoing WebHook {{#if name}}- {{name}}{{/if}}
+											</div>
+											<div class="admin-integrations-new-item-description">
+												{{{_ "Created_at_s_by_s" (dateFormated _createdAt) _createdBy.username}}}
+											</div>
+										</div>
+										<i class="icon-angle-right"></i>
+									</div>
+								</a>
+							{{/if}}
 						{{/each}}
 					</div>
 				</div>
diff --git a/packages/rocketchat-integrations/client/views/integrationsIncoming.coffee b/packages/rocketchat-integrations/client/views/integrationsIncoming.coffee
index 28f19b530c6fc814be9e694497cf604ce77b791c..8e8f09dd0e121955c49edac78546f7a2a3653984 100644
--- a/packages/rocketchat-integrations/client/views/integrationsIncoming.coffee
+++ b/packages/rocketchat-integrations/client/views/integrationsIncoming.coffee
@@ -15,6 +15,7 @@ Template.integrationsIncoming.helpers
 			data = ChatIntegrations.findOne({_id: params.id})
 			if data?
 				data.url = Meteor.absoluteUrl("hooks/#{encodeURIComponent(data._id)}/#{encodeURIComponent(data.userId)}/#{encodeURIComponent(data.token)}")
+				data.completeToken = "#{encodeURIComponent(data._id)}/#{encodeURIComponent(data.userId)}/#{encodeURIComponent(data.token)}"
 				Template.instance().record.set data
 				return data
 
@@ -25,10 +26,12 @@ Template.integrationsIncoming.helpers
 		return {} =
 			_id: Random.id()
 			alias: record.alias
+			emoji: record.emoji
 			avatar: record.avatar
 			msg: 'Example message'
 			bot:
 				i: Random.id()
+			groupable: false
 			attachments: [{
 				title: "Rocket.Chat"
 				title_link: "https://rocket.chat"
@@ -41,12 +44,52 @@ Template.integrationsIncoming.helpers
 				_id: Random.id()
 				username: record.username
 
+	exampleJson: ->
+		record = Template.instance().record.get()
+		data =
+			username: record.alias
+			icon_emoji: record.emoji
+			icon_url: record.avatar
+			text: 'Example message'
+			attachments: [{
+				title: "Rocket.Chat"
+				title_link: "https://rocket.chat"
+				text: "Rocket.Chat, the best open source chat"
+				image_url: "https://rocket.chat/images/mockup.png"
+				color: "#764FA5"
+			}]
+
+		for key, value of data
+			delete data[key] if value in [null, ""]
+
+		return hljs.highlight('json', JSON.stringify(data, null, 2)).value
+
+	curl: ->
+		record = Template.instance().record.get()
+		data =
+			username: record.alias
+			icon_emoji: record.emoji
+			icon_url: record.avatar
+			text: 'Example message'
+			attachments: [{
+				title: "Rocket.Chat"
+				title_link: "https://rocket.chat"
+				text: "Rocket.Chat, the best open source chat"
+				image_url: "https://rocket.chat/images/mockup.png"
+				color: "#764FA5"
+			}]
+
+		for key, value of data
+			delete data[key] if value in [null, ""]
+
+		return "curl -X POST --data-urlencode 'payload=#{JSON.stringify(data)}' #{record.url}"
 
 Template.integrationsIncoming.events
 	"blur input": (e, t) ->
 		t.record.set
 			name: $('[name=name]').val().trim()
 			alias: $('[name=alias]').val().trim()
+			emoji: $('[name=emoji]').val().trim()
 			avatar: $('[name=avatar]').val().trim()
 			channel: $('[name=channel]').val().trim()
 			username: $('[name=username]').val().trim()
@@ -65,7 +108,7 @@ Template.integrationsIncoming.events
 			closeOnConfirm: false
 			html: false
 		, ->
-			Meteor.call "deleteIntegration", params.id, (err, data) ->
+			Meteor.call "deleteIncomingIntegration", params.id, (err, data) ->
 				swal
 					title: t('Deleted')
 					text: t('Your_entry_has_been_deleted')
@@ -78,6 +121,7 @@ Template.integrationsIncoming.events
 	"click .submit > .save": ->
 		name = $('[name=name]').val().trim()
 		alias = $('[name=alias]').val().trim()
+		emoji = $('[name=emoji]').val().trim()
 		avatar = $('[name=avatar]').val().trim()
 		channel = $('[name=channel]').val().trim()
 		username = $('[name=username]').val().trim()
@@ -91,21 +135,21 @@ Template.integrationsIncoming.events
 		integration =
 			channel: channel
 			alias: alias if alias isnt ''
+			emoji: emoji if emoji isnt ''
 			avatar: avatar if avatar isnt ''
 			name: name if name isnt ''
 
 		params = Template.instance().data.params?()
 		if params?.id?
-			Meteor.call "updateIntegration", params.id, integration, (err, data) ->
+			Meteor.call "updateIncomingIntegration", params.id, integration, (err, data) ->
 				if err?
 					return toastr.error TAPi18n.__(err.error)
 
 				toastr.success TAPi18n.__("Integration_updated")
 		else
-			integration.type = 'webhook-incoming'
 			integration.username = username
 
-			Meteor.call "addIntegration", integration, (err, data) ->
+			Meteor.call "addIncomingIntegration", integration, (err, data) ->
 				if err?
 					return toastr.error TAPi18n.__(err.error)
 
diff --git a/packages/rocketchat-integrations/client/views/integrationsIncoming.html b/packages/rocketchat-integrations/client/views/integrationsIncoming.html
index d17db30e5c5921f2f48fd17d4504ed0aca5b3aad..42ffe785ae739ea077dda73bb99564824b706449 100644
--- a/packages/rocketchat-integrations/client/views/integrationsIncoming.html
+++ b/packages/rocketchat-integrations/client/views/integrationsIncoming.html
@@ -47,16 +47,39 @@
 								<div class="settings-description">{{_ "Should_be_a_URL_of_an_image"}}</div>
 							</div>
 						</div>
+						<div class="input-line double-col">
+							<label>{{_ "Emoji"}} ({{_ "optional"}})</label>
+							<div>
+								<input type="text" name="emoji" value="{{data.emoji}}" placeholder="{{_ 'Optional'}}" />
+								<div class="settings-description">{{_ "You_can_use_an_emoji_as_avatar"}}</div>
+								<div class="settings-description">{{{_ "Example_s" ":ghost:"}}}</div>
+							</div>
+						</div>
 						{{#if data.token}}
 							<div class="input-line double-col">
 								<label>Webhook URL</label>
 								<div>
-									<input type="text" name="token" value="{{data.url}}" disabled="disabled" />
+									<input type="text" name="webhookurl" value="{{data.url}}" disabled="disabled" />
 									<div class="settings-description">{{_ "Send_your_JSON_payloads_to_this_URL"}}</div>
-									<div class="settings-description"><a href="#" class="clipboard" data-clipboard-target="[name=token]">{{_ "COPY_TO_CLIPBOARD"}}</a></div>
+									<div class="settings-description"><a href="#" class="clipboard" data-clipboard-target="[name=webhookurl]">{{_ "COPY_TO_CLIPBOARD"}}</a></div>
+								</div>
+							</div>
+							<div class="input-line double-col">
+								<label>Token</label>
+								<div>
+									<input type="text" name="completeToken" value="{{data.completeToken}}" disabled="disabled" />
+									<div class="settings-description"><a href="#" class="clipboard" data-clipboard-target="[name=completeToken]">{{_ "COPY_TO_CLIPBOARD"}}</a></div>
 								</div>
 							</div>
 						{{/if}}
+						<div class="input-line double-col">
+							<label>{{_ "Example"}}</label>
+							<div>
+								<pre><code class="hljs json json-example">{{{exampleJson}}}</code></pre>
+								<input type="text" name="curl" value="{{curl}}" disabled="disabled" />
+								<div class="settings-description"><a href="#" class="clipboard" data-clipboard-target="[name=curl]">{{_ "COPY_TO_CLIPBOARD"}}</a></div>
+							</div>
+						</div>
 						<div class="input-line message-example">
 							{{#nrr nrrargs 'message' example}}{{/nrr}}
 						</div>
diff --git a/packages/rocketchat-integrations/client/views/integrationsNew.html b/packages/rocketchat-integrations/client/views/integrationsNew.html
index 496cf5112bbcaeb74bf75d498a73b9659e74b2cb..f4425ff8c3d2bb50dcb29ec6bd4b60c61fd542fd 100644
--- a/packages/rocketchat-integrations/client/views/integrationsNew.html
+++ b/packages/rocketchat-integrations/client/views/integrationsNew.html
@@ -20,7 +20,7 @@
 								<i class="icon-angle-right"></i>
 							</div>
 						</a>
-						<!-- <a href="{{pathFor "admin-integrations-incoming"}}">
+						<a href="{{pathFor "admin-integrations-outgoing"}}">
 							<div class="admin-integrations-new-item">
 								<i class="icon-logout"></i>
 								<div class="admin-integrations-new-item-body">
@@ -33,7 +33,7 @@
 								</div>
 								<i class="icon-angle-right"></i>
 							</div>
-						</a> -->
+						</a>
 					</div>
 				</div>
 			</div>
diff --git a/packages/rocketchat-integrations/client/views/integrationsOutgoing.coffee b/packages/rocketchat-integrations/client/views/integrationsOutgoing.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..2fdde6709199b5cab118591cce283062ec1ee518
--- /dev/null
+++ b/packages/rocketchat-integrations/client/views/integrationsOutgoing.coffee
@@ -0,0 +1,167 @@
+Template.integrationsOutgoing.onCreated ->
+	@record = new ReactiveVar
+		username: 'rocket.cat'
+		token: Random.id(24)
+
+
+Template.integrationsOutgoing.helpers
+
+	join: (arr, sep) ->
+		if not arr?.join?
+			return arr
+
+		return arr.join sep
+
+	hasPermission: ->
+		return RocketChat.authz.hasAllPermission 'manage-integrations'
+
+	data: ->
+		params = Template.instance().data.params?()
+
+		if params?.id?
+			data = ChatIntegrations.findOne({_id: params.id})
+			if data?
+				if not data.token?
+					data.token = Random.id(24)
+				return data
+
+		return Template.instance().record.curValue
+
+	example: ->
+		record = Template.instance().record.get()
+		return {} =
+			_id: Random.id()
+			alias: record.alias
+			emoji: record.emoji
+			avatar: record.avatar
+			msg: 'Response text'
+			bot:
+				i: Random.id()
+			groupable: false
+			attachments: [{
+				title: "Rocket.Chat"
+				title_link: "https://rocket.chat"
+				text: "Rocket.Chat, the best open source chat"
+				image_url: "https://rocket.chat/images/mockup.png"
+				color: "#764FA5"
+			}]
+			ts: new Date
+			u:
+				_id: Random.id()
+				username: record.username
+
+	exampleJson: ->
+		record = Template.instance().record.get()
+		data =
+			username: record.alias
+			icon_emoji: record.emoji
+			icon_url: record.avatar
+			text: 'Response text'
+			attachments: [{
+				title: "Rocket.Chat"
+				title_link: "https://rocket.chat"
+				text: "Rocket.Chat, the best open source chat"
+				image_url: "https://rocket.chat/images/mockup.png"
+				color: "#764FA5"
+			}]
+
+		for key, value of data
+			delete data[key] if value in [null, ""]
+
+		return hljs.highlight('json', JSON.stringify(data, null, 2)).value
+
+
+Template.integrationsOutgoing.events
+	"blur input": (e, t) ->
+		t.record.set
+			name: $('[name=name]').val().trim()
+			alias: $('[name=alias]').val().trim()
+			emoji: $('[name=emoji]').val().trim()
+			avatar: $('[name=avatar]').val().trim()
+			channel: $('[name=channel]').val().trim()
+			username: $('[name=username]').val().trim()
+			triggerWords: $('[name=triggerWords]').val().trim()
+			urls: $('[name=urls]').val().trim()
+			token: $('[name=token]').val().trim()
+
+
+	"click .submit > .delete": ->
+		params = Template.instance().data.params()
+
+		swal
+			title: t('Are_you_sure')
+			text: t('You_will_not_be_able_to_recover')
+			type: 'warning'
+			showCancelButton: true
+			confirmButtonColor: '#DD6B55'
+			confirmButtonText: t('Yes_delete_it')
+			cancelButtonText: t('Cancel')
+			closeOnConfirm: false
+			html: false
+		, ->
+			Meteor.call "deleteOutgoingIntegration", params.id, (err, data) ->
+				swal
+					title: t('Deleted')
+					text: t('Your_entry_has_been_deleted')
+					type: 'success'
+					timer: 1000
+					showConfirmButton: false
+
+				FlowRouter.go "admin-integrations"
+
+	"click .submit > .save": ->
+		name = $('[name=name]').val().trim()
+		alias = $('[name=alias]').val().trim()
+		emoji = $('[name=emoji]').val().trim()
+		avatar = $('[name=avatar]').val().trim()
+		channel = $('[name=channel]').val().trim()
+		username = $('[name=username]').val().trim()
+		triggerWords = $('[name=triggerWords]').val().trim()
+		urls = $('[name=urls]').val().trim()
+		token = $('[name=token]').val().trim()
+
+		if username is ''
+			return toastr.error TAPi18n.__("The_username_is_required")
+
+		triggerWords = triggerWords.split(',')
+		for triggerWord, index in triggerWords
+			triggerWords[index] = triggerWord.trim()
+			delete triggerWords[index] if triggerWord.trim() is ''
+
+		triggerWords = _.without triggerWords, [undefined]
+
+		urls = urls.split('\n')
+		for url, index in urls
+			urls[index] = url.trim()
+			delete urls[index] if url.trim() is ''
+
+		urls = _.without urls, [undefined]
+
+		if urls.length is 0
+			return toastr.error TAPi18n.__("You_should_inform_one_url_at_least")
+
+		integration =
+			username: username
+			channel: channel if channel isnt ''
+			alias: alias if alias isnt ''
+			emoji: emoji if emoji isnt ''
+			avatar: avatar if avatar isnt ''
+			name: name if name isnt ''
+			triggerWords: triggerWords if triggerWords isnt ''
+			urls: urls if urls isnt ''
+			token: token if token isnt ''
+
+		params = Template.instance().data.params?()
+		if params?.id?
+			Meteor.call "updateOutgoingIntegration", params.id, integration, (err, data) ->
+				if err?
+					return toastr.error TAPi18n.__(err.error)
+
+				toastr.success TAPi18n.__("Integration_updated")
+		else
+			Meteor.call "addOutgoingIntegration", integration, (err, data) ->
+				if err?
+					return toastr.error TAPi18n.__(err.error)
+
+				toastr.success TAPi18n.__("Integration_added")
+				FlowRouter.go "admin-integrations-outgoing", {id: data._id}
diff --git a/packages/rocketchat-integrations/client/views/integrationsOutgoing.html b/packages/rocketchat-integrations/client/views/integrationsOutgoing.html
new file mode 100644
index 0000000000000000000000000000000000000000..afadc8b7bbe2c06a26b212578da673dc14370bc7
--- /dev/null
+++ b/packages/rocketchat-integrations/client/views/integrationsOutgoing.html
@@ -0,0 +1,100 @@
+<template name="integrationsOutgoing">
+	<div class="permissions-manager">
+		{{#if hasPermission}}
+			<a href="{{pathFor "admin-integrations"}}"><i class="icon-angle-left"></i> {{_ "Back_to_integrations"}}</a><br><br>
+			<div class="rocket-form">
+				<div class="section">
+					<div class="section-content">
+						<div class="input-line double-col">
+							<label>{{_ "Name"}} ({{_ "optional"}})</label>
+							<div>
+								<input type="text" name="name" value="{{data.name}}" placeholder="{{_ 'Optional'}}" />
+								<div class="settings-description">{{_ "You_should_name_it_to_easily_manage_your_integrations"}}</div>
+							</div>
+						</div>
+						<div class="input-line double-col">
+							<label>{{_ "Channel"}} ({{_ "optional"}})</label>
+							<div>
+								<input type="text" name="channel" value="{{data.channel}}" placeholder="{{_ 'User_or_channel_name'}}" />
+								<div class="settings-description">{{_ "Optional channel to listen on"}}</div>
+								<div class="settings-description">{{{_ "Start_with_s_for_user_or_s_for_channel_Eg_s_or_s" "@" "#" "@john" "#general"}}}</div>
+								<div class="settings-description">{{{_ "Leave empty to listen <strong>any public channel</strong>"}}}</div>
+							</div>
+						</div>
+						<div class="input-line double-col">
+							<label>{{_ "Trigger_Words"}} ({{_ "optional"}})</label>
+							<div>
+								<input type="text" name="triggerWords" value="{{join data.triggerWords ','}}" />
+								<div class="settings-description">{{_ "When a line starts with one of these words, post to the URL(s) below"}}</div>
+								<div class="settings-description">{{_ "Separate multiple words with commas"}}</div>
+							</div>
+						</div>
+						<div class="input-line double-col">
+							<label>{{_ "URLs"}}</label>
+							<div>
+								<textarea name="urls" style="height: 100px;">{{join data.urls "\n"}}</textarea>
+								<div class="settings-description">{{_ "Enter as many URLs as you like, one per line, please"}}</div>
+							</div>
+						</div>
+						<div class="input-line double-col">
+							<label>{{_ "Post_as"}}</label>
+							<div>
+								<input type="text" name="username" value="{{data.username}}" />
+								<div class="settings-description">{{_ "Choose_the_username_that_this_integration_will_post_as"}}</div>
+								<div class="settings-description">{{_ "Should_exists_a_user_with_this_username"}}</div>
+							</div>
+						</div>
+						<div class="input-line double-col">
+							<label>{{_ "Alias"}} ({{_ "optional"}})</label>
+							<div>
+								<input type="text" name="alias" value="{{data.alias}}" placeholder="{{_ 'Optional'}}" />
+								<div class="settings-description">{{_ "Choose_the_alias_that_will_appear_before_the_username_in_messages"}}</div>
+							</div>
+						</div>
+						<div class="input-line double-col">
+							<label>{{_ "Avatar_URL"}} ({{_ "optional"}})</label>
+							<div>
+								<input type="url" name="avatar" value="{{data.avatar}}" placeholder="{{_ 'Optional'}}" />
+								<div class="settings-description">{{_ "You_can_change_a_different_avatar_too"}}</div>
+								<div class="settings-description">{{_ "Should_be_a_URL_of_an_image"}}</div>
+							</div>
+						</div>
+						<div class="input-line double-col">
+							<label>{{_ "Emoji"}} ({{_ "optional"}})</label>
+							<div>
+								<input type="text" name="emoji" value="{{data.emoji}}" placeholder="{{_ 'Optional'}}" />
+								<div class="settings-description">{{_ "You_can_use_an_emoji_as_avatar"}}</div>
+								<div class="settings-description">{{{_ "Example_s" ":ghost:"}}}</div>
+							</div>
+						</div>
+						<div class="input-line double-col">
+							<label>Token ({{_ "optional"}})</label>
+							<div>
+								<input type="text" name="token" value="{{data.token}}" />
+							</div>
+						</div>
+						<div class="input-line double-col">
+							<label>{{_ "Responding"}}</label>
+							<div>
+								<div class="settings-description">{{{_ "If the handler wishes to post a response back into the Slack channel, the following JSON should be returned as the body of the response:"}}}</div>
+								<pre><code class="hljs json json-example">{{{exampleJson}}}</code></pre>
+								<div class="settings-description">{{{_ "Empty bodies or bodies with an empty text property will simply be ignored. Non-200 responses will be retried a reasonable number of times. A response will be posted using the alias and avatar specified above. You can override these informations as in the example above."}}}</div>
+							</div>
+						</div>
+						<div class="input-line message-example">
+							{{#nrr nrrargs 'message' example}}{{/nrr}}
+						</div>
+					</div>
+				</div>
+				<div class="submit">
+					{{#if data.token}}
+						<button class="button red delete"><i class="icon-trash"></i><span>{{_ "Delete"}}</span></button>
+					{{/if}}
+					<button class="button save"><i class="icon-send"></i><span>{{_ "Save_changes"}}</span></button>
+				</div>
+			</div>
+		{{else}}
+			{{_ "Not_authorized"}}
+		{{/if}}
+	</div>
+</template>
diff --git a/packages/rocketchat-integrations/package.js b/packages/rocketchat-integrations/package.js
index ae298211d7288758f4087124a7b929e3ec1dcabf..f5ce2880e3efb0e618ea48cf4d6771662e59a9f8 100644
--- a/packages/rocketchat-integrations/package.js
+++ b/packages/rocketchat-integrations/package.js
@@ -11,7 +11,10 @@ Package.onUse(function(api) {
 
   api.use('coffeescript');
   api.use('underscore');
-  api.use('rocketchat:lib@0.0.1');
+  api.use('simple:highlight.js');
+  api.use('rocketchat:lib');
+  api.use('rocketchat:authorization');
+  api.use('rocketchat:api');
 
   api.use('kadira:flow-router', 'client');
   api.use('templating', 'client');
@@ -28,6 +31,8 @@ Package.onUse(function(api) {
   api.addFiles('client/views/integrationsNew.coffee', 'client');
   api.addFiles('client/views/integrationsIncoming.html', 'client');
   api.addFiles('client/views/integrationsIncoming.coffee', 'client');
+  api.addFiles('client/views/integrationsOutgoing.html', 'client');
+  api.addFiles('client/views/integrationsOutgoing.coffee', 'client');
 
   // stylesheets
   api.addAssets('client/stylesheets/integrations.less', 'server');
@@ -39,13 +44,21 @@ Package.onUse(function(api) {
   api.addFiles('server/publications/integrations.coffee', 'server');
 
   // methods
-  api.addFiles('server/methods/addIntegration.coffee', 'server');
-  api.addFiles('server/methods/updateIntegration.coffee', 'server');
-  api.addFiles('server/methods/deleteIntegration.coffee', 'server');
+  api.addFiles('server/methods/incoming/addIncomingIntegration.coffee', 'server');
+  api.addFiles('server/methods/incoming/updateIncomingIntegration.coffee', 'server');
+  api.addFiles('server/methods/incoming/deleteIncomingIntegration.coffee', 'server');
+  api.addFiles('server/methods/outgoing/addOutgoingIntegration.coffee', 'server');
+  api.addFiles('server/methods/outgoing/updateOutgoingIntegration.coffee', 'server');
+  api.addFiles('server/methods/outgoing/deleteOutgoingIntegration.coffee', 'server');
 
   // api
   api.addFiles('server/api/api.coffee', 'server');
 
+
+  api.addFiles('server/triggers.coffee', 'server');
+
+  api.addFiles('server/processWebhookMessage.js', 'server');
+
   var _ = Npm.require('underscore');
   var fs = Npm.require('fs');
   tapi18nFiles = _.compact(_.map(fs.readdirSync('packages/rocketchat-integrations/i18n'), function(filename) {
@@ -53,6 +66,6 @@ Package.onUse(function(api) {
       return 'i18n/' + filename;
     }
   }));
-  api.use('tap:i18n', ['client', 'server']);
-  api.addFiles(tapi18nFiles, ['client', 'server']);
+  api.use('tap:i18n');
+  api.addFiles(tapi18nFiles);
 });
diff --git a/packages/rocketchat-integrations/server/api/api.coffee b/packages/rocketchat-integrations/server/api/api.coffee
index 4001e3c09a790b0702ca3e3bb6fd0f2b4578753c..98e926b07de6cc23d0c22261d4de521fa73fa6cb 100644
--- a/packages/rocketchat-integrations/server/api/api.coffee
+++ b/packages/rocketchat-integrations/server/api/api.coffee
@@ -1,8 +1,11 @@
 Api = new Restivus
-	enableCors: false
+	enableCors: true
 	apiPath: 'hooks/'
 	auth:
 		user: ->
+			if @bodyParams?.payload?
+				@bodyParams = JSON.parse @bodyParams.payload
+
 			user = RocketChat.models.Users.findOne
 				_id: @request.params.userId
 				'services.resume.loginTokens.hashedToken': decodeURIComponent @request.params.token
@@ -12,76 +15,153 @@ Api = new Restivus
 
 Api.addRoute ':integrationId/:userId/:token', authRequired: true,
 	post: ->
-		if @bodyParams?.payload?
-			@bodyParams = JSON.parse @bodyParams.payload
+		console.log 'Post integration'
+		console.log '@urlParams', @urlParams
+		console.log '@bodyParams', @bodyParams
 
 		integration = RocketChat.models.Integrations.findOne(@urlParams.integrationId)
 		user = RocketChat.models.Users.findOne(@userId)
 
-		channel = @bodyParams.channel or integration.channel
-		channelType = channel[0]
-		channel = channel.substr(1)
-
-		switch channelType
-			when '#'
-				room = RocketChat.models.Rooms.findOne
-					$or: [
-						{_id: channel}
-						{name: channel}
-					]
-
-				if not room?
-					return {} =
-						statusCode: 400
-						body:
-							success: false
-							error: 'invalid-channel'
-
-				rid = room._id
-				Meteor.runAsUser user._id, ->
-					Meteor.call 'joinRoom', room._id
-
-			when '@'
-				roomUser = RocketChat.models.Users.findOne
-					$or: [
-						{_id: channel}
-						{username: channel}
-					]
-
-				if not roomUser?
-					return {} =
-						statusCode: 400
-						body:
-							success: false
-							error: 'invalid-channel'
-
-				rid = [user._id, roomUser._id].sort().join('')
-				room = RocketChat.models.Rooms.findOne(rid)
-
-				if not room
-					Meteor.runAsUser user._id, ->
-						Meteor.call 'createDirectMessage', roomUser._id
-						room = RocketChat.models.Rooms.findOne(rid)
-
-			else
-				return {} =
-					statusCode: 400
-					body:
-						success: false
-						error: 'invalid-channel-type'
-
-		message =
-			avatar: integration.avatar
+		@bodyParams.bot =
+			i: integration._id
+
+		defaultValues =
+			channel: integration.channel
 			alias: integration.alias
-			msg: @bodyParams.text or ''
-			attachments: @bodyParams.attachments
-			parseUrls: false
-			bot:
-				i: integration._id
+			avatar: integration.avatar
+			emoji: integration.emoji
+
+		try
+			message = processWebhookMessage @bodyParams, user, defaultValues
+
+			if not message?
+				return RocketChat.API.v1.failure 'unknown-error'
+
+			return RocketChat.API.v1.success()
+		catch e
+			return RocketChat.API.v1.failure e.error
+
+
+createIntegration = (options, user) ->
+	console.log 'Add integration'
+	console.log options
+
+	Meteor.runAsUser user._id, =>
+		switch options['event']
+			when 'newMessageOnChannel'
+				options.data ?= {}
+
+				if options.data.channel_name? and options.data.channel_name.indexOf('#') is -1
+					options.data.channel_name = '#' + options.data.channel_name
+
+				Meteor.call 'addOutgoingIntegration',
+					username: 'rocket.cat'
+					urls: [options.target_url]
+					name: options.name
+					channel: options.data.channel_name
+					triggerWords: options.data.trigger_words
+
+			when 'newMessageToUser'
+				if options.data.username.indexOf('@') is -1
+					options.data.username = '@' + options.data.username
+
+				Meteor.call 'addOutgoingIntegration',
+					username: 'rocket.cat'
+					urls: [options.target_url]
+					name: options.name
+					channel: options.data.username
+					triggerWords: options.data.trigger_words
+
+	return RocketChat.API.v1.success()
+
+
+removeIntegration = (options, user) ->
+	console.log 'Remove integration'
+	console.log options
+
+	integrationToRemove = RocketChat.models.Integrations.findOne urls: options.target_url
+	Meteor.runAsUser user._id, =>
+		Meteor.call 'deleteOutgoingIntegration', integrationToRemove._id
+
+	return RocketChat.API.v1.success()
+
+
+Api.addRoute 'add/:integrationId/:userId/:token', authRequired: true,
+	post: ->
+		integration = RocketChat.models.Integrations.findOne(@urlParams.integrationId)
 
-		RocketChat.sendMessage user, message, room, {}
+		if not integration?
+			return RocketChat.API.v1.failure 'Invalid integraiton id'
+
+		user = RocketChat.models.Users.findOne(@userId)
+
+		return createIntegration @bodyParams, user
+
+
+Api.addRoute 'remove/:integrationId/:userId/:token', authRequired: true,
+	post: ->
+		integration = RocketChat.models.Integrations.findOne(@urlParams.integrationId)
+
+		if not integration?
+			return RocketChat.API.v1.failure 'Invalid integraiton id'
+
+		user = RocketChat.models.Users.findOne(@userId)
+
+		return removeIntegration @bodyParams, user
+
+
+RocketChat.API.v1.addRoute 'integrations.create', authRequired: true,
+	post: ->
+		return createIntegration @bodyParams, @user
+
+
+RocketChat.API.v1.addRoute 'integrations.remove', authRequired: true,
+	post: ->
+		return removeIntegration @bodyParams, @user
+
+
+Api.addRoute 'sample/:integrationId/:userId/:token', authRequired: true,
+	get: ->
+		console.log 'Sample Integration'
+
+		return {} =
+			statusCode: 200
+			body: [
+				token: Random.id(24)
+				channel_id: Random.id()
+				channel_name: 'general'
+				timestamp: new Date
+				user_id: Random.id()
+				user_name: 'rocket.cat'
+				text: 'Sample text 1'
+				trigger_word: 'Sample'
+			,
+				token: Random.id(24)
+				channel_id: Random.id()
+				channel_name: 'general'
+				timestamp: new Date
+				user_id: Random.id()
+				user_name: 'rocket.cat'
+				text: 'Sample text 2'
+				trigger_word: 'Sample'
+			,
+				token: Random.id(24)
+				channel_id: Random.id()
+				channel_name: 'general'
+				timestamp: new Date
+				user_id: Random.id()
+				user_name: 'rocket.cat'
+				text: 'Sample text 3'
+				trigger_word: 'Sample'
+			]
+
+
+Api.addRoute 'info/:integrationId/:userId/:token', authRequired: true,
+	get: ->
+		console.log 'Info integration'
 
 		return {} =
 			statusCode: 200
 			body:
 				success: true
+
diff --git a/packages/rocketchat-integrations/server/methods/addIntegration.coffee b/packages/rocketchat-integrations/server/methods/incoming/addIncomingIntegration.coffee
similarity index 66%
rename from packages/rocketchat-integrations/server/methods/addIntegration.coffee
rename to packages/rocketchat-integrations/server/methods/incoming/addIncomingIntegration.coffee
index 454b87d6bd236932a6a0a2750aff7a8c475fe0bf..54efaf760064dd44e6fc5c07c564f2fc0bca3733 100644
--- a/packages/rocketchat-integrations/server/methods/addIntegration.coffee
+++ b/packages/rocketchat-integrations/server/methods/incoming/addIncomingIntegration.coffee
@@ -1,22 +1,22 @@
 Meteor.methods
-	addIntegration: (integration) ->
+	addIncomingIntegration: (integration) ->
 		if not RocketChat.authz.hasPermission @userId, 'manage-integrations'
 			throw new Meteor.Error 'not_authorized'
 
 		if not _.isString(integration.channel)
-			throw new Meteor.Error 'invalid_channel', '[methods] addIntegration -> channel must be string'
+			throw new Meteor.Error 'invalid_channel', '[methods] addIncomingIntegration -> channel must be string'
 
 		if integration.channel.trim() is ''
-			throw new Meteor.Error 'invalid_channel', '[methods] addIntegration -> channel can\'t be empty'
+			throw new Meteor.Error 'invalid_channel', '[methods] addIncomingIntegration -> channel can\'t be empty'
 
 		if integration.channel[0] not in ['@', '#']
-			throw new Meteor.Error 'invalid_channel', '[methods] addIntegration -> channel should start with # or @'
+			throw new Meteor.Error 'invalid_channel', '[methods] addIncomingIntegration -> channel should start with # or @'
 
 		if not _.isString(integration.username)
-			throw new Meteor.Error 'invalid_username', '[methods] addIntegration -> username must be string'
+			throw new Meteor.Error 'invalid_username', '[methods] addIncomingIntegration -> username must be string'
 
 		if integration.username.trim() is ''
-			throw new Meteor.Error 'invalid_username', '[methods] addIntegration -> username can\'t be empty'
+			throw new Meteor.Error 'invalid_username', '[methods] addIncomingIntegration -> username can\'t be empty'
 
 		record = undefined
 		channelType = integration.channel[0]
@@ -37,12 +37,12 @@ Meteor.methods
 					]
 
 		if record is undefined
-			throw new Meteor.Error 'channel_does_not_exists', "[methods] addIntegration -> The channel does not exists"
+			throw new Meteor.Error 'channel_does_not_exists', "[methods] addIncomingIntegration -> The channel does not exists"
 
 		user = RocketChat.models.Users.findOne({username: integration.username})
 
 		if not user?
-			throw new Meteor.Error 'user_does_not_exists', "[methods] addIntegration -> The username does not exists"
+			throw new Meteor.Error 'user_does_not_exists', "[methods] addIncomingIntegration -> The username does not exists"
 
 		stampedToken = Accounts._generateStampedLoginToken()
 		hashStampedToken = Accounts._hashStampedToken(stampedToken)
@@ -53,6 +53,7 @@ Meteor.methods
 					hashedToken: hashStampedToken.hashedToken
 					integration: true
 
+		integration.type = 'webhook-incoming'
 		integration.token = hashStampedToken.hashedToken
 		integration.userId = user._id
 		integration._createdAt = new Date
@@ -60,6 +61,8 @@ Meteor.methods
 
 		RocketChat.models.Users.update {_id: user._id}, updateObj
 
+		RocketChat.models.Roles.addUserRoles user._id, 'bot'
+
 		integration._id = RocketChat.models.Integrations.insert integration
 
 		return integration
diff --git a/packages/rocketchat-integrations/server/methods/deleteIntegration.coffee b/packages/rocketchat-integrations/server/methods/incoming/deleteIncomingIntegration.coffee
similarity index 75%
rename from packages/rocketchat-integrations/server/methods/deleteIntegration.coffee
rename to packages/rocketchat-integrations/server/methods/incoming/deleteIncomingIntegration.coffee
index d6f22c27701d26daa5f4605fb1b10315e07bfd5b..692bb014d273bbd73c344a5dbaf341aad12ee545 100644
--- a/packages/rocketchat-integrations/server/methods/deleteIntegration.coffee
+++ b/packages/rocketchat-integrations/server/methods/incoming/deleteIncomingIntegration.coffee
@@ -1,12 +1,12 @@
 Meteor.methods
-	deleteIntegration: (integrationId) ->
+	deleteIncomingIntegration: (integrationId) ->
 		if not RocketChat.authz.hasPermission @userId, 'manage-integrations'
 			throw new Meteor.Error 'not_authorized'
 
 		integration = RocketChat.models.Integrations.findOne(integrationId)
 
 		if not integration?
-			throw new Meteor.Error 'invalid_integration', '[methods] addIntegration -> integration not found'
+			throw new Meteor.Error 'invalid_integration', '[methods] deleteIncomingIntegration -> integration not found'
 
 		updateObj =
 			$pull:
diff --git a/packages/rocketchat-integrations/server/methods/updateIntegration.coffee b/packages/rocketchat-integrations/server/methods/incoming/updateIncomingIntegration.coffee
similarity index 55%
rename from packages/rocketchat-integrations/server/methods/updateIntegration.coffee
rename to packages/rocketchat-integrations/server/methods/incoming/updateIncomingIntegration.coffee
index d41d0e3d145a455cc6a0b96130792f5d79788e4b..59a93bdbbafae5e788a0cee499d1aa0fd23ece1e 100644
--- a/packages/rocketchat-integrations/server/methods/updateIntegration.coffee
+++ b/packages/rocketchat-integrations/server/methods/incoming/updateIncomingIntegration.coffee
@@ -1,19 +1,20 @@
 Meteor.methods
-	updateIntegration: (integrationId, integration) ->
+	updateIncomingIntegration: (integrationId, integration) ->
 		if not RocketChat.authz.hasPermission @userId, 'manage-integrations'
 			throw new Meteor.Error 'not_authorized'
 
 		if not _.isString(integration.channel)
-			throw new Meteor.Error 'invalid_channel', '[methods] addIntegration -> channel must be string'
+			throw new Meteor.Error 'invalid_channel', '[methods] updateIncomingIntegration -> channel must be string'
 
 		if integration.channel.trim() is ''
-			throw new Meteor.Error 'invalid_channel', '[methods] addIntegration -> channel can\'t be empty'
+			throw new Meteor.Error 'invalid_channel', '[methods] updateIncomingIntegration -> channel can\'t be empty'
 
 		if integration.channel[0] not in ['@', '#']
-			throw new Meteor.Error 'invalid_channel', '[methods] addIntegration -> channel should start with # or @'
+			throw new Meteor.Error 'invalid_channel', '[methods] updateIncomingIntegration -> channel should start with # or @'
 
-		if not RocketChat.models.Integrations.findOne(integrationId)?
-			throw new Meteor.Error 'invalid_integration', '[methods] addIntegration -> integration not found'
+		currentIntegration = RocketChat.models.Integrations.findOne(integrationId)
+		if not currentIntegration?
+			throw new Meteor.Error 'invalid_integration', '[methods] updateIncomingIntegration -> integration not found'
 
 		record = undefined
 		channelType = integration.channel[0]
@@ -34,12 +35,16 @@ Meteor.methods
 					]
 
 		if record is undefined
-			throw new Meteor.Error 'channel_does_not_exists', "[methods] addIntegration -> The channel does not exists"
+			throw new Meteor.Error 'channel_does_not_exists', "[methods] updateIncomingIntegration -> The channel does not exists"
+
+		user = RocketChat.models.Users.findOne({username: currentIntegration.username})
+		RocketChat.models.Roles.addUserRoles user._id, 'bot'
 
 		RocketChat.models.Integrations.update integrationId,
 			$set:
 				name: integration.name
 				avatar: integration.avatar
+				emoji: integration.emoji
 				alias: integration.alias
 				channel: integration.channel
 				_updatedAt: new Date
diff --git a/packages/rocketchat-integrations/server/methods/outgoing/addOutgoingIntegration.coffee b/packages/rocketchat-integrations/server/methods/outgoing/addOutgoingIntegration.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..6aab25ee634ae44e80c105f6911ad414e25a73fb
--- /dev/null
+++ b/packages/rocketchat-integrations/server/methods/outgoing/addOutgoingIntegration.coffee
@@ -0,0 +1,69 @@
+Meteor.methods
+	addOutgoingIntegration: (integration) ->
+		if integration.channel?.trim? and integration.channel.trim() is ''
+			delete integration.channel
+
+		if not RocketChat.authz.hasPermission(@userId, 'manage-integrations') and not RocketChat.authz.hasPermission(@userId, 'manage-integrations', 'bot')
+			throw new Meteor.Error 'not_authorized'
+
+		if integration.username.trim() is ''
+			throw new Meteor.Error 'invalid_username', '[methods] addOutgoingIntegration -> username can\'t be empty'
+
+		if not Match.test integration.urls, [String]
+			throw new Meteor.Error 'invalid_urls', '[methods] addOutgoingIntegration -> urls must be an array'
+
+		for url, index in integration.urls
+			delete integration.urls[index] if url.trim() is ''
+
+		integration.urls = _.without integration.urls, [undefined]
+
+		if integration.urls.length is 0
+			throw new Meteor.Error 'invalid_urls', '[methods] addOutgoingIntegration -> urls is required'
+
+		if integration.channel? and integration.channel[0] not in ['@', '#']
+			throw new Meteor.Error 'invalid_channel', '[methods] addOutgoingIntegration -> channel should start with # or @'
+
+		if integration.triggerWords?
+			if not Match.test integration.triggerWords, [String]
+				throw new Meteor.Error 'invalid_triggerWords', '[methods] addOutgoingIntegration -> triggerWords must be an array'
+
+			for triggerWord, index in integration.triggerWords
+				delete integration.triggerWords[index] if triggerWord.trim() is ''
+
+			integration.triggerWords = _.without integration.triggerWords, [undefined]
+
+		if integration.channel?
+			record = undefined
+			channelType = integration.channel[0]
+			channel = integration.channel.substr(1)
+
+			switch channelType
+				when '#'
+					record = RocketChat.models.Rooms.findOne
+						$or: [
+							{_id: channel}
+							{name: channel}
+						]
+				when '@'
+					record = RocketChat.models.Users.findOne
+						$or: [
+							{_id: channel}
+							{username: channel}
+						]
+
+			if record is undefined
+				throw new Meteor.Error 'channel_does_not_exists', "[methods] addOutgoingIntegration -> The channel does not exists"
+
+		user = RocketChat.models.Users.findOne({username: integration.username})
+
+		if not user?
+			throw new Meteor.Error 'user_does_not_exists', "[methods] addOutgoingIntegration -> The username does not exists"
+
+		integration.type = 'webhook-outgoing'
+		integration.userId = user._id
+		integration._createdAt = new Date
+		integration._createdBy = RocketChat.models.Users.findOne @userId, {fields: {username: 1}}
+
+		integration._id = RocketChat.models.Integrations.insert integration
+
+		return integration
diff --git a/packages/rocketchat-integrations/server/methods/outgoing/deleteOutgoingIntegration.coffee b/packages/rocketchat-integrations/server/methods/outgoing/deleteOutgoingIntegration.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..1808b05c2100b002ead280f7afd164ee44299e0c
--- /dev/null
+++ b/packages/rocketchat-integrations/server/methods/outgoing/deleteOutgoingIntegration.coffee
@@ -0,0 +1,13 @@
+Meteor.methods
+	deleteOutgoingIntegration: (integrationId) ->
+		if not RocketChat.authz.hasPermission(@userId, 'manage-integrations') and not RocketChat.authz.hasPermission(@userId, 'manage-integrations', 'bot')
+			throw new Meteor.Error 'not_authorized'
+
+		integration = RocketChat.models.Integrations.findOne(integrationId)
+
+		if not integration?
+			throw new Meteor.Error 'invalid_integration', '[methods] deleteOutgoingIntegration -> integration not found'
+
+		RocketChat.models.Integrations.remove _id: integrationId
+
+		return true
diff --git a/packages/rocketchat-integrations/server/methods/outgoing/updateOutgoingIntegration.coffee b/packages/rocketchat-integrations/server/methods/outgoing/updateOutgoingIntegration.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..2e2d7afb2d1aa95dd1c5ce10d4bd047b544c51ce
--- /dev/null
+++ b/packages/rocketchat-integrations/server/methods/outgoing/updateOutgoingIntegration.coffee
@@ -0,0 +1,86 @@
+Meteor.methods
+	updateOutgoingIntegration: (integrationId, integration) ->
+		if not RocketChat.authz.hasPermission @userId, 'manage-integrations'
+			throw new Meteor.Error 'not_authorized'
+
+		if integration.username.trim() is ''
+			throw new Meteor.Error 'invalid_username', '[methods] updateOutgoingIntegration -> username can\'t be empty'
+
+		if not Match.test integration.urls, [String]
+			throw new Meteor.Error 'invalid_urls', '[methods] updateOutgoingIntegration -> urls must be an array'
+
+		for url, index in integration.urls
+			delete integration.urls[index] if url.trim() is ''
+
+		integration.urls = _.without integration.urls, [undefined]
+
+		if integration.urls.length is 0
+			throw new Meteor.Error 'invalid_urls', '[methods] updateOutgoingIntegration -> urls is required'
+
+		if _.isString(integration.channel)
+			integration.channel = integration.channel.trim()
+		else
+			integration.channel = undefined
+
+		if integration.channel? and integration.channel[0] not in ['@', '#']
+			throw new Meteor.Error 'invalid_channel', '[methods] updateOutgoingIntegration -> channel should start with # or @'
+
+		if not integration.token? or integration.token?.trim() is ''
+			throw new Meteor.Error 'invalid_token', '[methods] updateOutgoingIntegration -> token is required'
+
+		if integration.triggerWords?
+			if not Match.test integration.triggerWords, [String]
+				throw new Meteor.Error 'invalid_triggerWords', '[methods] updateOutgoingIntegration -> triggerWords must be an array'
+
+			for triggerWord, index in integration.triggerWords
+				delete integration.triggerWords[index] if triggerWord.trim() is ''
+
+			integration.triggerWords = _.without integration.triggerWords, [undefined]
+
+		if not RocketChat.models.Integrations.findOne(integrationId)?
+			throw new Meteor.Error 'invalid_integration', '[methods] updateOutgoingIntegration -> integration not found'
+
+
+		if integration.channel?
+			record = undefined
+			channelType = integration.channel[0]
+			channel = integration.channel.substr(1)
+
+			switch channelType
+				when '#'
+					record = RocketChat.models.Rooms.findOne
+						$or: [
+							{_id: channel}
+							{name: channel}
+						]
+				when '@'
+					record = RocketChat.models.Users.findOne
+						$or: [
+							{_id: channel}
+							{username: channel}
+						]
+
+			if record is undefined
+				throw new Meteor.Error 'channel_does_not_exists', "[methods] updateOutgoingIntegration -> The channel does not exists"
+
+		user = RocketChat.models.Users.findOne({username: integration.username})
+
+		if not user?
+			throw new Meteor.Error 'user_does_not_exists', "[methods] updateOutgoingIntegration -> The username does not exists"
+
+		RocketChat.models.Integrations.update integrationId,
+			$set:
+				name: integration.name
+				avatar: integration.avatar
+				emoji: integration.emoji
+				alias: integration.alias
+				channel: integration.channel
+				username: integration.username
+				userId: user._id
+				urls: integration.urls
+				token: integration.token
+				triggerWords: integration.triggerWords
+				_updatedAt: new Date
+				_updatedBy: RocketChat.models.Users.findOne @userId, {fields: {username: 1}}
+
+		return RocketChat.models.Integrations.findOne(integrationId)
diff --git a/packages/rocketchat-integrations/server/processWebhookMessage.js b/packages/rocketchat-integrations/server/processWebhookMessage.js
new file mode 100644
index 0000000000000000000000000000000000000000..ee684f4d59a0360818d48018184d2533c9098d4f
--- /dev/null
+++ b/packages/rocketchat-integrations/server/processWebhookMessage.js
@@ -0,0 +1,102 @@
+this.processWebhookMessage = function(messageObj, user, defaultValues) {
+	var attachment, channel, channelType, i, len, message, ref, rid, room, roomUser;
+
+	if (!defaultValues) {
+		defaultValues = {
+			channel: '',
+			alias: '',
+			avatar: '',
+			emoji: ''
+		};
+	}
+
+	channel = messageObj.channel || defaultValues.channel;
+
+	channelType = channel[0];
+
+	channel = channel.substr(1);
+
+	switch (channelType) {
+		case '#':
+			room = RocketChat.models.Rooms.findOne({
+				$or: [
+					{
+						_id: channel
+					}, {
+						name: channel
+					}
+				]
+			});
+			if (room == null) {
+				throw new Meteor.Error('invalid-channel');
+			}
+			rid = room._id;
+			if (room.t === 'c') {
+				Meteor.runAsUser(user._id, function() {
+					return Meteor.call('joinRoom', room._id);
+				});
+			}
+			break;
+		case '@':
+			roomUser = RocketChat.models.Users.findOne({
+				$or: [
+					{
+						_id: channel
+					}, {
+						username: channel
+					}
+				]
+			});
+			if (roomUser == null) {
+				throw new Meteor.Error('invalid-channel');
+			}
+			rid = [user._id, roomUser._id].sort().join('');
+			room = RocketChat.models.Rooms.findOne(rid);
+			if (!room) {
+				Meteor.runAsUser(user._id, function() {
+					Meteor.call('createDirectMessage', roomUser.username);
+					return room = RocketChat.models.Rooms.findOne(rid);
+				});
+			}
+			break;
+		default:
+			throw new Meteor.Error('invalid-channel-type');
+	}
+
+	message = {
+		alias: messageObj.username || messageObj.alias || defaultValues.alias,
+		msg: _.trim(messageObj.text || messageObj.msg || ''),
+		attachments: messageObj.attachments,
+		parseUrls: false,
+		bot: messageObj.bot,
+		groupable: false
+	};
+
+	if ((messageObj.icon_url != null) || (messageObj.avatar != null)) {
+		message.avatar = messageObj.icon_url || messageObj.avatar;
+	} else if ((messageObj.icon_emoji != null) || (messageObj.emoji != null)) {
+		message.emoji = messageObj.icon_emoji || messageObj.emoji;
+	} else if (defaultValues.avatar != null) {
+		message.avatar = defaultValues.avatar;
+	} else if (defaultValues.emoji != null) {
+		message.emoji = defaultValues.emoji;
+	}
+
+	if (_.isArray(message.attachments)) {
+		ref = message.attachments;
+		for (i = 0, len = ref.length; i < len; i++) {
+			attachment = ref[i];
+			if (attachment.msg) {
+				attachment.text = _.trim(attachment.msg);
+				delete attachment.msg;
+			}
+		}
+	}
+
+	var messageReturn = RocketChat.sendMessage(user, message, room, {});
+
+	return {
+		channel: channel,
+		message: messageReturn
+	}
+};
diff --git a/packages/rocketchat-integrations/server/triggers.coffee b/packages/rocketchat-integrations/server/triggers.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..72fae25524a98baef82bb60f1004dc9ace50286a
--- /dev/null
+++ b/packages/rocketchat-integrations/server/triggers.coffee
@@ -0,0 +1,129 @@
+triggers = {}
+
+RocketChat.models.Integrations.find({type: 'webhook-outgoing'}).observe
+	added: (record) ->
+		channel = record.channel or '__any'
+		triggers[channel] ?= {}
+		triggers[channel][record._id] = record
+
+	changed: (record) ->
+		channel = record.channel or '__any'
+		triggers[channel] ?= {}
+		triggers[channel][record._id] = record
+
+	removed: (record) ->
+		channel = record.channel or '__any'
+		delete triggers[channel][record._id]
+
+
+ExecuteTriggerUrl = (url, trigger, message, room, tries=0) ->
+	word = undefined
+	if trigger.triggerWords?.length > 0
+		for triggerWord in trigger.triggerWords
+			if message.msg.indexOf(triggerWord) is 0
+				word = triggerWord
+				break
+
+		# Stop if there are triggerWords but none match
+		if not word?
+			return
+
+	data =
+		token: trigger.token
+		channel_id: room._id
+		channel_name: room.name
+		timestamp: message.ts
+		user_id: message.u._id
+		user_name: message.u.username
+		text: message.msg
+
+	if word?
+		data.trigger_word = word
+
+	opts =
+		data: data
+		npmRequestOptions:
+			rejectUnauthorized: !RocketChat.settings.get 'Allow_Invalid_SelfSigned_Certs'
+			strictSSL: !RocketChat.settings.get 'Allow_Invalid_SelfSigned_Certs'
+		headers:
+			'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36'
+
+	HTTP.call 'POST', url, opts, (error, result) ->
+		if not result? or result.statusCode isnt 200
+			if result.statusCode is 410
+				RocketChat.models.Integrations.remove _id: trigger._id
+				return
+
+			if tries <= 6
+				# Try again in 0.1s, 1s, 10s, 1m40s, 16m40s, 2h46m40s and 27h46m40s
+				Meteor.setTimeout ->
+					ExecuteTriggerUrl url, trigger, message, room, tries+1
+				, Math.pow(10, tries+2)
+			return
+
+		# process outgoing webhook response as a new message
+		else if result?.statusCode is 200 and (result.data?.text? or result.data?.attachments?)
+			user = RocketChat.models.Users.findOneByUsername(trigger.username)
+
+			result.data.bot =
+				i: trigger._id
+
+			defaultValues =
+				channel: trigger.channel
+				alias: trigger.alias
+				avatar: trigger.avatar
+				emoji: trigger.emoji
+
+			try
+				message = processWebhookMessage result.data, user, defaultValues
+
+				if not message?
+					return RocketChat.API.v1.failure 'unknown-error'
+
+				return RocketChat.API.v1.success()
+			catch e
+				return RocketChat.API.v1.failure e.error
+
+ExecuteTrigger = (trigger, message, room) ->
+	for url in trigger.urls
+		ExecuteTriggerUrl url, trigger, message, room
+
+
+ExecuteTriggers = (message, room) ->
+	if not room?
+		return
+
+	triggersToExecute = []
+
+	switch room.t
+		when 'd'
+			id = room._id.replace(message.u._id, '')
+
+			username = _.without room.usernames, message.u.username
+			username = username[0]
+
+			if triggers['@'+id]?
+				triggersToExecute.push trigger for key, trigger of triggers['@'+id]
+
+			if id isnt username and triggers['@'+username]?
+				triggersToExecute.push trigger for key, trigger of triggers['@'+username]
+
+		when 'c'
+			if triggers.__any?
+				triggersToExecute.push trigger for key, trigger of triggers.__any
+
+		else
+			if triggers['#'+room._id]?
+				triggersToExecute.push trigger for key, trigger of triggers['#'+room._id]
+
+			if room._id isnt room.name and triggers['#'+room.name]?
+				triggersToExecute.push trigger for key, trigger of triggers['#'+room.name]
+
+
+	for triggerToExecute in triggersToExecute
+		ExecuteTrigger triggerToExecute, message, room
+
+	return message
+
+
+RocketChat.callbacks.add 'afterSaveMessage', ExecuteTriggers, RocketChat.callbacks.priority.LOW
diff --git a/packages/rocketchat-ldap/config_server.coffee b/packages/rocketchat-ldap/config_server.coffee
index fd4f3f5f133ebb3ab71d08b8116a841a79c9da15..66e79c078540a68c939ad57ace51074675eef70a 100644
--- a/packages/rocketchat-ldap/config_server.coffee
+++ b/packages/rocketchat-ldap/config_server.coffee
@@ -1,14 +1,23 @@
 MeteorWrapperLdapjs = Npm.require 'ldapjs'
 
 Meteor.startup ->
-	RocketChat.settings.addGroup 'LDAP'
-	RocketChat.settings.add 'LDAP_Enable', false, { type: 'boolean', group: 'LDAP', public: true }
-	RocketChat.settings.add 'LDAP_Url', 'ldap://', { type: 'string' , group: 'LDAP' }
-	RocketChat.settings.add 'LDAP_Port', '389', { type: 'string' , group: 'LDAP' }
-	RocketChat.settings.add 'LDAP_DN', '', { type: 'string' , group: 'LDAP', public: true }
-	RocketChat.settings.add 'LDAP_Bind_Search', '', { type: 'string' , group: 'LDAP' }
-	RocketChat.settings.add 'LDAP_Sync_User_Data', false, { type: 'boolean' , group: 'LDAP' }
-	RocketChat.settings.add 'LDAP_Sync_User_Data_FieldMap', '{"cn":"name", "mail":"email"}', { type: 'string' , group: 'LDAP' }
+	RocketChat.settings.addGroup 'LDAP', ->
+		enableQuery = {_id: 'LDAP_Enable', value: true}
+		enableTLSQuery = [
+			{_id: 'LDAP_Enable', value: true}
+			{_id: 'LDAP_TLS', value: true}
+		]
+
+		@add 'LDAP_Enable', false, { type: 'boolean', public: true }
+		@add 'LDAP_TLS', false, { type: 'boolean', enableQuery: enableQuery }
+		@add 'LDAP_CA_Cert', '', { type: 'string', multiline: true, enableQuery: enableTLSQuery }
+		@add 'LDAP_Reject_Unauthorized', true, { type: 'boolean', enableQuery: enableTLSQuery }
+		@add 'LDAP_Url', 'ldap://', { type: 'string' , enableQuery: enableQuery }
+		@add 'LDAP_Port', '389', { type: 'string' , enableQuery: enableQuery }
+		@add 'LDAP_DN', '', { type: 'string' , public: true, enableQuery: enableQuery }
+		@add 'LDAP_Bind_Search', '', { type: 'string' , enableQuery: enableQuery }
+		@add 'LDAP_Sync_User_Data', false, { type: 'boolean' , enableQuery: enableQuery }
+		@add 'LDAP_Sync_User_Data_FieldMap', '{"cn":"name", "mail":"email"}', { type: 'string', enableQuery: enableQuery }
 
 
 timer = undefined
@@ -20,11 +29,17 @@ updateServices = ->
 
 		if enable?
 			console.log "Enabling LDAP".blue
+			LDAP_DEFAULTS.TLS = RocketChat.settings.get 'LDAP_TLS'
+			LDAP_DEFAULTS.CACert = RocketChat.settings.get 'LDAP_CA_Cert'
+			LDAP_DEFAULTS.rejectUnauthorized = RocketChat.settings.get 'LDAP_Reject_Unauthorized'
 			LDAP_DEFAULTS.url = RocketChat.settings.get 'LDAP_Url'
 			LDAP_DEFAULTS.port = RocketChat.settings.get 'LDAP_Port' if RocketChat.settings.get 'LDAP_Port'
 			LDAP_DEFAULTS.dn = RocketChat.settings.get 'LDAP_DN' or false
 			LDAP_DEFAULTS.bindSearch = RocketChat.settings.get 'LDAP_Bind_Search' or ''
 		else
+			LDAP_DEFAULTS.TLS = undefined
+			LDAP_DEFAULTS.CACert = undefined
+			LDAP_DEFAULTS.rejectUnauthorized = undefined
 			LDAP_DEFAULTS.url = undefined
 			LDAP_DEFAULTS.port = undefined
 			LDAP_DEFAULTS.dn = undefined
diff --git a/packages/rocketchat-ldap/i18n/de.i18n.json b/packages/rocketchat-ldap/i18n/de.i18n.json
index 22e1aec0e1553993b912be11b53e78c0a31c39c5..77df8c918f8c8eff2ef9c2e360a949a020e062b9 100644
--- a/packages/rocketchat-ldap/i18n/de.i18n.json
+++ b/packages/rocketchat-ldap/i18n/de.i18n.json
@@ -1,3 +1,3 @@
 {
-  "LDAP_Dn" : "LDAP DN"
+  "LDAP_Dn" : "LDAP-DN"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-ldap/i18n/ro.i18n.json b/packages/rocketchat-ldap/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..22e1aec0e1553993b912be11b53e78c0a31c39c5
--- /dev/null
+++ b/packages/rocketchat-ldap/i18n/ro.i18n.json
@@ -0,0 +1,3 @@
+{
+  "LDAP_Dn" : "LDAP DN"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-ldap/i18n/sr.i18n.json b/packages/rocketchat-ldap/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-ldap/i18n/sr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-ldap/ldap_server.js b/packages/rocketchat-ldap/ldap_server.js
index d12d9346940cb7676ba75d221cc6da7d45fa8ad5..7cf5ff8c44fad5d8ebc239bfbb383e5d0690a0f9 100644
--- a/packages/rocketchat-ldap/ldap_server.js
+++ b/packages/rocketchat-ldap/ldap_server.js
@@ -11,6 +11,7 @@ var slug = function (text) {
 // e.g. "uid=someuser,cn=users,dc=somevalue"
 LDAP_DEFAULTS = {
 	url: false,
+	TLS: false,
 	port: '389',
 	dn: false,
 	createNewUser: true,
@@ -42,6 +43,25 @@ var LDAP = function(options) {
 	this.ldapjs = MeteorWrapperLdapjs;
 };
 
+
+function startTLS(client) {
+	var opts = {
+		rejectUnauthorized: LDAP_DEFAULTS.rejectUnauthorized
+	};
+
+	if ( LDAP_DEFAULTS.CACert && LDAP_DEFAULTS.CACert != '' ){
+		opts.ca = [LDAP_DEFAULTS.CACert];
+	}
+
+	var starttlsSync = Meteor.wrapAsync(client.starttls);
+
+	var res = starttlsSync(opts , null);
+	if (res) {
+		console.log("StartTLS Result: " + res);
+	}
+}
+
+
 /**
  * Attempt to bind (authenticate) ldap
  * and perform a dn search if specified
@@ -56,17 +76,29 @@ LDAP.prototype.ldapCheck = function(options) {
 
 	options = options || {};
 
-	if (options.hasOwnProperty('username') && options.hasOwnProperty('ldapPass')) {
+	if (!options.hasOwnProperty('username') || !options.hasOwnProperty('ldapPass')) {
+		throw new Meteor.Error(403, "Missing LDAP Auth Parameter");
+	}
 
-		var ldapAsyncFut = new Future();
+	var ldapAsyncFut = new Future();
 
 
-		// Create ldap client
-		var fullUrl = self.options.url + ':' + self.options.port;
-		var client = self.ldapjs.createClient({
-			url: fullUrl
-		});
+	// Create ldap client
+	var fullUrl = self.options.url + ':' + self.options.port;
+	var client = self.ldapjs.createClient({
+		url: fullUrl,
+		reconnect: false
+	});
+
+	if (LDAP_DEFAULTS.TLS == true) {
+		startTLS(client);
+	}
+
+	client.on('error', function(e) {
+		ldapAsyncFut.return({error: e});
+	});
 
+	client.on('connect', function(e) {
 		var bindSync = Meteor.wrapAsync(client.bind.bind(client));
 
 		// Slide @xyz.whatever from username if it was passed in
@@ -142,7 +174,7 @@ LDAP.prototype.ldapCheck = function(options) {
 						delete opts.password;
 					} catch(e) {
 						console.log('LDAP: Error', e);
-						ldapAsyncFut.return({
+						return ldapAsyncFut.return({
 							error: e
 						});
 					}
@@ -153,12 +185,14 @@ LDAP.prototype.ldapCheck = function(options) {
 				client.search(options.ldapOptions.dn, opts, function(err, res) {
 					if (err) {
 						console.log('LDAP: Search Error', err);
-						ldapAsyncFut.return({
+						return ldapAsyncFut.return({
 							error: err
 						});
 					}
+					var entryCount = 0;
 					var dn = self.options.dn;
 					res.on('searchEntry', function(entry) {
+						entryCount++;
 						dn = entry.object.dn;
 					});
 					res.on('error', function(err) {
@@ -168,7 +202,15 @@ LDAP.prototype.ldapCheck = function(options) {
 						});
 					});
 					res.on('end', function(result) {
-						bind(dn);
+						if (entryCount === 1) {
+							bind(dn);
+						} else {
+							console.log('LDAP: Search returned', entryCount, 'record(s)');
+							var err = new Error('User not Found');
+							ldapAsyncFut.return({
+								error: err
+							});
+						}
 					});
 				});
 			} catch (e) {
@@ -180,13 +222,9 @@ LDAP.prototype.ldapCheck = function(options) {
 		} else {
 			bind(self.options.dn);
 		}
+	});
 
-		return ldapAsyncFut.wait();
-
-	} else {
-		throw new Meteor.Error(403, "Missing LDAP Auth Parameter");
-	}
-
+	return ldapAsyncFut.wait();
 };
 
 
@@ -195,6 +233,7 @@ LDAP.prototype.ldapCheck = function(options) {
 // Meteor.loginWithLDAP on client side
 // @param {Object} loginRequest will consist of username, ldapPass, ldap, and ldapOptions
 Accounts.registerLoginHandler("ldap", function(loginRequest) {
+	var self = this;
 	// If "ldap" isn't set in loginRequest object,
 	// then this isn't the proper handler (return undefined)
 	if (!loginRequest.ldap) {
@@ -217,7 +256,24 @@ Accounts.registerLoginHandler("ldap", function(loginRequest) {
 	var ldapResponse = ldapObj.ldapCheck(loginRequest);
 
 	if (ldapResponse.error) {
-		throw new Meteor.Error("LDAP-login-error", ldapResponse.error);
+		console.log(ldapResponse.error);
+		console.log('[LDAP] Falling back to standard account base');
+		if (typeof loginRequest.username === 'string')
+			if (loginRequest.username.indexOf('@') === -1)
+				loginRequest.username = {username: loginRequest.username};
+			else
+				loginRequest.username = {email: loginRequest.username};
+
+		loginRequest = {
+			user: loginRequest.username,
+			password: {
+				digest: SHA256(loginRequest.ldapPass),
+				algorithm: "sha-256"
+			}
+		}
+
+		return Accounts._runLoginHandlers(self, loginRequest);
+		// throw new Meteor.Error("LDAP-login-error", ldapResponse.error);
 	} else {
 		// Set initial userId and token vals
 		var userId = null;
diff --git a/packages/rocketchat-ldap/package.js b/packages/rocketchat-ldap/package.js
index f832514eb3db1b35f1f12303ef1200bd60fd7910..38720bb37dd012f383c2cf913b29377c2576de4c 100644
--- a/packages/rocketchat-ldap/package.js
+++ b/packages/rocketchat-ldap/package.js
@@ -22,10 +22,11 @@ Package.onUse(function(api) {
   api.versionsFrom('1.0.3.1');
 
   // Commom
-  api.use('rocketchat:lib@0.0.1');
-  api.use('tap:i18n@1.5.1');
+  api.use('rocketchat:lib');
+  api.use('tap:i18n');
   api.use('yasaricli:slugify');
   api.use('coffeescript');
+  api.use('sha');
   // Client
   api.use('templating', 'client');
   // Server
diff --git a/packages/rocketchat-lib/README.md b/packages/rocketchat-lib/README.md
index b00630727af688bf729b3c51b0ec9cd14d5e9ab5..68ab59d17c7927deec6a4124fd96996fc0e5862b 100644
--- a/packages/rocketchat-lib/README.md
+++ b/packages/rocketchat-lib/README.md
@@ -4,6 +4,49 @@ This package contains the main libraries of Rocket.Chat.
 
 ### APIs
 
+#### Settings
+
+This is an example to create settings:
+```javascript
+RocketChat.settings.addGroup('Settings_Group', function() {
+    this.add('SettingInGroup', 'default_value', { type: 'boolean', public: true });
+
+    this.section('Group_Section', function() {
+        this.add('Setting_Inside_Section', 'default_value', {
+            type: 'boolean', 
+            public: true, 
+            enableQuery: { 
+                _id: 'SettingInGroup', 
+                value: true 
+            }
+        });
+    });
+});
+```
+
+`RocketChat.settings.add` type:
+
+* `string` - Stores a string value
+    * Additional options:
+        * `multiline`: boolean
+* `int` - Stores an integer value
+* `boolean` - Stores a boolean value
+* `select` - Creates an `<select>` element
+    * Additional options:
+        * `values`: Array of: { key: 'value', i18nLabel: 'Option_Label' }
+* `color` - Creates a color pick element
+* `action` - Executes a `Method.call` to `value`
+    * Additional options:
+        * `actionText`: Translatable value of the button
+* `asset` - Creates an upload field
+
+`RocketChat.settings.add` options:
+
+* `description` - Description of the setting
+* `public` - Boolean to set if the setting should be sent to client or not
+* `enableQuery` - Only enable this setting if the correspondent setting has the value specified
+* `alert` - Shows an alert message with the given text
+
 #### roomTypes
 
 You can create your own room type using (on the client):
@@ -23,7 +66,9 @@ RocketChat.roomTypes.add('l', 5, {
             return { name: sub.name }
         }
     },
-    permissions: [ 'view-l-room' ]
+    condition: () => {
+        return RocketChat.authz.hasAllPermission('view-l-room');
+    }
 });
 ```
 
@@ -52,19 +97,9 @@ AccountBox.addItem({
     name: 'Livechat',
     icon: 'icon-chat-empty',
     class: 'livechat-manager',
-    route: {
-        name: 'livechat-manager',
-        path: '/livechat-manager',
-        action(params, queryParams) {
-            Session.set('openedRoom');
-            BlazeLayout.render('main', {
-                center: 'page-container',
-                pageTitle: 'Live Chat Manager',
-                pageTemplate: 'livechat-manager'
-            });
-        }
-    },
-    permissions: ['view-livechat-manager']
+    condition: () => {
+        return RocketChat.authz.hasAllPermission('view-livechat-manager');
+    }
 });
 ```
 
diff --git a/packages/rocketchat-lib/client/TabBar.coffee b/packages/rocketchat-lib/client/TabBar.coffee
index 237024dbdd7c4738f931733b5c03aab1e90faff1..5228f2e55020c4ff1d961c21fd78a6e14069dcba 100644
--- a/packages/rocketchat-lib/client/TabBar.coffee
+++ b/packages/rocketchat-lib/client/TabBar.coffee
@@ -4,11 +4,15 @@ RocketChat.TabBar = new class
 
 	buttons = new ReactiveVar {}
 
+	extraGroups = {}
+
 	animating = false
 	open = new ReactiveVar false
 	template = new ReactiveVar ''
 	data = new ReactiveVar {}
 
+	visibleGroup = new ReactiveVar ''
+
 	setTemplate = (t, callback) ->
 		return if animating is true
 		template.set t
@@ -65,6 +69,12 @@ RocketChat.TabBar = new class
 		Tracker.nonreactive ->
 			btns = buttons.get()
 			btns[config.id] = config
+
+			if extraGroups[config.id]?
+				btns[config.id].groups ?= []
+				btns[config.id].groups = _.union btns[config.id].groups, extraGroups[config.id]
+				delete extraGroups[config.id]
+
 			buttons.set btns
 
 	removeButton = (id) ->
@@ -93,6 +103,23 @@ RocketChat.TabBar = new class
 	resetButtons = ->
 		buttons.set {}
 
+	showGroup = (group) ->
+		visibleGroup.set group
+
+	getVisibleGroup = ->
+		visibleGroup.get()
+
+	addGroup = (id, groups) ->
+		Tracker.nonreactive ->
+			btns = buttons.get()
+			if btns[id]
+				btns[id].groups ?= []
+				btns[id].groups = _.union btns[id].groups, groups
+				buttons.set btns
+			else
+				extraGroups[id] ?= []
+				extraGroups[id] = _.union extraGroups[id], groups
+
 	setTemplate: setTemplate
 	setData: setData
 	getTemplate: getTemplate
@@ -108,3 +135,7 @@ RocketChat.TabBar = new class
 	getButtons: getButtons
 	reset: reset
 	resetButtons: resetButtons
+
+	showGroup: showGroup
+	getVisibleGroup: getVisibleGroup
+	addGroup: addGroup
diff --git a/packages/rocketchat-lib/client/defaultTabBars.js b/packages/rocketchat-lib/client/defaultTabBars.js
new file mode 100644
index 0000000000000000000000000000000000000000..6737d36c587d0f4d495a4bdf10a8876bea0a0969
--- /dev/null
+++ b/packages/rocketchat-lib/client/defaultTabBars.js
@@ -0,0 +1,35 @@
+RocketChat.TabBar.addButton({
+	groups: ['channel', 'privategroup', 'directmessage'],
+	id: 'message-search',
+	i18nTitle: 'Search',
+	icon: 'octicon octicon-search',
+	template: 'messageSearch',
+	order: 1
+});
+
+RocketChat.TabBar.addButton({
+	groups: ['directmessage'],
+	id: 'user-info',
+	i18nTitle: 'User_Info',
+	icon: 'octicon octicon-person',
+	template: 'membersList',
+	order: 2
+});
+
+RocketChat.TabBar.addButton({
+	groups: ['channel', 'privategroup'],
+	id: 'members-list',
+	i18nTitle: 'Members_List',
+	icon: 'octicon octicon-organization',
+	template: 'membersList',
+	order: 2
+});
+
+RocketChat.TabBar.addButton({
+	groups: ['channel', 'privategroup', 'directmessage'],
+	id: 'uploaded-files-list',
+	i18nTitle: 'Room_uploaded_file_list',
+	icon: 'octicon octicon-file-symlink-directory',
+	template: 'uploadedFilesList',
+	order: 3
+});
diff --git a/packages/rocketchat-lib/client/lib/openRoom.coffee b/packages/rocketchat-lib/client/lib/openRoom.coffee
index 545dce131b85cd960539bb4b3580f566491542bb..7e74d9fd94959246dd10b8815094edd50835dd21 100644
--- a/packages/rocketchat-lib/client/lib/openRoom.coffee
+++ b/packages/rocketchat-lib/client/lib/openRoom.coffee
@@ -27,6 +27,7 @@ currentTracker = undefined
 				BlazeLayout.render 'main', {center: 'roomNotFound'}
 				return
 
+			$('.rocket-loader').remove();
 			mainNode = document.querySelector('.main-content')
 			if mainNode?
 				for child in mainNode.children
@@ -50,16 +51,9 @@ currentTracker = undefined
 					$('.message-form .input-message').focus()
 				, 100
 
-			RocketChat.TabBar.resetButtons()
-			RocketChat.TabBar.addButton({ id: 'message-search', i18nTitle: t('Search'), icon: 'octicon octicon-search', template: 'messageSearch', order: 1 })
-			if type is 'd'
-				RocketChat.TabBar.addButton({ id: 'members-list', i18nTitle: t('User_Info'), icon: 'octicon octicon-person', template: 'membersList', order: 2 })
-			else
-				RocketChat.TabBar.addButton({ id: 'members-list', i18nTitle: t('Members_List'), icon: 'octicon octicon-organization', template: 'membersList', order: 2 })
-			RocketChat.TabBar.addButton({ id: 'uploaded-files-list', i18nTitle: t('Room_uploaded_file_list'), icon: 'octicon octicon-file-symlink-directory', template: 'uploadedFilesList', order: 3 })
-
 			# update user's room subscription
-			if ChatSubscription.findOne({rid: room._id})?.open is false
+			sub = ChatSubscription.findOne({rid: room._id})
+			if sub?.open is false
 				Meteor.call 'openRoom', room._id
 
-			RocketChat.callbacks.run 'enter-room', ChatSubscription.findOne({rid: room._id})
+			RocketChat.callbacks.run 'enter-room', sub
diff --git a/packages/rocketchat-lib/client/lib/roomExit.coffee b/packages/rocketchat-lib/client/lib/roomExit.coffee
index d8a44ae00a37fc9a8ad39caeffa568b27ed2b748..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?
@@ -10,8 +12,9 @@
 			if child?
 				if child.classList.contains('room-container')
 					wrapper = child.querySelector('.messages-box > .wrapper')
-					if wrapper.scrollTop >= wrapper.scrollHeight - wrapper.clientHeight
-						child.oldScrollTop = 10e10
-					else
-						child.oldScrollTop = wrapper.scrollTop
+					if wrapper
+						if wrapper.scrollTop >= wrapper.scrollHeight - wrapper.clientHeight
+							child.oldScrollTop = 10e10
+						else
+							child.oldScrollTop = wrapper.scrollTop
 				mainNode.removeChild child
diff --git a/packages/rocketchat-lib/client/lib/roomTypes.coffee b/packages/rocketchat-lib/client/lib/roomTypes.coffee
index 2e3773a8122eb20cde8049a5a13d1f456ce4b9cb..02843ea4702eb591530e7e6cc7f2c58bab0e18e4 100644
--- a/packages/rocketchat-lib/client/lib/roomTypes.coffee
+++ b/packages/rocketchat-lib/client/lib/roomTypes.coffee
@@ -3,23 +3,11 @@ RocketChat.roomTypes = new class
 	roomTypes = {}
 	mainOrder = 1
 
-	protectedAction = (item) ->
-		# if not item.permissions? or RocketChat.authz.hasAtLeastOnePermission item.permissions
-		return item.route.action
-
-		# return ->
-		# 	BlazeLayout.render 'main',
-		# 		center: 'pageContainer'
-		# 		# @TODO text Not_authorized don't get the correct language
-		# 		pageTitle: t('Not_authorized')
-		# 		pageTemplate: 'notAuthorized'
-
 	### Adds a room type to app
 	@param identifier An identifier to the room type. If a real room, MUST BE the same of `db.rocketchat_room.t` field, if not, can be null
 	@param order Order number of the type
 	@param config
 		template: template name to render on sideNav
-		permissions: list of permissions to see the sideNav template
 		icon: icon class
 		route:
 			name: route name
@@ -45,7 +33,7 @@ RocketChat.roomTypes = new class
 		if config.route?.path? and config.route?.name? and config.route?.action?
 			FlowRouter.route config.route.path,
 				name: config.route.name
-				action: protectedAction config
+				action: config.route.action
 				triggersExit: [roomExit]
 
 	###
@@ -58,14 +46,16 @@ RocketChat.roomTypes = new class
 
 		return FlowRouter.path roomTypes[roomType].route.name, roomTypes[roomType].route.link(subData)
 
+	checkCondition = (roomType) ->
+		return not roomType.condition? or roomType.condition()
+
 	getAllTypes = ->
-		typesPermitted = []
+		orderedTypes = []
 
 		_.sortBy(roomTypesOrder, 'order').forEach (type) ->
-			if not roomTypes[type.identifier].permissions? or RocketChat.authz.hasAtLeastOnePermission roomTypes[type.identifier].permissions
-				typesPermitted.push roomTypes[type.identifier]
+			orderedTypes.push roomTypes[type.identifier]
 
-		return typesPermitted
+		return orderedTypes
 
 	getIcon = (roomType) ->
 		return roomTypes[roomType]?.icon
@@ -85,4 +75,6 @@ RocketChat.roomTypes = new class
 	# setRoute: setRoute
 	getRouteLink: getRouteLink
 
+	checkCondition: checkCondition
+
 	add: add
diff --git a/packages/rocketchat-lib/client/lib/settings.coffee b/packages/rocketchat-lib/client/lib/settings.coffee
index 16ce89cf20f2c233761c06468f168851af0fc209..7a19eb1d3fb35ec970236196f47043f85b235000 100644
--- a/packages/rocketchat-lib/client/lib/settings.coffee
+++ b/packages/rocketchat-lib/client/lib/settings.coffee
@@ -38,11 +38,26 @@ Meteor.startup ->
 			if not siteUrl or not Meteor.userId()?
 				return
 
-			if RocketChat.authz.hasRole(Meteor.userId(), 'admin') is false
+			if RocketChat.authz.hasRole(Meteor.userId(), 'admin') is false or Meteor.settings.public.sandstorm
 				return c.stop()
 
 			siteUrl = siteUrl.replace /\/$/, ''
 			if siteUrl isnt location.origin
-				toastr.warning TAPi18n.__('The_configured_URL_is_different_from_the_URL_you_are_accessing'), TAPi18n.__('Warning')
+				swal
+					type: 'warning'
+					title: t('Warning')
+					text: t("The_setting_s_is_configured_to_s_and_you_are_accessing_from_s", t('Site_Url'), siteUrl, location.origin) + '<br/><br/>' + t("Do_you_want_to_change_to_s_question", location.origin)
+					showCancelButton: true
+					confirmButtonText: t('Yes')
+					cancelButtonText: t('Cancel')
+					closeOnConfirm: false
+					html: true
+				, ->
+					Meteor.call 'saveSetting', 'Site_Url', location.origin, ->
+						swal
+							title: t('Saved')
+							type: 'success'
+							timer: 1000
+							showConfirmButton: false
 
 			return c.stop()
diff --git a/packages/rocketchat-lib/i18n/ar.i18n.json b/packages/rocketchat-lib/i18n/ar.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..b2b4bbb310607e261b0c8df1201622ca7e7fd039 100644
--- a/packages/rocketchat-lib/i18n/ar.i18n.json
+++ b/packages/rocketchat-lib/i18n/ar.i18n.json
@@ -1 +1,5 @@
-{ }
\ No newline at end of file
+{
+  "All_logs" : "كل السجلات",
+  "Delete" : "حذف",
+  "Edit" : "تعديل"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-lib/i18n/de.i18n.json b/packages/rocketchat-lib/i18n/de.i18n.json
index b0d162a99b648c9d7236d8d3f27abb581bca66dc..061db4135c9217af7ddc78058d835a2c10db05ac 100644
--- a/packages/rocketchat-lib/i18n/de.i18n.json
+++ b/packages/rocketchat-lib/i18n/de.i18n.json
@@ -1,4 +1,7 @@
 {
+  "All_logs" : "Alle Protokolle",
+  "Debug_Level" : "Debug-Level",
+  "Delete" : "Löschen",
   "Edit" : "Bearbeiten",
-  "Delete" : "Löschen"
+  "Only_errors" : "Nur Fehler"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-lib/i18n/en.i18n.json b/packages/rocketchat-lib/i18n/en.i18n.json
index b0e165dc996194714898a880cb80f9b81b423e09..f8de802dbcd68c19c65f4b7604913c8e0a6e2625 100644
--- a/packages/rocketchat-lib/i18n/en.i18n.json
+++ b/packages/rocketchat-lib/i18n/en.i18n.json
@@ -1,4 +1,7 @@
 {
+  "All_logs" : "All logs",
+  "Debug_Level" : "Debug Level",
+  "Delete" : "Delete",
   "Edit" : "Edit",
-  "Delete" : "Delete"
+  "Only_errors" : "Only errors"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-lib/i18n/fi.i18n.json b/packages/rocketchat-lib/i18n/fi.i18n.json
index f283462d8f20c210b14553b1c3c17da4acea4428..22892d14afcdedca05a6c16cb143e4290d6618d6 100644
--- a/packages/rocketchat-lib/i18n/fi.i18n.json
+++ b/packages/rocketchat-lib/i18n/fi.i18n.json
@@ -1,4 +1,7 @@
 {
+  "All_logs" : "Kaikki lokit",
+  "Debug_Level" : "Debug-taso",
+  "Delete" : "Poista",
   "Edit" : "Muokkaa",
-  "Delete" : "Poista"
+  "Only_errors" : "Vain virheet"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-lib/i18n/fr.i18n.json b/packages/rocketchat-lib/i18n/fr.i18n.json
index 6fcd2330c33793ab254abbc95a87d661e29a92c0..af1d286560d4732bce2a156e606deefccace2a73 100644
--- a/packages/rocketchat-lib/i18n/fr.i18n.json
+++ b/packages/rocketchat-lib/i18n/fr.i18n.json
@@ -1,4 +1,6 @@
 {
+  "All_logs" : "Tous les journaux",
+  "Delete" : "Supprimer",
   "Edit" : "Modifier",
-  "Delete" : "Supprimer"
+  "Only_errors" : "Seules les erreurs"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-lib/i18n/he.i18n.json b/packages/rocketchat-lib/i18n/he.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..53b1d1e98eb64a0709a0846c46c29e5298a07cdd 100644
--- a/packages/rocketchat-lib/i18n/he.i18n.json
+++ b/packages/rocketchat-lib/i18n/he.i18n.json
@@ -1 +1,6 @@
-{ }
\ No newline at end of file
+{
+  "All_logs" : "כל היומנים",
+  "Debug_Level" : "רמת פירוט",
+  "Delete" : "מחיקה",
+  "Only_errors" : "שגיאות בלבד"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-lib/i18n/hr.i18n.json b/packages/rocketchat-lib/i18n/hr.i18n.json
index 247eb268a3c435b68b8f098edd085331410e5c0a..487e25187be3df3fb4c76dccf60b0c5ae69fabed 100644
--- a/packages/rocketchat-lib/i18n/hr.i18n.json
+++ b/packages/rocketchat-lib/i18n/hr.i18n.json
@@ -1,4 +1,4 @@
 {
-  "Edit" : "Uredi",
-  "Delete" : "Obriši"
+  "Delete" : "Obriši",
+  "Edit" : "Uredi"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-lib/i18n/km.i18n.json b/packages/rocketchat-lib/i18n/km.i18n.json
index 0db86550f900f25f327791234b252eb0e194d2ef..6e4efda1491e155c327edb2d3bf275603eba5be7 100644
--- a/packages/rocketchat-lib/i18n/km.i18n.json
+++ b/packages/rocketchat-lib/i18n/km.i18n.json
@@ -1,4 +1,4 @@
 {
-  "Edit" : "កែ​សម្រួល",
-  "Delete" : "លុប"
+  "Delete" : "លុប",
+  "Edit" : "កែ​សម្រួល"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-lib/i18n/ko.i18n.json b/packages/rocketchat-lib/i18n/ko.i18n.json
index b454f6fb4a396dac50ac6a5e0ab65e71d1a355f4..fc308db9155bae2c107a60030de485b5842ae2d4 100644
--- a/packages/rocketchat-lib/i18n/ko.i18n.json
+++ b/packages/rocketchat-lib/i18n/ko.i18n.json
@@ -1,4 +1,4 @@
 {
-  "Edit" : "수정",
-  "Delete" : "삭제"
+  "Delete" : "삭제",
+  "Edit" : "수정"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-lib/i18n/ms-MY.i18n.json b/packages/rocketchat-lib/i18n/ms-MY.i18n.json
index 1c06d12d0c6e020f77830dce783473288ff64d59..bfe97c78cb240d185e5d58586ac8840ed3a291cb 100644
--- a/packages/rocketchat-lib/i18n/ms-MY.i18n.json
+++ b/packages/rocketchat-lib/i18n/ms-MY.i18n.json
@@ -1,4 +1,4 @@
 {
-  "Edit" : "Sunting",
-  "Delete" : "Padam"
+  "Delete" : "Padam",
+  "Edit" : "Sunting"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-lib/i18n/nl.i18n.json b/packages/rocketchat-lib/i18n/nl.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..39d4c63986ee7caf430a3e4e142e378af51d8bcd 100644
--- a/packages/rocketchat-lib/i18n/nl.i18n.json
+++ b/packages/rocketchat-lib/i18n/nl.i18n.json
@@ -1 +1,7 @@
-{ }
\ No newline at end of file
+{
+  "All_logs" : "Alle logs",
+  "Debug_Level" : "Debug Level",
+  "Delete" : "Verwijder",
+  "Edit" : "Wijzig",
+  "Only_errors" : "Alleen fouten"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-lib/i18n/pl.i18n.json b/packages/rocketchat-lib/i18n/pl.i18n.json
index f0a5a7f12d23523abf20979ebe37c7ea9f5901b4..9b98eea9a2a7c85060a76bc95b25091114cde216 100644
--- a/packages/rocketchat-lib/i18n/pl.i18n.json
+++ b/packages/rocketchat-lib/i18n/pl.i18n.json
@@ -1,4 +1,4 @@
 {
-  "Edit" : "Edycja",
-  "Delete" : "Usuń"
+  "Delete" : "Usuń",
+  "Edit" : "Edycja"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-lib/i18n/pt.i18n.json b/packages/rocketchat-lib/i18n/pt.i18n.json
index 7c1bc08766f41b0d8e6f48cf824fc5a4cba307ed..94accdb5b74bb98183cc32641f769b285c69f2b2 100644
--- a/packages/rocketchat-lib/i18n/pt.i18n.json
+++ b/packages/rocketchat-lib/i18n/pt.i18n.json
@@ -1,4 +1,4 @@
 {
-  "Edit" : "Editar",
-  "Delete" : "Deletar"
+  "Delete" : "Deletar",
+  "Edit" : "Editar"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-lib/i18n/ro.i18n.json b/packages/rocketchat-lib/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..974ae6298ae9636855175b0a64ad425db7f73def
--- /dev/null
+++ b/packages/rocketchat-lib/i18n/ro.i18n.json
@@ -0,0 +1,7 @@
+{
+  "All_logs" : "Toate înregistrările",
+  "Debug_Level" : "Debug Level",
+  "Delete" : "Șterge",
+  "Edit" : "Editează",
+  "Only_errors" : "Doar erori"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-lib/i18n/ru.i18n.json b/packages/rocketchat-lib/i18n/ru.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..1a0f7a2f5aaa5780c1832be101282d6da5961d30 100644
--- a/packages/rocketchat-lib/i18n/ru.i18n.json
+++ b/packages/rocketchat-lib/i18n/ru.i18n.json
@@ -1 +1,4 @@
-{ }
\ No newline at end of file
+{
+  "Delete" : "Удалить",
+  "Edit" : "Редактировать"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-lib/i18n/sr.i18n.json b/packages/rocketchat-lib/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-lib/i18n/sr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-lib/i18n/tr.i18n.json b/packages/rocketchat-lib/i18n/tr.i18n.json
index 230736a85351678f1c3d3f2b7d48473b6bb3e3e6..fe60600ba2d3f8f7d3a4693526e0d87c5467482d 100644
--- a/packages/rocketchat-lib/i18n/tr.i18n.json
+++ b/packages/rocketchat-lib/i18n/tr.i18n.json
@@ -1,4 +1,4 @@
 {
-  "Edit" : "Düzenle",
-  "Delete" : "Sil"
+  "Delete" : "Sil",
+  "Edit" : "Düzenle"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-lib/i18n/zh.i18n.json b/packages/rocketchat-lib/i18n/zh.i18n.json
index 4a3796cadc9228cb35cdd5374a75d9d3d32e7296..297bc71c15ea96488a72d04d40a30823fa36fd5b 100644
--- a/packages/rocketchat-lib/i18n/zh.i18n.json
+++ b/packages/rocketchat-lib/i18n/zh.i18n.json
@@ -1,4 +1,4 @@
 {
-  "Edit" : "编辑",
-  "Delete" : "删除"
+  "Delete" : "删除",
+  "Edit" : "编辑"
 }
\ No newline at end of file
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 55%
rename from packages/rocketchat-lib/client/MessageTypes.coffee
rename to packages/rocketchat-lib/lib/MessageTypes.coffee
index 3e374f4d7cace7513e86cf03b9d796585a742a02..58f651d4586d4a5f121de0149d4f8f1520a7f6bc 100644
--- a/packages/rocketchat-lib/client/MessageTypes.coffee
+++ b/packages/rocketchat-lib/lib/MessageTypes.coffee
@@ -68,3 +68,45 @@ Meteor.startup ->
 		id: 'rtc'
 		render: (message) ->
 			RocketChat.callbacks.run 'renderRtcMessage', message
+
+	RocketChat.MessageTypes.registerType
+		id: 'user-muted'
+		system: true
+		message: 'User_muted_by'
+		data: (message) ->
+			return { user_muted: message.msg, user_by: message.u.username }
+
+	RocketChat.MessageTypes.registerType
+		id: 'user-unmuted'
+		system: true
+		message: 'User_unmuted_by'
+		data: (message) ->
+			return { user_unmuted: message.msg, user_by: message.u.username }
+
+	RocketChat.MessageTypes.registerType
+		id: 'new-moderator'
+		system: true
+		message: 'User__username__was_added_as_a_moderator_by__user_by_'
+		data: (message) ->
+			return { username: message.msg, user_by: message.u.username }
+
+	RocketChat.MessageTypes.registerType
+		id: 'moderator-removed'
+		system: true
+		message: 'User__username__was_removed_as_a_moderator_by__user_by_'
+		data: (message) ->
+			return { username: message.msg, user_by: message.u.username }
+
+	RocketChat.MessageTypes.registerType
+		id: 'new-owner'
+		system: true
+		message: 'User__username__was_added_as_a_owner_by__user_by_'
+		data: (message) ->
+			return { username: message.msg, user_by: message.u.username }
+
+	RocketChat.MessageTypes.registerType
+		id: 'owner-removed'
+		system: true
+		message: 'User__username__was_removed_as_a_owner_by__user_by_'
+		data: (message) ->
+			return { username: message.msg, user_by: message.u.username }
diff --git a/packages/rocketchat-lib/package.js b/packages/rocketchat-lib/package.js
index 897bd0bab52cb71c4c7c823acebc60bdd9b579a8..5f2639f86fdc741d73f86ff96c95705f8f6dfcf7 100644
--- a/packages/rocketchat-lib/package.js
+++ b/packages/rocketchat-lib/package.js
@@ -22,13 +22,20 @@ Package.onUse(function(api) {
 	api.use('service-configuration');
 	api.use('check');
 	api.use('arunoda:streams');
+	api.use('rocketchat:version');
 	api.use('kadira:flow-router', 'client');
 
-	// COMMON LIB
 	api.addFiles('lib/core.coffee');
+
+	// DEBUGGER
+	api.addFiles('server/lib/debug.js', 'server');
+
+	// COMMON LIB
 	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');
@@ -62,6 +69,7 @@ Package.onUse(function(api) {
 	api.addFiles('server/methods/saveSetting.coffee', 'server');
 	api.addFiles('server/methods/sendInvitationEmail.coffee', 'server');
 	api.addFiles('server/methods/sendMessage.coffee', 'server');
+	api.addFiles('server/methods/sendSMTPTestEmail.coffee', 'server');
 	api.addFiles('server/methods/setAdminStatus.coffee', 'server');
 	api.addFiles('server/methods/setRealName.coffee', 'server');
 	api.addFiles('server/methods/setUsername.coffee', 'server');
@@ -70,6 +78,7 @@ Package.onUse(function(api) {
 
 	// SERVER STARTUP
 	api.addFiles('server/startup/settingsOnLoadCdnPrefix.coffee', 'server');
+	api.addFiles('server/startup/settingsOnLoadSMTP.coffee', 'server');
 	api.addFiles('server/startup/oAuthServicesUpdate.coffee', 'server');
 	api.addFiles('server/startup/settings.coffee', 'server');
 
@@ -88,7 +97,11 @@ 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');
+
+	api.addFiles('client/defaultTabBars.js', 'client');
+
+	// VERSION
+	api.addFiles('rocketchat.info');
 
 	// TAPi18n
 	api.use('templating', 'client');
@@ -99,9 +112,8 @@ Package.onUse(function(api) {
 			return 'i18n/' + filename;
 		}
 	}));
-	api.use('tap:i18n@1.6.1', ['client', 'server']);
-	api.imply('tap:i18n');
-	api.addFiles(tapi18nFiles, ['client', 'server']);
+	api.use('tap:i18n');
+	api.addFiles(tapi18nFiles);
 
 	// EXPORT
 	api.export('RocketChat');
diff --git a/packages/rocketchat-lib/rocketchat.info b/packages/rocketchat-lib/rocketchat.info
new file mode 100644
index 0000000000000000000000000000000000000000..37f939dff5bfb57635a8edd8cd3df2cd23141af7
--- /dev/null
+++ b/packages/rocketchat-lib/rocketchat.info
@@ -0,0 +1,3 @@
+{
+	"version": "0.14.0"
+}
diff --git a/packages/rocketchat-lib/server/functions/sendMessage.coffee b/packages/rocketchat-lib/server/functions/sendMessage.coffee
index 20620d1c9dc55f6d3fc8701ce8374664fb5f6ccb..fa30388ff35ff8b4d127e89b120adb80f5ac74cf 100644
--- a/packages/rocketchat-lib/server/functions/sendMessage.coffee
+++ b/packages/rocketchat-lib/server/functions/sendMessage.coffee
@@ -11,7 +11,7 @@ RocketChat.sendMessage = (user, message, room, options) ->
 	message.rid = room._id
 
 	if message.parseUrls isnt false
-		if urls = message.msg.match /([A-Za-z]{3,9}):\/\/([-;:&=\+\$,\w]+@{1})?([-A-Za-z0-9\.]+)+:?(\d+)?((\/[-\+=!:~%\/\.@\,\w]+)?\??([-\+=&!:;%@\/\.\,\w]+)?#?([\w]+)?)?/g
+		if urls = message.msg.match /([A-Za-z]{3,9}):\/\/([-;:&=\+\$,\w]+@{1})?([-A-Za-z0-9\.]+)+:?(\d+)?((\/[-\+=!:~%\/\.@\,\w]+)?\??([-\+=&!:;%@\/\.\,\w]+)?#?([^\s]+)?)?/g
 			message.urls = urls.map (url) -> url: url
 
 	message = RocketChat.callbacks.run 'beforeSaveMessage', message
@@ -30,7 +30,7 @@ RocketChat.sendMessage = (user, message, room, options) ->
 	###
 	Meteor.defer ->
 
-		RocketChat.callbacks.run 'afterSaveMessage', message
+		RocketChat.callbacks.run 'afterSaveMessage', message, room
 
 	###
 	Update all the room activity tracker fields
diff --git a/packages/rocketchat-lib/server/functions/setUsername.coffee b/packages/rocketchat-lib/server/functions/setUsername.coffee
index da23f4970b57347ea426a766bfc6c8eacbc3e254..cee48c9cad45dc8ec19b6def09f73be144f5c1fa 100644
--- a/packages/rocketchat-lib/server/functions/setUsername.coffee
+++ b/packages/rocketchat-lib/server/functions/setUsername.coffee
@@ -40,6 +40,7 @@ RocketChat._setUsername = (userId, username) ->
 			RocketChat.models.Messages.updateUsernameAndMessageOfMentionByIdAndOldUsername msg._id, previousUsername, username, updatedMsg
 
 		RocketChat.models.Rooms.replaceUsername previousUsername, username
+		RocketChat.models.Rooms.replaceMutedUsername previousUsername, username
 		RocketChat.models.Rooms.replaceUsernameOfUserByUserId user._id, username
 
 		RocketChat.models.Subscriptions.setUserUsernameByUserId user._id, username
diff --git a/packages/rocketchat-lib/server/functions/settings.coffee b/packages/rocketchat-lib/server/functions/settings.coffee
index 34f829a6d9d0a305bcc389fe8a1db56f4eb28e81..81b4099fe66a59c554efd676451a9d90bdcfd985 100644
--- a/packages/rocketchat-lib/server/functions/settings.coffee
+++ b/packages/rocketchat-lib/server/functions/settings.coffee
@@ -1,3 +1,5 @@
+RocketChat.settings._sorter = 0
+
 ###
 # Add a setting
 # @param {String} _id
@@ -14,6 +16,10 @@ RocketChat.settings.add = (_id, value, options = {}) ->
 	options.valueSource = 'packageValue'
 	options.ts = new Date
 	options.hidden = false
+	options.sorter ?= RocketChat.settings._sorter++
+
+	if options.enableQuery?
+		options.enableQuery = JSON.stringify options.enableQuery
 
 	if process?.env?[_id]?
 		value = process.env[_id]
@@ -32,23 +38,33 @@ RocketChat.settings.add = (_id, value, options = {}) ->
 	if not options.i18nDescription?
 		options.i18nDescription = "#{_id}_Description"
 
-	return RocketChat.models.Settings.upsert { _id: _id },
+	updateOperations =
 		$set: options
 		$setOnInsert:
 			value: value
 			createdAt: new Date
 
+	if not options.section?
+		updateOperations.$unset = { section: 1 }
+
+	return RocketChat.models.Settings.upsert { _id: _id }, updateOperations
+
+
 
 ###
 # Add a setting group
 # @param {String} _id
 ###
-RocketChat.settings.addGroup = (_id, options = {}) ->
+RocketChat.settings.addGroup = (_id, options = {}, cb) ->
 	# console.log '[functions] RocketChat.settings.addGroup -> '.green, 'arguments:', arguments
 
 	if not _id
 		return false
 
+	if _.isFunction(options)
+		cb = options
+		options = {}
+
 	if not options.i18nLabel?
 		options.i18nLabel = _id
 
@@ -58,12 +74,27 @@ RocketChat.settings.addGroup = (_id, options = {}) ->
 	options.ts = new Date
 	options.hidden = false
 
-	return RocketChat.models.Settings.upsert { _id: _id },
+	RocketChat.models.Settings.upsert { _id: _id },
 		$set: options
 		$setOnInsert:
 			type: 'group'
 			createdAt: new Date
 
+	if cb?
+		cb.call
+			add: (id, value, options = {}) ->
+				options.group = _id
+				RocketChat.settings.add id, value, options
+
+			section: (section, cb) ->
+				cb.call
+					add: (id, value, options = {}) ->
+						options.group = _id
+						options.section = section
+						RocketChat.settings.add id, value, options
+
+	return
+
 
 ###
 # Remove a setting by id
@@ -91,6 +122,19 @@ RocketChat.settings.updateById = (_id, value) ->
 	return RocketChat.models.Settings.updateValueById _id, value
 
 
+###
+# Update options of a setting by id
+# @param {String} _id
+###
+RocketChat.settings.updateOptionsById = (_id, options) ->
+	# console.log '[functions] RocketChat.settings.updateOptionsById -> '.green, 'arguments:', arguments
+
+	if not _id or not options?
+		return false
+
+	return RocketChat.models.Settings.updateOptionsById _id, options
+
+
 ###
 # Update a setting by id
 # @param {String} _id
@@ -112,14 +156,17 @@ RocketChat.settings.init = ->
 	RocketChat.models.Settings.find().observe
 		added: (record) ->
 			Meteor.settings[record._id] = record.value
-			process.env[record._id] = record.value
+			if record.env is true
+				process.env[record._id] = record.value
 			RocketChat.settings.load record._id, record.value, initialLoad
 		changed: (record) ->
 			Meteor.settings[record._id] = record.value
-			process.env[record._id] = record.value
+			if record.env is true
+				process.env[record._id] = record.value
 			RocketChat.settings.load record._id, record.value, initialLoad
 		removed: (record) ->
 			delete Meteor.settings[record._id]
-			delete process.env[record._id]
+			if record.env is true
+				delete process.env[record._id]
 			RocketChat.settings.load record._id, undefined, initialLoad
 	initialLoad = false
diff --git a/packages/rocketchat-lib/server/lib/debug.js b/packages/rocketchat-lib/server/lib/debug.js
new file mode 100644
index 0000000000000000000000000000000000000000..1ccc9791d31b8f4d6441be9227caab3cf66e4a3e
--- /dev/null
+++ b/packages/rocketchat-lib/server/lib/debug.js
@@ -0,0 +1,46 @@
+RocketChat.debugLevel = 'debug';
+
+Meteor.startup(function() {
+	RocketChat.settings.onload('Debug_Level', function(key, value, initialLoad) {
+		if (value) {
+			RocketChat.debugLevel = value;
+		}
+	});
+
+	var value = RocketChat.settings.get('Debug_Level');
+	if (value) {
+		RocketChat.debugLevel = value;
+	}
+});
+
+var wrapMethods = function(name, originalHandler, methodsMap) {
+	methodsMap[name] = function() {
+		if (RocketChat.debugLevel === 'debug') {
+			var args = name === "ufsWrite" ? Array.prototype.slice.call(arguments, 1) : arguments;
+			console.log('[methods]'.green, name, '-> userId:', Meteor.userId(), ', arguments: ', args);
+		}
+
+		return originalHandler.apply(this, arguments);
+	};
+};
+
+var originalMeteorMethods = Meteor.methods;
+
+Meteor.methods = function(methodMap) {
+	_.each(methodMap, function(handler, name) {
+		wrapMethods(name, handler, methodMap);
+	});
+	originalMeteorMethods(methodMap);
+};
+
+var originalMeteorPublish = Meteor.publish;
+
+Meteor.publish = function(name, func) {
+	return originalMeteorPublish(name, function() {
+		if (RocketChat.debugLevel === 'debug') {
+			console.log('[publish]'.green, name, '-> userId:', this.userId, ', arguments: ', arguments);
+		}
+
+		return func.apply(this, arguments);
+	})
+};
diff --git a/packages/rocketchat-lib/server/methods/addOAuthService.coffee b/packages/rocketchat-lib/server/methods/addOAuthService.coffee
index 4545add58416ea93414ac1ac01edadeeace8d9c6..b115a6d4bb3e5223bb5f3b70fd39f576fb55e8a6 100644
--- a/packages/rocketchat-lib/server/methods/addOAuthService.coffee
+++ b/packages/rocketchat-lib/server/methods/addOAuthService.coffee
@@ -3,8 +3,6 @@ Meteor.methods
 		if not Meteor.userId()
 			throw new Meteor.Error('invalid-user', "[methods] addOAuthService -> Invalid user")
 
-		console.log '[methods] addOAuthService -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
-
 		unless RocketChat.authz.hasPermission( Meteor.userId(), 'add-oauth-service') is true
 			throw new Meteor.Error 'not-authorized', '[methods] addOAuthService -> Not authorized'
 
@@ -17,6 +15,7 @@ Meteor.methods
 		RocketChat.settings.add "Accounts_OAuth_Custom_#{name}_authorize_path"    , '/oauth/authorize', { type: 'string' , group: 'Accounts', section: "Custom OAuth: #{name}", i18nLabel: 'Accounts_OAuth_Custom_Authorize_Path', persistent: true }
 		RocketChat.settings.add "Accounts_OAuth_Custom_#{name}_id"                , ''                , { type: 'string' , group: 'Accounts', section: "Custom OAuth: #{name}", i18nLabel: 'Accounts_OAuth_Custom_id', persistent: true }
 		RocketChat.settings.add "Accounts_OAuth_Custom_#{name}_secret"            , ''                , { type: 'string' , group: 'Accounts', section: "Custom OAuth: #{name}", i18nLabel: 'Accounts_OAuth_Custom_Secret', persistent: true }
+		RocketChat.settings.add "Accounts_OAuth_Custom_#{name}_login_style"       , 'popup'           , { type: 'select' , group: 'Accounts', section: "Custom OAuth: #{name}", i18nLabel: 'Accounts_OAuth_Custom_Login_Style', persistent: true, values: [ { key: 'redirect', i18nLabel: 'Redirect' }, { key: 'popup', i18nLabel: 'Popup' }, { key: '', i18nLabel: 'Default' } ] }
 		RocketChat.settings.add "Accounts_OAuth_Custom_#{name}_button_label_text" , ''                , { type: 'string' , group: 'Accounts', section: "Custom OAuth: #{name}", i18nLabel: 'Accounts_OAuth_Custom_Button_Label_Text', persistent: true }
 		RocketChat.settings.add "Accounts_OAuth_Custom_#{name}_button_label_color", '#FFFFFF'         , { type: 'string' , group: 'Accounts', section: "Custom OAuth: #{name}", i18nLabel: 'Accounts_OAuth_Custom_Button_Label_Color', persistent: true }
 		RocketChat.settings.add "Accounts_OAuth_Custom_#{name}_button_color"      , '#13679A'         , { type: 'string' , group: 'Accounts', section: "Custom OAuth: #{name}", i18nLabel: 'Accounts_OAuth_Custom_Button_Color', persistent: true }
diff --git a/packages/rocketchat-lib/server/methods/checkRegistrationSecretURL.coffee b/packages/rocketchat-lib/server/methods/checkRegistrationSecretURL.coffee
index a69c22fffe43e99f3a946a5c6dcd334023358194..592b85470995143fba4caaf3ba22e11de7ec55f9 100644
--- a/packages/rocketchat-lib/server/methods/checkRegistrationSecretURL.coffee
+++ b/packages/rocketchat-lib/server/methods/checkRegistrationSecretURL.coffee
@@ -1,4 +1,3 @@
 Meteor.methods
 	checkRegistrationSecretURL: (hash) ->
-		console.log '[method] checkRegistrationSecretURL'.green, hash
 		return hash is RocketChat.settings.get 'Accounts_RegistrationForm_SecretURL'
diff --git a/packages/rocketchat-lib/server/methods/joinDefaultChannels.coffee b/packages/rocketchat-lib/server/methods/joinDefaultChannels.coffee
index 97218c2df15e04ef6bb2823626a0cb0565216f7a..3087fb387f430b9699110fd83fcf3cd2e9d979c3 100644
--- a/packages/rocketchat-lib/server/methods/joinDefaultChannels.coffee
+++ b/packages/rocketchat-lib/server/methods/joinDefaultChannels.coffee
@@ -3,8 +3,6 @@ Meteor.methods
 		if not Meteor.userId()
 			throw new Meteor.Error('invalid-user', "[methods] joinDefaultChannels -> Invalid user")
 
-		console.log '[methods] joinDefaultChannels -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
-
 		user = Meteor.user()
 
 		RocketChat.callbacks.run 'beforeJoinDefaultChannels', user
diff --git a/packages/rocketchat-lib/server/methods/removeOAuthService.coffee b/packages/rocketchat-lib/server/methods/removeOAuthService.coffee
index 60d94fef7eeb8a9618bc972e090324d6b018d2f0..221b2495df2f5bd20f140f82c16a2aadd716bddc 100644
--- a/packages/rocketchat-lib/server/methods/removeOAuthService.coffee
+++ b/packages/rocketchat-lib/server/methods/removeOAuthService.coffee
@@ -3,8 +3,6 @@ Meteor.methods
 		if not Meteor.userId()
 			throw new Meteor.Error('invalid-user', "[methods] addOAuthService -> Invalid user")
 
-		console.log '[methods] addOAuthService -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
-
 		unless RocketChat.authz.hasPermission( Meteor.userId(), 'add-oauth-service') is true
 			throw new Meteor.Error 'not-authorized', '[methods] addOAuthService -> Not authorized'
 
diff --git a/packages/rocketchat-lib/server/methods/robotMethods.coffee b/packages/rocketchat-lib/server/methods/robotMethods.coffee
index 664cb049bda7d24e22d156cbae5a576e3faff77b..4a101fdacf1ce680349c1572c598f4f092b1123f 100644
--- a/packages/rocketchat-lib/server/methods/robotMethods.coffee
+++ b/packages/rocketchat-lib/server/methods/robotMethods.coffee
@@ -6,8 +6,6 @@ Meteor.methods
 		unless RocketChat.authz.hasRole Meteor.userId(), 'robot'
 			throw new Meteor.Error 'unauthorized', '[methods] robot.modelCall -> Unauthorized'
 
-		console.log '[method] robot.modelCall'.green, arguments
-
 		unless _.isFunction RocketChat.models[model]?[method]
 			throw new Meteor.Error 'invalid-method', '[methods] robot.modelCall -> Invalid method'
 
diff --git a/packages/rocketchat-lib/server/methods/saveSetting.coffee b/packages/rocketchat-lib/server/methods/saveSetting.coffee
index b2775cb055c1b2c5f963df3b0e01c1ef0d618ae6..0b6c1cad55a2c403ca121f74c9aba2110afc6a80 100644
--- a/packages/rocketchat-lib/server/methods/saveSetting.coffee
+++ b/packages/rocketchat-lib/server/methods/saveSetting.coffee
@@ -1,6 +1,5 @@
 Meteor.methods
 	saveSetting: (_id, value) ->
-		console.log '[method] saveSetting', _id, value
 		if Meteor.userId()?
 			user = Meteor.users.findOne Meteor.userId()
 
diff --git a/packages/rocketchat-lib/server/methods/sendMessage.coffee b/packages/rocketchat-lib/server/methods/sendMessage.coffee
index 527470eeb9e75fab4d555cee7b6b1e36193b6148..bec44f79f1a79520abb1ea2f3ed2d650c81499de 100644
--- a/packages/rocketchat-lib/server/methods/sendMessage.coffee
+++ b/packages/rocketchat-lib/server/methods/sendMessage.coffee
@@ -6,8 +6,6 @@ Meteor.methods
 		if not Meteor.userId()
 			throw new Meteor.Error('invalid-user', "[methods] sendMessage -> Invalid user")
 
-		console.log '[methods] sendMessage -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
-
 		user = RocketChat.models.Users.findOneById Meteor.userId(), fields: username: 1
 
 		room = Meteor.call 'canAccessRoom', message.rid, user._id
@@ -15,6 +13,15 @@ Meteor.methods
 		if not room
 			return false
 
+		if user.username in (room.muted or [])
+			RocketChat.Notifications.notifyUser Meteor.userId(), 'message', {
+				_id: Random.id()
+				rid: room._id
+				ts: new Date
+				msg: TAPi18n.__('You_have_been_muted', {}, user.language);
+			}
+			return false
+
 		RocketChat.sendMessage user, message, room, options
 
 # Limit a user to sending 5 msgs/second
diff --git a/packages/rocketchat-lib/server/methods/sendSMTPTestEmail.coffee b/packages/rocketchat-lib/server/methods/sendSMTPTestEmail.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..d766f129c99482c7e3f68d3e9498e754a5b47f58
--- /dev/null
+++ b/packages/rocketchat-lib/server/methods/sendSMTPTestEmail.coffee
@@ -0,0 +1,29 @@
+Meteor.methods
+	sendSMTPTestEmail: ->
+		if not Meteor.userId()
+			throw new Meteor.Error 'invalid-user', "[methods] sendSMTPTestEmail -> Invalid user"
+
+		user = Meteor.user()
+		unless user.emails?[0]?.address
+			throw new Meteor.Error 'invalid-email', "[methods] sendSMTPTestEmail -> Invalid e-mail"
+
+		Email.send
+			to: user.emails[0].address
+			from: RocketChat.settings.get('From_Email')
+			subject: "SMTP Test E-mail"
+			html: "You have successfully sent an e-mail"
+
+		console.log 'Sending email to ' + user.emails[0].address
+
+		return {
+			message: "Your_mail_was_sent_to_s"
+			params: [user.emails[0].address]
+		}
+
+# Limit a user to sending 1 test mail/second
+DDPRateLimiter.addRule
+	type: 'method'
+	name: 'sendSMTPTestEmail'
+	userId: (userId) ->
+		return true
+, 1, 1000
diff --git a/packages/rocketchat-lib/server/methods/setAdminStatus.coffee b/packages/rocketchat-lib/server/methods/setAdminStatus.coffee
index b81d6d9f04f62db1ee3817794d0afd9854d3f5c2..542c5853fd094f682c17af4225fdc2527cf22cb4 100644
--- a/packages/rocketchat-lib/server/methods/setAdminStatus.coffee
+++ b/packages/rocketchat-lib/server/methods/setAdminStatus.coffee
@@ -7,8 +7,8 @@ Meteor.methods
 			throw new Meteor.Error 'not-authorized', '[methods] setAdminStatus -> Not authorized'
 
 		if admin
-			RocketChat.authz.addUsersToRoles( userId, 'admin')
+			RocketChat.authz.addUserRoles( userId, 'admin')
 		else
-			RocketChat.authz.removeUsersFromRoles( userId, 'admin')
+			RocketChat.authz.removeUserFromRoles( userId, 'admin')
 
 		return true
diff --git a/packages/rocketchat-lib/server/methods/setRealName.coffee b/packages/rocketchat-lib/server/methods/setRealName.coffee
index 2a913c93f3eccb44f92c2bb4d63499330ba96f32..92a2c9b078e1e14edc185f1dec2afe639525a36f 100644
--- a/packages/rocketchat-lib/server/methods/setRealName.coffee
+++ b/packages/rocketchat-lib/server/methods/setRealName.coffee
@@ -3,8 +3,6 @@ Meteor.methods
 		if not Meteor.userId()
 			throw new Meteor.Error('invalid-user', "[methods] setRealName -> Invalid user")
 
-		console.log '[methods] setRealName -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
-
 		user = Meteor.user()
 
 		if user.name is name
diff --git a/packages/rocketchat-lib/server/methods/setUsername.coffee b/packages/rocketchat-lib/server/methods/setUsername.coffee
index f9e62785daf2c0d1907d85b5b0a8075e9cc36fd4..c74ec4a6b21f39fdcc0da7bd61f505e24c96336e 100644
--- a/packages/rocketchat-lib/server/methods/setUsername.coffee
+++ b/packages/rocketchat-lib/server/methods/setUsername.coffee
@@ -8,8 +8,6 @@ Meteor.methods
 		if user.username? and not RocketChat.settings.get("Accounts_AllowUsernameChange")
 			throw new Meteor.Error(403, "[methods] setUsername -> Username change not allowed")
 
-		console.log '[methods] setUsername -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
-
 		if user.username is username
 			return username
 
@@ -22,7 +20,7 @@ Meteor.methods
 			throw new Meteor.Error 'username-invalid', "#{username} is not a valid username, use only letters, numbers, dots and dashes"
 
 		if user.username != undefined
-			if not username.toLowerCase() == user.username.toLowerCase() 
+			if not username.toLowerCase() == user.username.toLowerCase()
 				if not  RocketChat.checkUsernameAvailability username
 					throw new Meteor.Error 'username-unavailable', "#{username} is already in use :("
 		else
diff --git a/packages/rocketchat-lib/server/methods/updateUser.coffee b/packages/rocketchat-lib/server/methods/updateUser.coffee
index 9a20d41012221417c70dc3176a562077088f4b80..2416d3d11846058197b35372e529bc6bc88c2c1c 100644
--- a/packages/rocketchat-lib/server/methods/updateUser.coffee
+++ b/packages/rocketchat-lib/server/methods/updateUser.coffee
@@ -3,8 +3,6 @@ Meteor.methods
 		if not Meteor.userId()
 			throw new Meteor.Error('invalid-user', "[methods] updateUser -> Invalid user")
 
-		console.log '[methods] updateUser -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
-
 		user = Meteor.user()
 
 		canEditUserPermission = RocketChat.authz.hasPermission( user._id, 'edit-other-user-info')
@@ -25,4 +23,8 @@ Meteor.methods
 		Meteor.runAsUser userData._id, ->
 			Meteor.call 'setUsername', userData.username
 
-		return true
\ No newline at end of file
+		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 b7449cddf4757cd9b6aa2a05183eae6672cfa6b3..c7e7bf5ba00811df1d543f3ac89af416065e67b1 100644
--- a/packages/rocketchat-lib/server/models/Messages.coffee
+++ b/packages/rocketchat-lib/server/models/Messages.coffee
@@ -24,6 +24,14 @@ RocketChat.models.Messages = new class extends RocketChat.models._Base
 
 		return @find query, options
 
+	findVisibleByMentionAndRoomId: (username, rid, options) ->
+		query =
+			_hidden: { $ne: true }
+			"mentions.username": username
+			"rid": rid
+
+		return @find query, options
+
 	findVisibleByRoomId: (roomId, options) ->
 		query =
 			_hidden:
@@ -108,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
@@ -126,7 +142,6 @@ RocketChat.models.Messages = new class extends RocketChat.models._Base
 
 		return @insert record
 
-
 	# UPDATE
 	setHiddenById: (_id, hidden=true) ->
 		query =
@@ -148,6 +163,8 @@ RocketChat.models.Messages = new class extends RocketChat.models._Base
 				msg: ''
 				t: 'rm'
 				urls: []
+				mentions: []
+				attachments: []
 				editedAt: new Date()
 				editedBy:
 					_id: Meteor.userId()
@@ -266,12 +283,33 @@ RocketChat.models.Messages = new class extends RocketChat.models._Base
 		message = user.username
 		return @createWithTypeRoomIdMessageAndUser 'au', roomId, message, user, extraData
 
-	createRoomRenamedWithRoomIdRoomNameAndUser: (roomId, roomName, user, extraData) ->
-		return @createWithTypeRoomIdMessageAndUser 'r', roomId, roomName, user, extraData
-
 	createCommandWithRoomIdAndUser: (command, roomId, user, extraData) ->
 		return @createWithTypeRoomIdMessageAndUser 'command', roomId, command, user, extraData
 
+	createUserMutedWithRoomIdAndUser: (roomId, user, extraData) ->
+		message = user.username
+		return @createWithTypeRoomIdMessageAndUser 'user-muted', roomId, message, user, extraData
+
+	createUserUnmutedWithRoomIdAndUser: (roomId, user, extraData) ->
+		message = user.username
+		return @createWithTypeRoomIdMessageAndUser 'user-unmuted', roomId, message, user, extraData
+
+	createNewModeratorWithRoomIdAndUser: (roomId, user, extraData) ->
+		message = user.username
+		return @createWithTypeRoomIdMessageAndUser 'new-moderator', roomId, message, user, extraData
+
+	createModeratorRemovedWithRoomIdAndUser: (roomId, user, extraData) ->
+		message = user.username
+		return @createWithTypeRoomIdMessageAndUser 'moderator-removed', roomId, message, user, extraData
+
+	createNewOwnerWithRoomIdAndUser: (roomId, user, extraData) ->
+		message = user.username
+		return @createWithTypeRoomIdMessageAndUser 'new-owner', roomId, message, user, extraData
+
+	createOwnerRemovedWithRoomIdAndUser: (roomId, user, extraData) ->
+		message = user.username
+		return @createWithTypeRoomIdMessageAndUser 'owner-removed', roomId, message, user, extraData
+
 	# REMOVE
 	removeById: (_id) ->
 		query =
diff --git a/packages/rocketchat-lib/server/models/Rooms.coffee b/packages/rocketchat-lib/server/models/Rooms.coffee
index e1588bc548419cc9003d11d04b401f48a17b91c0..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
@@ -278,6 +289,16 @@ RocketChat.models.Rooms = new class extends RocketChat.models._Base
 
 		return @update query, update, { multi: true }
 
+	replaceMutedUsername: (previousUsername, username) ->
+		query =
+			muted: previousUsername
+
+		update =
+			$set:
+				"muted.$": username
+
+		return @update query, update, { multi: true }
+
 	replaceUsernameOfUserByUserId: (userId, username) ->
 		query =
 			"u._id": userId
@@ -310,6 +331,36 @@ RocketChat.models.Rooms = new class extends RocketChat.models._Base
 
 		return @update query, update
 
+	setTopicById: (_id, topic) ->
+		query =
+			_id: _id
+
+		update =
+			$set:
+				topic: topic
+
+		return @update query, update
+
+	muteUsernameByRoomId: (_id, username) ->
+		query =
+			_id: _id
+
+		update =
+			$addToSet:
+				muted: username
+
+		return @update query, update
+
+	unmuteUsernameByRoomId: (_id, username) ->
+		query =
+			_id: _id
+
+		update =
+			$pull:
+				muted: username
+
+		return @update query, update
+
 
 	# INSERT
 	createWithTypeNameUserAndUsernames: (type, name, user, usernames, extraData) ->
diff --git a/packages/rocketchat-lib/server/models/Settings.coffee b/packages/rocketchat-lib/server/models/Settings.coffee
index 282c9262b6b84ce1760d023d325c86e77e0f534a..c16d51c83164c4e7fa6bd250e785d9625f6b12fb 100644
--- a/packages/rocketchat-lib/server/models/Settings.coffee
+++ b/packages/rocketchat-lib/server/models/Settings.coffee
@@ -37,6 +37,16 @@ RocketChat.models.Settings = new class extends RocketChat.models._Base
 		return @update query, update
 
 
+	updateOptionsById: (_id, options) ->
+		query =
+			_id: _id
+
+		update =
+			$set: options
+
+		return @update query, update
+
+
 	# REMOVE
 	createWithIdAndValue: (_id, value) ->
 		record =
diff --git a/packages/rocketchat-lib/server/models/Subscriptions.coffee b/packages/rocketchat-lib/server/models/Subscriptions.coffee
index 20910f4e03d88a568d093e31c3b51fb26d31817c..5a3248071206e749829baa63dfaee4668cb9dbf3 100644
--- a/packages/rocketchat-lib/server/models/Subscriptions.coffee
+++ b/packages/rocketchat-lib/server/models/Subscriptions.coffee
@@ -25,6 +25,15 @@ RocketChat.models.Subscriptions = new class extends RocketChat.models._Base
 
 		return @find query, options
 
+	# FIND
+	findByRoomIdAndRoles: (roomId, roles, options) ->
+		roles = [].concat roles
+		query =
+			"rid": roomId
+			"roles": { $in: roles }
+
+		return @find query, options
+
 	getLastSeen: (options = {}) ->
 		query = { ls: { $exists: 1 } }
 		options.sort = { ls: -1 }
@@ -54,7 +63,7 @@ RocketChat.models.Subscriptions = new class extends RocketChat.models._Base
 		update =
 			$set:
 				alert: false
-				open: false
+				open: true
 				archived: false
 
 		return @update query, update
@@ -210,6 +219,25 @@ RocketChat.models.Subscriptions = new class extends RocketChat.models._Base
 
 		return @update query, update, { multi: true }
 
+	addRoleById: (_id, role) ->
+		query =
+			_id: _id
+
+		update =
+			$addToSet:
+				roles: role
+
+		return @update query, update
+
+	removeRoleById: (_id, role) ->
+		query =
+			_id: _id
+
+		update =
+			$pull:
+				roles: role
+
+		return @update query, update
 
 	# INSERT
 	createWithRoomAndUser: (room, user, extraData) ->
diff --git a/packages/rocketchat-lib/server/models/Users.coffee b/packages/rocketchat-lib/server/models/Users.coffee
index f72dc4db3436451de00ad5e0e71fb58a1b1a3228..9e9aaf502b32de11d48ebaf9ba85b22d82944cc2 100644
--- a/packages/rocketchat-lib/server/models/Users.coffee
+++ b/packages/rocketchat-lib/server/models/Users.coffee
@@ -46,6 +46,13 @@ RocketChat.models.Users = new class extends RocketChat.models._Base
 
 		return @findOne query, options
 
+	findOneByIdAndLoginToken: (_id, token, options) ->
+		query =
+			_id: _id
+			'services.resume.loginTokens.hashedToken' : Accounts._hashLoginToken(token)
+
+		return @findOne query, options
+
 
 	# FIND
 	findUsersNotOffline: (options) ->
@@ -64,6 +71,24 @@ RocketChat.models.Users = new class extends RocketChat.models._Base
 
 		return @find query, options
 
+	findActiveByUsernameRegexWithExceptions: (username, exceptions = [], options = {}) ->
+		console.log 'findActiveByUsernameRegexWithExceptions', username, exceptions
+		if not _.isArray exceptions
+			exceptions = [ exceptions ]
+
+		usernameRegex = new RegExp username, "i"
+		query =
+			$and: [
+				{ active: true }
+				{ username: { $nin: exceptions } }
+				{ username: usernameRegex }
+			]
+			# username: { $regex: usernameRegex, $nin: exceptions }
+			# username: { $nin: exceptions }
+
+		console.log 'findActiveByUsernameRegexWithExceptions query', JSON.stringify query, null, ' '
+		return @find query, options
+
 	findByActiveUsersNameOrUsername: (nameOrUsername, options) ->
 		query =
 			username:
diff --git a/packages/rocketchat-lib/server/publications/settings.coffee b/packages/rocketchat-lib/server/publications/settings.coffee
index c3d5beb0a4f53965daaaf50ba273a9f58f457445..f5454f90107f514706575a3cc864cf7509427189 100644
--- a/packages/rocketchat-lib/server/publications/settings.coffee
+++ b/packages/rocketchat-lib/server/publications/settings.coffee
@@ -1,6 +1,4 @@
 Meteor.publish 'settings', (ids = []) ->
-	console.log '[publish] settings'.green
-
 	filter =
 		hidden: { $ne: true }
 		public: true
@@ -12,8 +10,6 @@ Meteor.publish 'settings', (ids = []) ->
 	return RocketChat.models.Settings.find filter, { fields: _id: 1, value: 1 }
 
 Meteor.publish 'admin-settings', ->
-	console.log '[publish] admin-settings'.green
-
 	unless @userId
 		return @ready()
 
diff --git a/packages/rocketchat-lib/server/startup/oAuthServicesUpdate.coffee b/packages/rocketchat-lib/server/startup/oAuthServicesUpdate.coffee
index eb796abc309180597f2d308c3b52b665e3eef8cc..75b30d643e2ef305a26c8c376331fce28505d090 100644
--- a/packages/rocketchat-lib/server/startup/oAuthServicesUpdate.coffee
+++ b/packages/rocketchat-lib/server/startup/oAuthServicesUpdate.coffee
@@ -29,12 +29,14 @@ oAuthServicesUpdate = ->
 					data.authorizePath = RocketChat.models.Settings.findOneById("#{service._id}_authorize_path")?.value
 					data.buttonLabelText = RocketChat.models.Settings.findOneById("#{service._id}_button_label_text")?.value
 					data.buttonLabelColor = RocketChat.models.Settings.findOneById("#{service._id}_button_label_color")?.value
+					data.loginStyle = RocketChat.models.Settings.findOneById("#{service._id}_login_style")?.value
 					data.buttonColor = RocketChat.models.Settings.findOneById("#{service._id}_button_color")?.value
 					new CustomOAuth serviceName.toLowerCase(),
 						serverURL: data.serverURL
 						tokenPath: data.tokenPath
 						identityPath: data.identityPath
 						authorizePath: data.authorizePath
+						loginStyle: data.loginStyle
 
 				if serviceName is 'Facebook'
 					data.appId = data.clientId
diff --git a/packages/rocketchat-lib/server/startup/settings.coffee b/packages/rocketchat-lib/server/startup/settings.coffee
index 688e0cd49248ab5b4c72fac8815bf16d46b54a28..4f3bf96d8cb93e636a585e5cad7bf8172fdef116 100644
--- a/packages/rocketchat-lib/server/startup/settings.coffee
+++ b/packages/rocketchat-lib/server/startup/settings.coffee
@@ -2,141 +2,169 @@
 if not RocketChat.models.Settings.findOneById 'uniqueID'
 	RocketChat.models.Settings.createWithIdAndValue 'uniqueID', Random.id()
 
-RocketChat.settings.addGroup 'Accounts'
-RocketChat.settings.add 'Accounts_EmailVerification', false, { type: 'boolean', group: 'Accounts', public: true, section: 'Registration' }
-RocketChat.settings.add 'Accounts_ManuallyApproveNewUsers', false, { type: 'boolean', group: 'Accounts', section: 'Registration' }
-RocketChat.settings.add 'Accounts_AllowedDomainsList', '', { type: 'string', group: 'Accounts', public: true, section: 'Registration' }
-
-RocketChat.settings.add 'Accounts_RegistrationForm', 'Public', { type: 'select', group: 'Accounts', public: true, section: 'Registration', values: [ { key: 'Public', i18nLabel: 'Accounts_RegistrationForm_Public' }, { key: 'Disabled', i18nLabel: 'Accounts_RegistrationForm_Disabled' }, { key: 'Secret URL', i18nLabel: 'Accounts_RegistrationForm_Secret_URL' } ] }
-RocketChat.settings.add 'Accounts_RegistrationForm_SecretURL', Random.id(), { type: 'string', group: 'Accounts', section: 'Registration' }
-RocketChat.settings.add 'Accounts_RegistrationForm_LinkReplacementText', 'New user registration is currently disabled', { type: 'string', group: 'Accounts', section: 'Registration', public: true }
-RocketChat.settings.add 'Accounts_Registration_AuthenticationServices_Enabled', true, { type: 'boolean', group: 'Accounts', section: 'Registration', public: true }
-
-RocketChat.settings.add 'Accounts_PasswordReset', true, { type: 'boolean', group: 'Accounts', public: true, section: 'Registration' }
-
-RocketChat.settings.add 'Accounts_AvatarStoreType', 'GridFS', { type: 'string', group: 'Accounts', section: 'Avatar' }
-RocketChat.settings.add 'Accounts_AvatarStorePath', '', { type: 'string', group: 'Accounts', section: 'Avatar' }
-RocketChat.settings.add 'Accounts_AvatarResize', false, { type: 'boolean', group: 'Accounts', section: 'Avatar' }
-RocketChat.settings.add 'Accounts_AvatarSize', 200, { type: 'int', group: 'Accounts', section: 'Avatar' }
-
-RocketChat.settings.add 'Accounts_OAuth_Facebook', false, { type: 'boolean', group: 'Accounts', section: 'Facebook', public: true }
-RocketChat.settings.add 'Accounts_OAuth_Facebook_id', '', { type: 'string', group: 'Accounts', section: 'Facebook' }
-RocketChat.settings.add 'Accounts_OAuth_Facebook_secret', '', { type: 'string', group: 'Accounts', section: 'Facebook' }
-RocketChat.settings.add 'Accounts_OAuth_Google', false, { type: 'boolean', group: 'Accounts', section: 'Google', public: true }
-RocketChat.settings.add 'Accounts_OAuth_Google_id', '', { type: 'string', group: 'Accounts', section: 'Google' }
-RocketChat.settings.add 'Accounts_OAuth_Google_secret', '', { type: 'string', group: 'Accounts', section: 'Google' }
-RocketChat.settings.add 'Accounts_OAuth_Github', false, { type: 'boolean', group: 'Accounts', section: 'Github', public: true }
-RocketChat.settings.add 'Accounts_OAuth_Github_id', '', { type: 'string', group: 'Accounts', section: 'Github' }
-RocketChat.settings.add 'Accounts_OAuth_Github_secret', '', { type: 'string', group: 'Accounts', section: 'Github' }
-RocketChat.settings.add 'Accounts_OAuth_Gitlab', false, { type: 'boolean', group: 'Accounts', section: 'Gitlab', public: true }
-RocketChat.settings.add 'Accounts_OAuth_Gitlab_id', '', { type: 'string', group: 'Accounts', section: 'Gitlab' }
-RocketChat.settings.add 'Accounts_OAuth_Gitlab_secret', '', { type: 'string', group: 'Accounts', section: 'Gitlab' }
-RocketChat.settings.add 'Accounts_OAuth_Linkedin', false, { type: 'boolean', group: 'Accounts', section: 'Linkedin', public: true }
-RocketChat.settings.add 'Accounts_OAuth_Linkedin_id', '', { type: 'string', group: 'Accounts', section: 'Linkedin' }
-RocketChat.settings.add 'Accounts_OAuth_Linkedin_secret', '', { type: 'string', group: 'Accounts', section: 'Linkedin' }
-RocketChat.settings.add 'Accounts_OAuth_Meteor', false, { type: 'boolean', group: 'Accounts', section: 'Meteor', public: true }
-RocketChat.settings.add 'Accounts_OAuth_Meteor_id', '', { type: 'string', group: 'Accounts', section: 'Meteor' }
-RocketChat.settings.add 'Accounts_OAuth_Meteor_secret', '', { type: 'string', group: 'Accounts', section: 'Meteor' }
-RocketChat.settings.add 'Accounts_OAuth_Twitter', false, { type: 'boolean', group: 'Accounts', section: 'Twitter', public: true }
-RocketChat.settings.add 'Accounts_OAuth_Twitter_id', '', { type: 'string', group: 'Accounts', section: 'Twitter' }
-RocketChat.settings.add 'Accounts_OAuth_Twitter_secret', '', { type: 'string', group: 'Accounts', section: 'Twitter' }
-
-RocketChat.settings.add 'Accounts_AllowUserProfileChange', true, { type: 'boolean', group: 'Accounts', section: 'General', public: true }
-RocketChat.settings.add 'Accounts_AllowUserAvatarChange', true, { type: 'boolean', group: 'Accounts', section: 'General', public: true }
-RocketChat.settings.add 'Accounts_AllowUsernameChange', true, { type: 'boolean', group: 'Accounts', section: 'General', public: true }
-RocketChat.settings.add 'Accounts_AllowPasswordChange', true, { type: 'boolean', group: 'Accounts', section: 'General', public: true }
-RocketChat.settings.add 'Accounts_RequireNameForSignUp', true, { type: 'boolean', group: 'Accounts', section: 'General', public: true }
-
-RocketChat.settings.add 'Accounts_LoginExpiration', 90, { type: 'int', group: 'Accounts', section: 'General', public: true }
-
-RocketChat.settings.addGroup 'FileUpload'
-RocketChat.settings.add 'FileUpload_Enabled', true, { type: 'boolean', group: 'FileUpload', public: true }
-RocketChat.settings.add 'FileUpload_MaxFileSize', 2097152, { type: 'int', group: 'FileUpload', public: true }
-RocketChat.settings.add 'FileUpload_MediaTypeWhiteList', 'image/*,audio/*,application/pdf,text/plain,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document', { type: 'string', group: 'FileUpload', public: true, i18nDescription: 'FileUpload_MediaTypeWhiteListDescription' }
-
-
-RocketChat.settings.addGroup 'General'
-RocketChat.settings.add 'Site_Url', __meteor_runtime_config__?.ROOT_URL, { type: 'string', group: 'General', i18nDescription: 'Site_Url_Description', public: true }
-RocketChat.settings.add 'Site_Name', 'Rocket.Chat', { type: 'string', group: 'General', public: true }
-RocketChat.settings.add 'Allow_Invalid_SelfSigned_Certs', false, { type: 'boolean', group: 'General' }
-RocketChat.settings.add 'Disable_Favorite_Rooms', false, { type: 'boolean', group: 'General' }
-RocketChat.settings.add 'CDN_PREFIX', '', { type: 'string', group: 'General' }
-RocketChat.settings.add 'Restart', 'restart_server', { type: 'action', group: 'General', actionText: 'Restart_the_server' }
-
-RocketChat.settings.add 'UTF8_Names_Validation', '[0-9a-zA-Z-_.]+', { type: 'string', group: 'General', section: 'UTF8', public: true  ,i18nDescription: 'UTF8_Names_Validation_Description'}
-RocketChat.settings.add 'UTF8_Names_Slugify', true, { type: 'boolean', group: 'General', section: 'UTF8', public: true }
-
-RocketChat.settings.addGroup 'API'
-RocketChat.settings.add 'API_Analytics', '', { type: 'string', group: 'API', public: true }
-RocketChat.settings.add 'API_Embed', true, { type: 'boolean', group: 'API', public: true }
-RocketChat.settings.add 'API_EmbedDisabledFor', '', { type: 'string', group: 'API', public: true, i18nDescription: 'API_EmbedDisabledFor_Description' }
-
-RocketChat.settings.addGroup 'SMTP'
-RocketChat.settings.add 'SMTP_Host', '', { type: 'string', group: 'SMTP' }
-RocketChat.settings.add 'SMTP_Port', '', { type: 'string', group: 'SMTP' }
-RocketChat.settings.add 'SMTP_Username', '', { type: 'string', group: 'SMTP' }
-RocketChat.settings.add 'SMTP_Password', '', { type: 'string', group: 'SMTP' }
-RocketChat.settings.add 'From_Email', '', { type: 'string', group: 'SMTP', placeholder: 'email@domain' }
-
-RocketChat.settings.add 'Invitation_Subject', 'You have been invited to Rocket.Chat', { type: 'string', group: 'SMTP', section: 'Invitation' }
-RocketChat.settings.add 'Invitation_HTML', '<h2>You have been invited to <h1>Rocket.Chat</h1></h2><p>Go to ' + __meteor_runtime_config__?.ROOT_URL + ' and try the best open source chat solution available today!</p>', { type: 'string', multiline: true, group: 'SMTP', section: 'Invitation' }
-RocketChat.settings.add 'Accounts_Enrollment_Email',  '', { type: 'string', multiline: true,  group: 'SMTP', section: 'Invitation' }
-
-RocketChat.settings.addGroup 'Message'
-RocketChat.settings.add 'Message_AllowEditing', true, { type: 'boolean', group: 'Message', public: true }
-RocketChat.settings.add 'Message_AllowEditing_BlockEditInMinutes', 0, { type: 'int', group: 'Message', public: true, i18nDescription: 'Message_AllowEditing_BlockEditInMinutesDescription' }
-RocketChat.settings.add 'Message_AllowDeleting', true, { type: 'boolean', group: 'Message', public: true }
-RocketChat.settings.add 'Message_AllowPinning', true, { type: 'boolean', group: 'Message', public: true }
-RocketChat.settings.add 'Message_ShowEditedStatus', true, { type: 'boolean', group: 'Message', public: true }
-RocketChat.settings.add 'Message_ShowDeletedStatus', false, { type: 'boolean', group: 'Message', public: true }
-RocketChat.settings.add 'Message_KeepHistory', false, { type: 'boolean', group: 'Message', public: true }
-RocketChat.settings.add 'Message_MaxAllowedSize', 5000, { type: 'int', group: 'Message', public: true }
-RocketChat.settings.add 'Message_ShowFormattingTips', true, { type: 'boolean', group: 'Message', public: true }
-RocketChat.settings.add 'Message_AudioRecorderEnabled', true, { type: 'boolean', group: 'Message', public: true, i18nDescription: 'Message_AudioRecorderEnabledDescription' }
-
-RocketChat.settings.addGroup 'Meta'
-RocketChat.settings.add 'Meta_language', '', { type: 'string', group: 'Meta' }
-RocketChat.settings.add 'Meta_fb_app_id', '', { type: 'string', group: 'Meta' }
-RocketChat.settings.add 'Meta_robots', '', { type: 'string', group: 'Meta' }
-RocketChat.settings.add 'Meta_google-site-verification', '', { type: 'string', group: 'Meta' }
-RocketChat.settings.add 'Meta_msvalidate01', '', { type: 'string', group: 'Meta' }
-
-RocketChat.settings.addGroup 'Push'
-RocketChat.settings.add 'Push_debug', false, { type: 'boolean', group: 'Push', public: true }
-RocketChat.settings.add 'Push_enable', true, { type: 'boolean', group: 'Push', public: true }
-RocketChat.settings.add 'Push_enable_gateway', true, { type: 'boolean', group: 'Push' }
-RocketChat.settings.add 'Push_gateway', 'https://rocket.chat', { type: 'string', group: 'Push' }
-RocketChat.settings.add 'Push_production', true, { type: 'boolean', group: 'Push', public: true }
-RocketChat.settings.add 'Push_test_push', 'push_test', { type: 'action', group: 'Push', actionText: 'Send_a_test_push_to_my_user' }
-RocketChat.settings.add 'Push_apn_passphrase', '', { type: 'string', group: 'Push', section: 'Certificates_and_Keys' }
-RocketChat.settings.add 'Push_apn_key', '', { type: 'string', multiline: true, group: 'Push', section: 'Certificates_and_Keys' }
-RocketChat.settings.add 'Push_apn_cert', '', { type: 'string', multiline: true, group: 'Push', section: 'Certificates_and_Keys' }
-RocketChat.settings.add 'Push_apn_dev_passphrase', '', { type: 'string', group: 'Push', section: 'Certificates_and_Keys' }
-RocketChat.settings.add 'Push_apn_dev_key', '', { type: 'string', multiline: true, group: 'Push', section: 'Certificates_and_Keys' }
-RocketChat.settings.add 'Push_apn_dev_cert', '', { type: 'string', multiline: true, group: 'Push', section: 'Certificates_and_Keys' }
-RocketChat.settings.add 'Push_gcm_api_key', '', { type: 'string', group: 'Push', section: 'Certificates_and_Keys' }
-RocketChat.settings.add 'Push_gcm_project_number', '', { type: 'string', group: 'Push', public: true, section: 'Certificates_and_Keys' }
-
-RocketChat.settings.addGroup 'Layout'
-RocketChat.settings.add 'Layout_Home_Title', 'Home', { type: 'string', group: 'Layout', public: true, section: 'Content' }
-RocketChat.settings.add 'Layout_Home_Body', 'Welcome to Rocket.Chat <br> Go to APP SETTINGS -> Layout to customize this intro.', { type: 'string', multiline: true, group: 'Layout', public: true, section: 'Content' }
-RocketChat.settings.add 'Layout_Terms_of_Service', 'Terms of Service <br> Go to APP SETTINGS -> Layout to customize this page.', { type: 'string', multiline: true, group: 'Layout', public: true, section: 'Content' }
-RocketChat.settings.add 'Layout_Privacy_Policy', 'Privacy Policy <br> Go to APP SETTINGS -> Layout to customize this page.', { type: 'string', multiline: true, group: 'Layout', public: true, section: 'Content' }
-RocketChat.settings.add 'Layout_Sidenav_Footer', '<div><a href="https://github.com/RocketChat/Rocket.Chat" class="logo" target="_blank"> <img src="/images/logo/logo.svg?v=3" /></a><div class="github-tagline"><span class="octicon octicon-pencil" style="color: #994C00"></span> with <span class="octicon octicon-heart" style="color: red"></span> on <span class="octicon octicon-mark-github"></span></div></div>', { type: 'string', group: 'Layout', public: true, i18nDescription: 'Layout_Sidenav_Footer_description' }
-RocketChat.settings.add 'Layout_Login_Header', '<a class="logo" href="/"><img src="/images/logo/logo.svg?v=3" /></a>', { type: 'string', multiline: true, group: 'Layout', public: true, section: 'Login' }
-RocketChat.settings.add 'Layout_Login_Terms', 'By proceeding to create your account and use Rocket.Chat, you are agreeing to our <a href="/terms-of-service">Terms of Service</a> and <a href="/privacy-policy">Privacy Policy</a>. If you do not agree, you cannot use Rocket.Chat.', { type: 'string', multiline: true, group: 'Layout', public: true, section: 'Login' }
+RocketChat.settings.addGroup 'Accounts', ->
+	@add 'Accounts_AllowUserProfileChange', true, { type: 'boolean', public: true }
+	@add 'Accounts_AllowUserAvatarChange', true, { type: 'boolean', public: true }
+	@add 'Accounts_AllowUsernameChange', true, { type: 'boolean', public: true }
+	@add 'Accounts_AllowPasswordChange', true, { type: 'boolean', public: true }
+	@add 'Accounts_RequireNameForSignUp', true, { type: 'boolean', public: true }
+	@add 'Accounts_LoginExpiration', 90, { type: 'int', public: true }
+	@add 'Accounts_ShowFormLogin', true, { type: 'boolean', public: true }
+
+	@section 'Registration', ->
+		@add 'Accounts_EmailVerification', false, { type: 'boolean', public: true }
+		@add 'Accounts_ManuallyApproveNewUsers', false, { type: 'boolean' }
+		@add 'Accounts_AllowedDomainsList', '', { type: 'string', public: true }
+		@add 'Accounts_RegistrationForm', 'Public', { type: 'select', public: true, values: [ { key: 'Public', i18nLabel: 'Accounts_RegistrationForm_Public' }, { key: 'Disabled', i18nLabel: 'Accounts_RegistrationForm_Disabled' }, { key: 'Secret URL', i18nLabel: 'Accounts_RegistrationForm_Secret_URL' } ] }
+		@add 'Accounts_RegistrationForm_SecretURL', Random.id(), { type: 'string' }
+		@add 'Accounts_RegistrationForm_LinkReplacementText', 'New user registration is currently disabled', { type: 'string', public: true }
+		@add 'Accounts_Registration_AuthenticationServices_Enabled', true, { type: 'boolean', public: true }
+		@add 'Accounts_PasswordReset', true, { type: 'boolean', public: true }
+
+	@section 'Avatar', ->
+		@add 'Accounts_AvatarResize', true, { type: 'boolean' }
+		@add 'Accounts_AvatarSize', 200, { type: 'int', enableQuery: {_id: 'Accounts_AvatarResize', value: true} }
+		@add 'Accounts_AvatarStoreType', 'GridFS', { type: 'select', values: [ { key: 'GridFS', i18nLabel: 'GridFS' }, { key: 'FileSystem', i18nLabel: 'FileSystem' } ] }
+		@add 'Accounts_AvatarStorePath', '', { type: 'string', enableQuery: {_id: 'Accounts_AvatarStoreType', value: 'FileSystem'} }
+
+	@section 'Facebook', ->
+		@add 'Accounts_OAuth_Facebook', false, { type: 'boolean', public: true }
+		@add 'Accounts_OAuth_Facebook_id', '', { type: 'string', enableQuery: {_id: 'Accounts_OAuth_Facebook', value: true} }
+		@add 'Accounts_OAuth_Facebook_secret', '', { type: 'string', enableQuery: {_id: 'Accounts_OAuth_Facebook', value: true} }
+
+	@section 'Google', ->
+		@add 'Accounts_OAuth_Google', false, { type: 'boolean', public: true }
+		@add 'Accounts_OAuth_Google_id', '', { type: 'string', enableQuery: {_id: 'Accounts_OAuth_Google', value: true} }
+		@add 'Accounts_OAuth_Google_secret', '', { type: 'string', enableQuery: {_id: 'Accounts_OAuth_Google', value: true} }
+
+	@section 'Github', ->
+		@add 'Accounts_OAuth_Github', false, { type: 'boolean', public: true }
+		@add 'Accounts_OAuth_Github_id', '', { type: 'string', enableQuery: {_id: 'Accounts_OAuth_Github', value: true} }
+		@add 'Accounts_OAuth_Github_secret', '', { type: 'string', enableQuery: {_id: 'Accounts_OAuth_Github', value: true} }
+
+	@section 'Gitlab', ->
+		@add 'Accounts_OAuth_Gitlab', false, { type: 'boolean', public: true }
+		@add 'Accounts_OAuth_Gitlab_id', '', { type: 'string', enableQuery: {_id: 'Accounts_OAuth_Gitlab', value: true} }
+		@add 'Accounts_OAuth_Gitlab_secret', '', { type: 'string', enableQuery: {_id: 'Accounts_OAuth_Gitlab', value: true} }
+
+	@section 'Linkedin', ->
+		@add 'Accounts_OAuth_Linkedin', false, { type: 'boolean', public: true }
+		@add 'Accounts_OAuth_Linkedin_id', '', { type: 'string', enableQuery: {_id: 'Accounts_OAuth_Linkedin', value: true} }
+		@add 'Accounts_OAuth_Linkedin_secret', '', { type: 'string', enableQuery: {_id: 'Accounts_OAuth_Linkedin', value: true} }
+
+	@section 'Meteor', ->
+		@add 'Accounts_OAuth_Meteor', false, { type: 'boolean', public: true }
+		@add 'Accounts_OAuth_Meteor_id', '', { type: 'string', enableQuery: {_id: 'Accounts_OAuth_Meteor', value: true} }
+		@add 'Accounts_OAuth_Meteor_secret', '', { type: 'string', enableQuery: {_id: 'Accounts_OAuth_Meteor', value: true} }
+
+	@section 'Twitter', ->
+		@add 'Accounts_OAuth_Twitter', false, { type: 'boolean', public: true }
+		@add 'Accounts_OAuth_Twitter_id', '', { type: 'string', enableQuery: {_id: 'Accounts_OAuth_Twitter', value: true} }
+		@add 'Accounts_OAuth_Twitter_secret', '', { type: 'string', enableQuery: {_id: 'Accounts_OAuth_Twitter', value: true} }
+
+
+RocketChat.settings.addGroup 'FileUpload', ->
+	@add 'FileUpload_Enabled', true, { type: 'boolean', public: true }
+	@add 'FileUpload_MaxFileSize', 2097152, { type: 'int', public: true }
+	@add 'FileUpload_MediaTypeWhiteList', 'image/*,audio/*,application/pdf,text/plain,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document', { type: 'string', public: true, i18nDescription: 'FileUpload_MediaTypeWhiteListDescription' }
+	@add 'FileUpload_ProtectFiles', true, { type: 'boolean', public: true, i18nDescription: 'FileUpload_ProtectFilesDescription' }
+
+
+RocketChat.settings.addGroup 'General', ->
+	@add 'Site_Url', __meteor_runtime_config__?.ROOT_URL, { type: 'string', i18nDescription: 'Site_Url_Description', public: true }
+	@add 'Site_Name', 'Rocket.Chat', { type: 'string', public: true }
+	@add 'Language', '', { type: 'language', public: true }
+	@add 'Allow_Invalid_SelfSigned_Certs', false, { type: 'boolean' }
+	@add 'Disable_Favorite_Rooms', false, { type: 'boolean' }
+	@add 'CDN_PREFIX', '', { type: 'string' }
+	@add 'Force_SSL', false, { type: 'boolean', public: true }
+	@add 'Debug_Level', 'error', { type: 'select', values: [ { key: 'error', i18nLabel: 'Only_errors' }, { key: 'debug', i18nLabel: 'All_logs' } ] }
+	@add 'Restart', 'restart_server', { type: 'action', actionText: 'Restart_the_server' }
+
+	@section 'UTF8', ->
+		@add 'UTF8_Names_Validation', '[0-9a-zA-Z-_.]+', { type: 'string', public: true, i18nDescription: 'UTF8_Names_Validation_Description'}
+		@add 'UTF8_Names_Slugify', true, { type: 'boolean', public: true }
+
+
+RocketChat.settings.addGroup 'API', ->
+	@add 'API_Analytics', '', { type: 'string', public: true }
+	@add 'API_Embed', true, { type: 'boolean', public: true }
+	@add 'API_EmbedDisabledFor', '', { type: 'string', public: true, i18nDescription: 'API_EmbedDisabledFor_Description' }
+
+
+RocketChat.settings.addGroup 'SMTP', ->
+	@add 'SMTP_Host', '', { type: 'string', env: true }
+	@add 'SMTP_Port', '', { type: 'string', env: true }
+	@add 'SMTP_Username', '', { type: 'string', env: true }
+	@add 'SMTP_Password', '', { type: 'string', env: true }
+	@add 'From_Email', '', { type: 'string', placeholder: 'email@domain' }
+	@add 'SMTP_Test_Button', 'sendSMTPTestEmail', { type: 'action', actionText: 'Send_a_test_mail_to_my_user' }
+
+	@section 'Invitation', ->
+		@add 'Invitation_Subject', 'You have been invited to Rocket.Chat', { type: 'string' }
+		@add 'Invitation_HTML', '<h2>You have been invited to <h1>Rocket.Chat</h1></h2><p>Go to ' + __meteor_runtime_config__?.ROOT_URL + ' and try the best open source chat solution available today!</p>', { type: 'string', multiline: true }
+		@add 'Accounts_Enrollment_Email',  '', { type: 'string', multiline: true }
+
+
+RocketChat.settings.addGroup 'Message', ->
+	@add 'Message_AllowEditing', true, { type: 'boolean', public: true }
+	@add 'Message_AllowEditing_BlockEditInMinutes', 0, { type: 'int', public: true, i18nDescription: 'Message_AllowEditing_BlockEditInMinutesDescription' }
+	@add 'Message_AllowDeleting', true, { type: 'boolean', public: true }
+	@add 'Message_AllowPinning', true, { type: 'boolean', public: true }
+	@add 'Message_ShowEditedStatus', true, { type: 'boolean', public: true }
+	@add 'Message_ShowDeletedStatus', false, { type: 'boolean', public: true }
+	@add 'Message_KeepHistory', false, { type: 'boolean', public: true }
+	@add 'Message_MaxAllowedSize', 5000, { type: 'int', public: true }
+	@add 'Message_ShowFormattingTips', true, { type: 'boolean', public: true }
+	@add 'Message_AudioRecorderEnabled', true, { type: 'boolean', public: true, i18nDescription: 'Message_AudioRecorderEnabledDescription' }
+	@add 'Message_GroupingPeriod', 300, { type: 'int', public: true, i18nDescription: 'Message_GroupingPeriodDescription' }
+
+
+RocketChat.settings.addGroup 'Meta', ->
+	@add 'Meta_language', '', { type: 'string' }
+	@add 'Meta_fb_app_id', '', { type: 'string' }
+	@add 'Meta_robots', '', { type: 'string' }
+	@add 'Meta_google-site-verification', '', { type: 'string' }
+	@add 'Meta_msvalidate01', '', { type: 'string' }
+
+
+RocketChat.settings.addGroup 'Push', ->
+	@add 'Push_debug', false, { type: 'boolean', public: true }
+	@add 'Push_enable', true, { type: 'boolean', public: true }
+	@add 'Push_enable_gateway', true, { type: 'boolean' }
+	@add 'Push_gateway', 'https://rocket.chat', { type: 'string' }
+	@add 'Push_production', true, { type: 'boolean', public: true }
+	@add 'Push_test_push', 'push_test', { type: 'action', actionText: 'Send_a_test_push_to_my_user' }
+
+	@section 'Certificates_and_Keys', ->
+		@add 'Push_apn_passphrase', '', { type: 'string' }
+		@add 'Push_apn_key', '', { type: 'string', multiline: true }
+		@add 'Push_apn_cert', '', { type: 'string', multiline: true }
+		@add 'Push_apn_dev_passphrase', '', { type: 'string' }
+		@add 'Push_apn_dev_key', '', { type: 'string', multiline: true }
+		@add 'Push_apn_dev_cert', '', { type: 'string', multiline: true }
+		@add 'Push_gcm_api_key', '', { type: 'string' }
+		@add 'Push_gcm_project_number', '', { type: 'string', public: true }
+
+
+RocketChat.settings.addGroup 'Layout', ->
+	@add 'Layout_Sidenav_Footer', '<div><a href="https://github.com/RocketChat/Rocket.Chat" class="logo" target="_blank"> <img src="/images/logo/logo.svg?v=3" /></a><div class="github-tagline"><span class="octicon octicon-pencil" style="color: #994C00"></span> with <span class="octicon octicon-heart" style="color: red"></span> on <span class="octicon octicon-mark-github"></span></div></div>', { type: 'string', public: true, i18nDescription: 'Layout_Sidenav_Footer_description' }
+
+	@section 'Content', ->
+		@add 'Layout_Home_Title', 'Home', { type: 'string', public: true }
+		@add 'Layout_Home_Body', 'Welcome to Rocket.Chat <br> Go to APP SETTINGS -> Layout to customize this intro.', { type: 'string', multiline: true, public: true }
+		@add 'Layout_Terms_of_Service', 'Terms of Service <br> Go to APP SETTINGS -> Layout to customize this page.', { type: 'string', multiline: true, public: true }
+		@add 'Layout_Privacy_Policy', 'Privacy Policy <br> Go to APP SETTINGS -> Layout to customize this page.', { type: 'string', multiline: true, public: true }
+
+	@section 'Login', ->
+		@add 'Layout_Login_Header', '<a class="logo" href="/"><img src="/images/logo/logo.svg?v=3" /></a>', { type: 'string', multiline: true, public: true }
+		@add 'Layout_Login_Terms', 'By proceeding to create your account and use Rocket.Chat, you are agreeing to our <a href="/terms-of-service">Terms of Service</a> and <a href="/privacy-policy">Privacy Policy</a>. If you do not agree, you cannot use Rocket.Chat.', { type: 'string', multiline: true, public: true }
+
 
 RocketChat.settings.add 'Statistics_opt_out', false, { type: 'boolean', group: false }
 
 RocketChat.settings.init()
 
-Meteor.startup ->
-	if process?.env? and not process.env['MAIL_URL']? and RocketChat.settings.get('SMTP_Host') and RocketChat.settings.get('SMTP_Username') and RocketChat.settings.get('SMTP_Password')
-		process.env['MAIL_URL'] = "smtp://" + encodeURIComponent(RocketChat.settings.get('SMTP_Username')) + ':' + encodeURIComponent(RocketChat.settings.get('SMTP_Password')) + '@' + encodeURIComponent(RocketChat.settings.get('SMTP_Host'))
-		if RocketChat.settings.get('SMTP_Port')
-			process.env['MAIL_URL'] += ':' + parseInt(RocketChat.settings.get('SMTP_Port'))
-
-
 # Remove runtime settings (non-persistent)
 Meteor.startup ->
 	RocketChat.models.Settings.update({ ts: { $lt: RocketChat.settings.ts }, persistent: { $ne: true } }, { $set: { hidden: true } }, { multi: true })
diff --git a/packages/rocketchat-lib/server/startup/settingsOnLoadSMTP.coffee b/packages/rocketchat-lib/server/startup/settingsOnLoadSMTP.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..67dfa65a82d2cb2374fd0dceacea0adcd4c6409a
--- /dev/null
+++ b/packages/rocketchat-lib/server/startup/settingsOnLoadSMTP.coffee
@@ -0,0 +1,28 @@
+buildMailURL = _.debounce ->
+	console.log 'Updating process.env.MAIL_URL'
+	if RocketChat.settings.get('SMTP_Host')
+		process.env.MAIL_URL = "smtp://"
+		if RocketChat.settings.get('SMTP_Username') and RocketChat.settings.get('SMTP_Password')
+                        process.env.MAIL_URL += encodeURIComponent(RocketChat.settings.get('SMTP_Username')) + ':' + encodeURIComponent(RocketChat.settings.get('SMTP_Password')) + '@'
+                process.env.MAIL_URL += encodeURIComponent(RocketChat.settings.get('SMTP_Host'))
+		if RocketChat.settings.get('SMTP_Port')
+			process.env.MAIL_URL += ':' + parseInt(RocketChat.settings.get('SMTP_Port'))
+, 500
+
+RocketChat.settings.onload 'SMTP_Host', (key, value, initialLoad) ->
+	if _.isString value
+		buildMailURL()
+
+RocketChat.settings.onload 'SMTP_Port', (key, value, initialLoad) ->
+	buildMailURL()
+
+RocketChat.settings.onload 'SMTP_Username', (key, value, initialLoad) ->
+	if _.isString value
+		buildMailURL()
+
+RocketChat.settings.onload 'SMTP_Password', (key, value, initialLoad) ->
+	if _.isString value
+		buildMailURL()
+
+Meteor.startup ->
+	buildMailURL()
diff --git a/packages/rocketchat-livechat/app/.meteor/packages b/packages/rocketchat-livechat/app/.meteor/packages
index 2f093f9100633e0fd58a54206b268cc3a555239b..83352a667a8daa77adcac18c085970cd760072e1 100644
--- a/packages/rocketchat-livechat/app/.meteor/packages
+++ b/packages/rocketchat-livechat/app/.meteor/packages
@@ -36,3 +36,5 @@ accounts-password
 standard-minifiers
 tap:i18n
 kevohagan:sweetalert
+ecmascript
+es5-shim
diff --git a/packages/rocketchat-livechat/app/.meteor/versions b/packages/rocketchat-livechat/app/.meteor/versions
index 34a2055ee61dc848e2ce7ba89515432a142a3791..3105a3bc809018b69d429eb62a7e20ba24c33fd9 100644
--- a/packages/rocketchat-livechat/app/.meteor/versions
+++ b/packages/rocketchat-livechat/app/.meteor/versions
@@ -27,6 +27,7 @@ ecmascript@0.1.6
 ecmascript-runtime@0.2.6
 ejson@1.0.7
 email@1.0.8
+es5-shim@4.1.14
 geojson-utils@1.0.4
 html-tools@1.0.5
 htmljs@1.0.5
diff --git a/packages/rocketchat-livechat/app/client/lib/chatMessages.coffee b/packages/rocketchat-livechat/app/client/lib/chatMessages.coffee
index 2cee37e8e78ff79d5d921e54e590336b5743cabf..842976af3615e7e0d5311a866ea29e6217fbac4d 100644
--- a/packages/rocketchat-livechat/app/client/lib/chatMessages.coffee
+++ b/packages/rocketchat-livechat/app/client/lib/chatMessages.coffee
@@ -93,11 +93,11 @@ class @ChatMessages
 							showError error.reason
 
 			if not Meteor.userId()
-				Meteor.call 'registerGuest', visitor.getToken(), (error, result) ->
+				Meteor.call 'livechat:registerGuest', { token: visitor.getToken() }, (error, result) ->
 					if error?
 						return showError error.reason
 
-					Meteor.loginWithPassword result.user, result.pass, (error) ->
+					Meteor.loginWithToken result.token, (error) ->
 						if error
 							return showError error.reason
 
diff --git a/packages/rocketchat-livechat/app/client/lib/collections.coffee b/packages/rocketchat-livechat/app/client/lib/collections.coffee
index 48b9e6fcd371f79351bdcf63768bc4c9b9d07740..c86ad59f9dde87d990bf26b7e8aa5ef400b6fc53 100644
--- a/packages/rocketchat-livechat/app/client/lib/collections.coffee
+++ b/packages/rocketchat-livechat/app/client/lib/collections.coffee
@@ -1,3 +1,5 @@
 @ChatMessage = new Meteor.Collection null
 @ChatRoom = new Meteor.Collection 'rocketchat_room'
 @Settings = new Meteor.Collection 'rocketchat_settings'
+@Trigger = new Meteor.Collection 'rocketchat_livechat_trigger'
+@Department = new Meteor.Collection 'rocketchat_livechat_department'
diff --git a/packages/rocketchat-livechat/app/client/lib/fromApp/RoomHistoryManager.coffee b/packages/rocketchat-livechat/app/client/lib/fromApp/RoomHistoryManager.coffee
index c12bd00df8d2a45e0b35ff3c4f915a223ef17e21..d21a2a296144c0c111377321e28972a2e5a63c67 100644
--- a/packages/rocketchat-livechat/app/client/lib/fromApp/RoomHistoryManager.coffee
+++ b/packages/rocketchat-livechat/app/client/lib/fromApp/RoomHistoryManager.coffee
@@ -30,6 +30,8 @@
 			ts = new Date
 
 		Meteor.call 'loadHistory', rid, ts, limit, undefined, (err, result) ->
+			return if err?
+
 			for item in result?.messages or []
 				if item.t isnt 'command'
 					ChatMessage.upsert {_id: item._id}, item
diff --git a/packages/rocketchat-livechat/app/client/lib/hooks.js b/packages/rocketchat-livechat/app/client/lib/hooks.js
new file mode 100644
index 0000000000000000000000000000000000000000..1342000e2ed72e039c070b290e15785e39aac62c
--- /dev/null
+++ b/packages/rocketchat-livechat/app/client/lib/hooks.js
@@ -0,0 +1,21 @@
+var api = {
+	pageVisited: function(info) {
+		Triggers.processRequest(info);
+
+		Meteor.call('livechat:pageVisited', visitor.getToken(), info);
+	}
+};
+
+window.addEventListener('message', function(msg) {
+	if (typeof msg.data === 'object' && msg.data.src !== undefined && msg.data.src === 'rocketchat') {
+		if (api[msg.data.fn] !== undefined && typeof api[msg.data.fn] === 'function') {
+			var args = [].concat(msg.data.args || [])
+			api[msg.data.fn].apply(null, args);
+		}
+	}
+}, false);
+
+// tell parent window that we are ready
+Meteor.startup(function() {
+	parentCall('ready');
+});
diff --git a/packages/rocketchat-livechat/app/client/lib/triggers.js b/packages/rocketchat-livechat/app/client/lib/triggers.js
new file mode 100644
index 0000000000000000000000000000000000000000..354e55d986d50e2c553a95d5ba12d06234c6b042
--- /dev/null
+++ b/packages/rocketchat-livechat/app/client/lib/triggers.js
@@ -0,0 +1,79 @@
+this.Triggers = (function() {
+	var triggers = [];
+	var initiated = false;
+	var requests = [];
+
+	var init = function() {
+		initiated = true;
+		Tracker.autorun(function() {
+			triggers = Trigger.find().fetch();
+
+			if (requests.length > 0 && triggers.length > 0) {
+				requests.forEach(function(request) {
+					processRequest(request);
+				});
+
+				requests = [];
+			}
+		});
+	};
+
+	var fire = function(actions) {
+		if (Meteor.userId()) {
+			console.log('already logged user - does nothing');
+			return;
+		}
+		actions.forEach(function(action) {
+			if (action.name === 'send-message') {
+				var roomId = visitor.getRoom();
+
+				if (!roomId) {
+					roomId = Random.id();
+					visitor.setRoom(roomId);
+				}
+
+				Session.set('triggered', true);
+				ChatMessage.insert({
+					msg: action.params.msg,
+					rid: roomId,
+					u: {
+						username: action.params.name
+					}
+				});
+
+				parentCall('openWidget');
+			}
+		});
+	};
+
+	var processRequest = function(request) {
+		if (!initiated) {
+			return requests.push(request);
+		}
+		triggers.forEach(function(trigger) {
+			trigger.conditions.forEach(function(condition) {
+				switch (condition.name) {
+					case 'page-url':
+						if (request.location.href.match(new RegExp(condition.value))) {
+							fire(trigger.actions);
+						}
+						break;
+
+					case 'time-on-site':
+						if (trigger.timeout) {
+							clearTimeout(trigger.timeout);
+						}
+						trigger.timeout = setTimeout(function() {
+							fire(trigger.actions);
+						}, parseInt(condition.value) * 1000);
+						break;
+				}
+			});
+		});
+	};
+
+	return {
+		init: init,
+		processRequest: processRequest
+	};
+})();
diff --git a/packages/rocketchat-livechat/app/client/routes/router.coffee b/packages/rocketchat-livechat/app/client/routes/router.coffee
index 1105938efd909a826cdff2c173366956960a41f9..6b1712849214f691f2ef3fc8c8c8f8c94955b1dd 100644
--- a/packages/rocketchat-livechat/app/client/routes/router.coffee
+++ b/packages/rocketchat-livechat/app/client/routes/router.coffee
@@ -9,4 +9,4 @@ FlowRouter.route '/livechat',
 	]
 
 	action: ->
-		BlazeLayout.render 'main', {center: 'room'}
+		BlazeLayout.render 'main', {center: 'livechatWindow'}
diff --git a/packages/rocketchat-livechat/app/client/startup/triggers.js b/packages/rocketchat-livechat/app/client/startup/triggers.js
new file mode 100644
index 0000000000000000000000000000000000000000..71cfdb1d0d95d6f0fc2783c61a3925a12180bb52
--- /dev/null
+++ b/packages/rocketchat-livechat/app/client/startup/triggers.js
@@ -0,0 +1,5 @@
+Meteor.startup(function() {
+	Meteor.subscribe('livechat:trigger', function() {
+		Triggers.init()
+	});
+});
diff --git a/packages/rocketchat-livechat/app/client/stylesheets/_variables.less b/packages/rocketchat-livechat/app/client/stylesheets/_variables.less
index e746bcf8cad8bb6c265e9615ce822df0fe6abe1e..d054cb4339ebf5cb56dea163696ef83819bcc777 100644
--- a/packages/rocketchat-livechat/app/client/stylesheets/_variables.less
+++ b/packages/rocketchat-livechat/app/client/stylesheets/_variables.less
@@ -1,5 +1,5 @@
 @header-min-height: 30px;
-@footer-min-height: 42px;
+@footer-min-height: 55px;
 
 @rooms-box-width: 260px;
 @flex-tab-width: 400px;
diff --git a/packages/rocketchat-livechat/app/client/stylesheets/main.less b/packages/rocketchat-livechat/app/client/stylesheets/main.less
index 1335a0114511bdc8c618d0986be524aa5358aeb3..afcc4fcf35a05107fa665c8b2582df9ec2fa036b 100644
--- a/packages/rocketchat-livechat/app/client/stylesheets/main.less
+++ b/packages/rocketchat-livechat/app/client/stylesheets/main.less
@@ -1,4 +1,3 @@
-@import url(//fonts.googleapis.com/css?family=Roboto:300,400,500,600,700&subset=latin,cyrillic-ext,greek-ext,greek,vietnamese,latin-ext,cyrillic);
 @import "_variables.less";
 @import "utils/_lesshat.import.less";
 @import "utils/_reset.import.less";
@@ -13,11 +12,9 @@ html, body {
 	height: 100%;
 }
 body {
-	padding: 0;
 	margin: 0;
-	font-size: 10pt;
-	font-family: "Roboto", "HelveticaNeue", sans-serif;
-	// font-size: 14px;
+	font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif, "Meiryo UI";
+	font-size: 0.8rem;
 	color: @primary-font-color;
 	height: 100%;
 	width: 100%;
@@ -36,6 +33,11 @@ textarea {
 	font-family: inherit;
 	font-size: inherit;
 	line-height: inherit;
+	padding: 5px;
+	margin: 5px;
+	border: 1px solid #E7E7E7;
+	border-radius: 5px;
+	outline: none;
 }
 
 input:focus {
@@ -54,6 +56,7 @@ input:focus {
 	word-spacing: 0;
 	box-shadow: 1px 1px 0 rgba(0, 0, 0, 0.125);
 	border: none;
+	border-radius: 0;
 	line-height: 16px;
 	position: relative;
 	cursor: pointer;background-color: #FFF;
@@ -334,7 +337,7 @@ input:focus {
 		}
 
 		.error {
-			bottom: 40px;
+			bottom: @footer-min-height;
 			position: fixed;
 			width: 100%;
 			background-color: #F7D799;
@@ -360,16 +363,14 @@ input:focus {
 		border-right: 1px solid #E7E7E7;
 
 		.input-wrapper {
-			padding: 6px;
+			padding: 6px 6px 0 6px;
 			textarea {
 				display: block;
 				padding: 6px 8px;
 				padding-right: 38px;
 				overflow-y: auto;
 				resize: none;
-				border: 1px solid #E7E7E7;
-				// margin: 10px;
-				border-radius: 5px;
+				margin: 0;
 				max-height: 200px;
 				width: 100%;
 				font-size: 12px;
@@ -378,7 +379,6 @@ input:focus {
 				line-height: normal;
 				background-color: #fff;
 				position: relative;
-				outline: none;
 			}
 		}
 	}
@@ -397,12 +397,12 @@ input:focus {
 	background-color: #FFF;
 	border-left: 1px solid #E7E7E7;
 	border-right: 1px solid #E7E7E7;
+	padding: 5px;
 
-	input, button {
+	input, button, select {
 		display: block;
-		padding: 5px;
-		margin: 5px;
 	}
+
 	.error {
 		display: none;
 		// width: 100%;
@@ -425,54 +425,85 @@ input:focus {
 		position: fixed;
 		height: 100%;
 		width: 100%;
+		z-index: 9990;
+		top: 0;
+		left: 0;
+	}
 
-		.wrapper {
-			background: white;
-			position: fixed;
-			height: 60vh;
-			width: 60vw;
-			top: 20vh;
-			left: 20vw;
-			border-radius: 6px;
-			display: flex;
-			flex-direction: column;
-
-			header {
-				flex: 1 0 40px;
-				padding: 0 15px;
-				border-bottom: 1px solid rgba(0, 0, 0, 0.1);
-				line-height: 40px;
-			}
+	.wrapper {
+		z-index: 9999;
+		background: white;
+		position: fixed;
+		height: 60vh;
+		width: 60vw;
+		top: 20vh;
+		left: 20vw;
+		border-radius: 6px;
+		display: flex;
+		flex-direction: column;
+
+		header {
+			flex: 1 0 40px;
+			padding: 0 15px;
+			border-bottom: 1px solid rgba(0, 0, 0, 0.1);
+			line-height: 40px;
+		}
 
-			.content {
-				overflow-y: scroll;
-				padding: 10px;
-				flex: 1 1 100%;
+		.content {
+			overflow-y: scroll;
+			padding: 10px;
+			flex: 1 1 100%;
 
-				.instructions {
-					margin-top: 5px;
-				}
+			.instructions {
+				margin-top: 5px;
+			}
 
-				.survey-item {
-					margin-top: 20px;
+			.survey-item {
+				margin-top: 20px;
 
-					.question {
-						display: block;
-					}
+				.question {
+					display: block;
+				}
 
-					.answer {
-						margin-right: 5px;
-					}
+				.answer {
+					margin-right: 5px;
+					display: inline-block;
+					text-align: center;
 				}
 			}
+		}
 
-			footer {
-				flex: 1 0 60px;
-				border-top: 1px solid rgba(0, 0, 0, 0.1);
-				line-height: 60px;
-				text-align: right;
-				padding-right: 20px;
-			}
+		footer {
+			flex: 1 0 60px;
+			border-top: 1px solid rgba(0, 0, 0, 0.1);
+			line-height: 60px;
+			text-align: right;
+			padding-right: 20px;
+		}
+	}
+}
+
+.powered-by {
+	text-align: right;
+	font-size: 0.65rem;
+	height: 20px;
+	line-height: 20px;
+	color: #666;
+	padding: 0 1em;
+	opacity: 0.5;
+
+	.transition(opacity .15s ease-out);
+
+	&:hover {
+		opacity: 1;
+	}
+
+	a {
+		text-decoration: none;
+		margin-left: 1px;
+		img {
+			height: 14px;
+			vertical-align: middle;
 		}
 	}
 }
diff --git a/packages/rocketchat-livechat/app/client/views/room.html b/packages/rocketchat-livechat/app/client/views/livechatWindow.html
similarity index 68%
rename from packages/rocketchat-livechat/app/client/views/room.html
rename to packages/rocketchat-livechat/app/client/views/livechatWindow.html
index 0220ed9abfa61b5216c72c5ca2429ece0897f2f3..91618ab52262b837081e4cfad2622fe6754b9bd4 100644
--- a/packages/rocketchat-livechat/app/client/views/room.html
+++ b/packages/rocketchat-livechat/app/client/views/livechatWindow.html
@@ -1,4 +1,4 @@
-<template name="room">
+<template name="livechatWindow">
 	{{#if livechatStartedEnabled}}
 		<div class="livechat-room">
 			<div class="title" style="background-color:{{color}}">
@@ -10,14 +10,15 @@
 				</div>
 				<h1>{{title}}</h1>
 			</div>
-			{{#if currentUser}}
-				{{> messages}}
-			{{else}}
-				{{#if livechatEnabled}}
+
+			{{#if livechatEnabled}}
+				{{#if showRegisterForm}}
 					{{> register}}
 				{{else}}
-					<div class="offline">{{_ "We_are_offline_Sorry_for_the_inconvenience"}}</div>
+					{{> messages}}
 				{{/if}}
+			{{else}}
+				<div class="offline">{{_ "We_are_offline_Sorry_for_the_inconvenience"}}</div>
 			{{/if}}
 		</div>
 	{{/if}}
diff --git a/packages/rocketchat-livechat/app/client/views/room.js b/packages/rocketchat-livechat/app/client/views/livechatWindow.js
similarity index 56%
rename from packages/rocketchat-livechat/app/client/views/room.js
rename to packages/rocketchat-livechat/app/client/views/livechatWindow.js
index a844293decb8b1d2f93df988525d8da7aa6b32b3..c566d31ddd55201e50a644bb2fa0a73aa86f2ccd 100644
--- a/packages/rocketchat-livechat/app/client/views/room.js
+++ b/packages/rocketchat-livechat/app/client/views/livechatWindow.js
@@ -1,57 +1,62 @@
-Template.room.helpers({
-	title: function() {
+Template.livechatWindow.helpers({
+	title() {
 		var ref;
 		if (!Template.instance().subscriptionsReady()) {
 			return '';
 		}
 		return ((ref = Settings.findOne('Livechat_title')) != null ? ref.value : void 0) || 'Rocket.Chat';
 	},
-	color: function() {
+	color() {
 		var ref;
 		if (!Template.instance().subscriptionsReady()) {
 			return 'transparent';
 		}
 		return ((ref = Settings.findOne('Livechat_title_color')) != null ? ref.value : void 0) || '#C1272D';
 	},
-	popoutActive: function() {
+	popoutActive() {
 		return FlowRouter.getQueryParam('mode') === 'popout';
 	},
-	livechatStartedEnabled: function() {
+	showRegisterForm() {
+		if (Session.get('triggered')  || Meteor.userId()) {
+			return false;
+		}
+		var form = Settings.findOne('Livechat_registration_form');
+		return form.value;
+	},
+	livechatStartedEnabled() {
 		return Template.instance().startedEnabled.get() !== null;
 	},
-	livechatEnabled: function() {
+	livechatEnabled() {
 		return Template.instance().startedEnabled.get();
 	}
 });
 
-Template.room.events({
-	'click .title': function() {
+Template.livechatWindow.events({
+	'click .title'() {
 		parentCall('toggleWindow');
 	},
-	'click .popout': function(event) {
+	'click .popout'(event) {
 		event.stopPropagation();
 		parentCall('openPopout');
 	}
 });
 
-Template.room.onCreated(function() {
-	self = this;
-
-	self.startedEnabled = new ReactiveVar(null);
+Template.livechatWindow.onCreated(function() {
+	this.startedEnabled = new ReactiveVar(null);
 
-	self.subscribe('settings', ['Livechat_title', 'Livechat_title_color', 'Livechat_enabled']);
+	this.subscribe('settings', ['Livechat_title', 'Livechat_title_color', 'Livechat_enabled', 'Livechat_registration_form']);
 
 	var initialCheck = true;
 
-	self.autorun(function() {
-		if (self.subscriptionsReady()) {
+	this.autorun(() => {
+		if (this.subscriptionsReady()) {
 			var enabled = Settings.findOne('Livechat_enabled');
 			if (enabled !== undefined) {
 				if (!enabled.value && initialCheck) {
 					parentCall('removeWidget');
 				}
 				initialCheck = false;
-				self.startedEnabled.set(enabled.value);
+				this.startedEnabled.set(enabled.value);
 			}
 		}
 	});
diff --git a/packages/rocketchat-livechat/app/client/views/message.coffee b/packages/rocketchat-livechat/app/client/views/message.coffee
index 1b49884bd821812463129ca722f73cee1b784c45..87cc3d9164e9d2d7a4ae436ccbcc0412bc9ef666 100644
--- a/packages/rocketchat-livechat/app/client/views/message.coffee
+++ b/packages/rocketchat-livechat/app/client/views/message.coffee
@@ -4,7 +4,7 @@ Template.message.helpers
 		return 'own' if this.u?._id is Meteor.userId()
 
 	time: ->
-		return moment(this.ts).format('HH:mm')
+		return moment(this.ts).format('LT')
 
 	date: ->
 		return moment(this.ts).format('LL')
diff --git a/packages/rocketchat-livechat/app/client/views/messages.html b/packages/rocketchat-livechat/app/client/views/messages.html
index 8bfbfd49b62fc84b8eeddac63fc1065ea9621689..8e3fe168b7d5c414af50acd9e875fbf0562b8671 100644
--- a/packages/rocketchat-livechat/app/client/views/messages.html
+++ b/packages/rocketchat-livechat/app/client/views/messages.html
@@ -19,5 +19,11 @@
 		<div class="input-wrapper">
 			<textarea class="input-message" placeholder="Type your message"></textarea>
 		</div>
+		<p class="powered-by">
+			Powered by
+			<a href="https://rocket.chat" target="_blank">
+				<img class="logo" src="/images/logo/logo-dark.svg?v=1">
+			</a>
+		</p>
 	</div>
 </template>
diff --git a/packages/rocketchat-livechat/app/client/views/register.coffee b/packages/rocketchat-livechat/app/client/views/register.coffee
deleted file mode 100644
index f815eab9013ff4e144e7f08f1cf275a9b16dd49a..0000000000000000000000000000000000000000
--- a/packages/rocketchat-livechat/app/client/views/register.coffee
+++ /dev/null
@@ -1,50 +0,0 @@
-Template.register.helpers
-	error: ->
-		return Template.instance().error.get()
-
-	title: ->
-		return '' unless Template.instance().subscriptionsReady()
-		return Settings.findOne('Livechat_title')?.value or 'Rocket.Chat'
-
-	color: ->
-		return 'transparent' unless Template.instance().subscriptionsReady()
-		return Settings.findOne('Livechat_title_color')?.value or '#C1272D'
-
-	welcomeMessage: ->
-		return ""
-
-Template.register.events
-	'submit #livechat-registration': (e, instance) ->
-		e.preventDefault()
-
-		$name = instance.$('input[name=name]')
-		$email = instance.$('input[name=email]')
-
-		unless $name.val().trim() and $email.val().trim()
-			return instance.showError TAPi18n.__('Please_fill_name_and_email')
-		else
-			Meteor.call 'registerGuest', visitor.getToken(), $name.val(), $email.val(), (error, result) ->
-				if error?
-					return instance.showError error.reason
-
-				Meteor.loginWithPassword result.user, result.pass, (error) ->
-					if error
-						return instance.showError error.reason
-
-	'click .error': (e, instance) ->
-		instance.hideError()
-
-Template.register.onCreated ->
-	@subscribe 'settings', ['Livechat_title', 'Livechat_title_color']
-	@error = new ReactiveVar
-
-	@showError = (msg) =>
-		$('.error').addClass('show')
-		@error.set msg
-		return
-
-	@hideError = =>
-		$('.error').removeClass('show')
-		@error.set()
-		return
-
diff --git a/packages/rocketchat-livechat/app/client/views/register.html b/packages/rocketchat-livechat/app/client/views/register.html
index 39ef026bf5e35097ec69459fd972aff8a798c2c5..7dd5afb76a2fc223cb3eae74eae8c0c01b0bb68d 100644
--- a/packages/rocketchat-livechat/app/client/views/register.html
+++ b/packages/rocketchat-livechat/app/client/views/register.html
@@ -9,7 +9,16 @@
 		</label>
 		<input type="text" name="name" id="guestName" placeholder="{{_ "Name"}}">
 		<input type="email" name="email" id="guestEmail" placeholder="{{_ "E-mail"}}">
-		<button type="submit" id="btnEntrar" class="-btn"> {{_ "Start_Chat"}} </button>
+
+		{{#if hasDepartments}}
+			<select name="department">
+				<option value="">{{_ "Select_a_department"}}</option>
+				{{#each departments}}
+					<option value="{{_id}}">{{name}}</option>
+				{{/each}}
+			</select>
+		{{/if}}
+		<button type="submit" id="btnEntrar" class="button"> {{_ "Start_Chat"}} </button>
 
 	</form>
 </template>
diff --git a/packages/rocketchat-livechat/app/client/views/register.js b/packages/rocketchat-livechat/app/client/views/register.js
new file mode 100644
index 0000000000000000000000000000000000000000..df91839e23a29673b2e3457efbbaffcd0e95d671
--- /dev/null
+++ b/packages/rocketchat-livechat/app/client/views/register.js
@@ -0,0 +1,68 @@
+Template.register.helpers({
+	error() {
+		return Template.instance().error.get();
+	},
+	welcomeMessage() {
+		return "";
+	},
+	hasDepartments() {
+		return Department.find().count() > 1;
+	},
+	departments() {
+		return Department.find();
+	}
+});
+
+Template.register.events({
+	'submit #livechat-registration' (e, instance) {
+		var $email, $name;
+		e.preventDefault();
+		$name = instance.$('input[name=name]');
+		$email = instance.$('input[name=email]');
+		if (!($name.val().trim() && $email.val().trim())) {
+			return instance.showError(TAPi18n.__('Please_fill_name_and_email'));
+		} else {
+			var departmentId = instance.$('select[name=department]').val();
+			if (!departmentId) {
+				var department = Department.findOne();
+				if (department) {
+					departmentId = department._id;
+				}
+			}
+
+			var guest = {
+				token: visitor.getToken(),
+				name: $name.val(),
+				email: $email.val(),
+				department: departmentId
+			};
+			Meteor.call('livechat:registerGuest', guest, function(error, result) {
+				if (error != null) {
+					return instance.showError(error.reason);
+				}
+				Meteor.loginWithToken(result.token, function(error) {
+					if (error) {
+						return instance.showError(error.reason);
+					}
+				});
+			});
+		}
+	},
+	'click .error' (e, instance) {
+		return instance.hideError();
+	}
+});
+
+Template.register.onCreated(function() {
+	this.subscribe('livechat:availableDepartments');
+
+	this.error = new ReactiveVar;
+	this.showError = (msg) => {
+		$('.error').addClass('show');
+		this.error.set(msg);
+	};
+	this.hideError = () => {
+		$('.error').removeClass('show');
+		this.error.set();
+	};
+});
diff --git a/packages/rocketchat-livechat/app/client/views/survey.html b/packages/rocketchat-livechat/app/client/views/survey.html
index 07babef73d29cc86d8fa90f6ce917f9b9f094be8..9c4a9b08f399a83330a1c5c241f5fadaf4835bd3 100644
--- a/packages/rocketchat-livechat/app/client/views/survey.html
+++ b/packages/rocketchat-livechat/app/client/views/survey.html
@@ -1,66 +1,65 @@
 <template name="survey">
 	<div id="survey">
-		<div class="overlay">
-			<div class="wrapper">
-				<header>
-					<b>{{_ 'Please_answer_survey'}}</b>
-				</header>
-				<div class="content">
-					<p class="instructions">{{_ 'Survey_instructions'}}</p>
-					<form id="survey" class="livechat-form">
-						<div class="survey-item">
-							<label class="question">
-								{{_ "How_satisfied_were_you_with_this_chat"}}
-							</label>
-							<label class="answer"><input type="radio" name="satisfaction" value="1" />1</label>
-							<label class="answer"><input type="radio" name="satisfaction" value="2" />2</label>
-							<label class="answer"><input type="radio" name="satisfaction" value="3" />3</label>
-							<label class="answer"><input type="radio" name="satisfaction" value="4" />4</label>
-							<label class="answer"><input type="radio" name="satisfaction" value="5" />5</label>
-						</div>
-						<div class="survey-item">
-							<label class="question">
-								{{_ "How_knowledgeable_was_the_chat_agent"}}
-							</label>
-							<label class="answer"><input type="radio" name="agentKnowledge" value="1" />1</label>
-							<label class="answer"><input type="radio" name="agentKnowledge" value="2" />2</label>
-							<label class="answer"><input type="radio" name="agentKnowledge" value="3" />3</label>
-							<label class="answer"><input type="radio" name="agentKnowledge" value="4" />4</label>
-							<label class="answer"><input type="radio" name="agentKnowledge" value="5" />5</label>
-						</div>
-						<div class="survey-item">
-							<label class="question">
-								{{_ "How_responsive_was_the_chat_agent"}}
-							</label>
-							<label class="answer"><input type="radio" name="agentResposiveness" value="1" />1</label>
-							<label class="answer"><input type="radio" name="agentResposiveness" value="2" />2</label>
-							<label class="answer"><input type="radio" name="agentResposiveness" value="3" />3</label>
-							<label class="answer"><input type="radio" name="agentResposiveness" value="4" />4</label>
-							<label class="answer"><input type="radio" name="agentResposiveness" value="5" />5</label>
-						</div>
-						<div class="survey-item">
-							<label class="question">
-								{{_ "How_friendly_was_the_chat_agent"}}
-							</label>
-							<label class="answer"><input type="radio" name="agentFriendliness" value="1" />1</label>
-							<label class="answer"><input type="radio" name="agentFriendliness" value="2" />2</label>
-							<label class="answer"><input type="radio" name="agentFriendliness" value="3" />3</label>
-							<label class="answer"><input type="radio" name="agentFriendliness" value="4" />4</label>
-							<label class="answer"><input type="radio" name="agentFriendliness" value="5" />5</label>
-						</div>
-						<div class="survey-item">
-							<label class="question">
-								{{_ "Additional_Feedback"}}
-							</label>
-							<textarea name="additionalFeedback" rows="5"></textarea>
-						</div>
-					</form>
-				</div>
-				<footer>
-					<button type="button" class="button secondary skip"><span>{{_ "Skip"}}</span></button>
-					<button type="button" class="button send"><span>{{_ "Send"}}</span></button>
-				</footer>
+		<div class="overlay"></div>
+		<div class="wrapper">
+			<header>
+				<b>{{_ 'Please_answer_survey'}}</b>
+			</header>
+			<div class="content">
+				<p class="instructions">{{_ 'Survey_instructions'}}</p>
+				<form id="survey" class="livechat-form">
+					<div class="survey-item">
+						<label class="question">
+							{{_ "How_satisfied_were_you_with_this_chat"}}
+						</label>
+						<label class="answer"><input type="radio" name="satisfaction" value="1" />1</label>
+						<label class="answer"><input type="radio" name="satisfaction" value="2" />2</label>
+						<label class="answer"><input type="radio" name="satisfaction" value="3" />3</label>
+						<label class="answer"><input type="radio" name="satisfaction" value="4" />4</label>
+						<label class="answer"><input type="radio" name="satisfaction" value="5" />5</label>
+					</div>
+					<div class="survey-item">
+						<label class="question">
+							{{_ "How_knowledgeable_was_the_chat_agent"}}
+						</label>
+						<label class="answer"><input type="radio" name="agentKnowledge" value="1" />1</label>
+						<label class="answer"><input type="radio" name="agentKnowledge" value="2" />2</label>
+						<label class="answer"><input type="radio" name="agentKnowledge" value="3" />3</label>
+						<label class="answer"><input type="radio" name="agentKnowledge" value="4" />4</label>
+						<label class="answer"><input type="radio" name="agentKnowledge" value="5" />5</label>
+					</div>
+					<div class="survey-item">
+						<label class="question">
+							{{_ "How_responsive_was_the_chat_agent"}}
+						</label>
+						<label class="answer"><input type="radio" name="agentResposiveness" value="1" />1</label>
+						<label class="answer"><input type="radio" name="agentResposiveness" value="2" />2</label>
+						<label class="answer"><input type="radio" name="agentResposiveness" value="3" />3</label>
+						<label class="answer"><input type="radio" name="agentResposiveness" value="4" />4</label>
+						<label class="answer"><input type="radio" name="agentResposiveness" value="5" />5</label>
+					</div>
+					<div class="survey-item">
+						<label class="question">
+							{{_ "How_friendly_was_the_chat_agent"}}
+						</label>
+						<label class="answer"><input type="radio" name="agentFriendliness" value="1" />1</label>
+						<label class="answer"><input type="radio" name="agentFriendliness" value="2" />2</label>
+						<label class="answer"><input type="radio" name="agentFriendliness" value="3" />3</label>
+						<label class="answer"><input type="radio" name="agentFriendliness" value="4" />4</label>
+						<label class="answer"><input type="radio" name="agentFriendliness" value="5" />5</label>
+					</div>
+					<div class="survey-item">
+						<label class="question">
+							{{_ "Additional_Feedback"}}
+						</label>
+						<textarea name="additionalFeedback" rows="5"></textarea>
+					</div>
+				</form>
 			</div>
+			<footer>
+				<button type="button" class="button secondary skip"><span>{{_ "Skip"}}</span></button>
+				<button type="button" class="button send"><span>{{_ "Send"}}</span></button>
+			</footer>
 		</div>
 	</div>
 </template>
diff --git a/packages/rocketchat-livechat/app/i18n/ar.i18n.json b/packages/rocketchat-livechat/app/i18n/ar.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..6f3586ed429589b001f86e18967c8e49966b230a 100644
--- a/packages/rocketchat-livechat/app/i18n/ar.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/ar.i18n.json
@@ -1 +1,4 @@
-{ }
\ No newline at end of file
+{
+  "Skip" : "تخطي",
+  "Start_Chat" : "بدأ الدردشة"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/cs.i18n.json b/packages/rocketchat-livechat/app/i18n/cs.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..6aaa0ff01cc53dc8626f112e9c09508972d5797a 100644
--- a/packages/rocketchat-livechat/app/i18n/cs.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/cs.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Start_Chat" : "Spustit chat"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/de.i18n.json b/packages/rocketchat-livechat/app/i18n/de.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..dffe62cd1756e9d0eb6f8b05366511739877d80a 100644
--- a/packages/rocketchat-livechat/app/i18n/de.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/de.i18n.json
@@ -1 +1,18 @@
-{ }
\ No newline at end of file
+{
+  "Additional_Feedback" : "Zusätzliches Feedback",
+  "Appearance" : "Erscheinungsbild",
+  "How_friendly_was_the_chat_agent" : "Wie freundlich war der Chat-Agent?",
+  "How_knowledgeable_was_the_chat_agent" : "Wie sachkundig war der Chat-Agent?",
+  "How_responsive_was_the_chat_agent" : "Wie reaktionsschnell war der Chat-Agent?",
+  "How_satisfied_were_you_with_this_chat" : "Wie zufrieden waren Sie mit diesem Chat?",
+  "Installation" : "Installation",
+  "Please_answer_survey" : "Bitte nehmen Sie sich einen Moment Zeit, um kurz einige Fragen zu dem Chat zu beantworten.",
+  "Please_fill_name_and_email" : "Bitte geben Sie einen Namen und eine E-Mail-Adresse ein.",
+  "Select_a_department" : "Wählen Sie eine Abteilung",
+  "Skip" : "Ãœberspringen",
+  "Start_Chat" : "Chat beginnen",
+  "Survey" : "Umfrage",
+  "Survey_instructions" : "Bewerten Sie jede Frage nach Ihrer Zufriedenheit. 1 bedeutet, dass Sie völlig unzufrieden sind und 5 bedeutet, dass Sie vollständig zufrieden sind.",
+  "Thank_you_for_your_feedback" : "Vielen Dank für Ihre Rückmeldung.",
+  "We_are_offline_Sorry_for_the_inconvenience" : "Wir sind offline. Entschuldigen Sie die Unannehmlichkeiten."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/el.i18n.json b/packages/rocketchat-livechat/app/i18n/el.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..14415269c851881c06176c8edb2c1ff71798ba6c 100644
--- a/packages/rocketchat-livechat/app/i18n/el.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/el.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Start_Chat" : "Έναρξη συνομιλίας"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/en.i18n.json b/packages/rocketchat-livechat/app/i18n/en.i18n.json
index b8a9e1d8a1b4886131a119f747ad48a6b9e23c6b..e31bf14dbe78719ee090591c3175ad28e827a04d 100644
--- a/packages/rocketchat-livechat/app/i18n/en.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/en.i18n.json
@@ -1,20 +1,18 @@
 {
   "Additional_Feedback" : "Additional Feedback",
-  "Skip" : "Skip",
-  "E-mail" : "E-mail",
+  "Appearance" : "Appearance",
   "How_friendly_was_the_chat_agent" : "How friendly was the chat agent?",
   "How_knowledgeable_was_the_chat_agent" : "How knowledgeable was the chat agent?",
   "How_responsive_was_the_chat_agent" : "How responsive was the chat agent?",
   "How_satisfied_were_you_with_this_chat" : "How satisfied were you with this chat?",
-  "Message" : "Message",
-  "Name" : "Name",
+  "Installation" : "Installation",
   "Please_answer_survey" : "Please take a moment to answer a quick survey about this chat",
   "Please_fill_name_and_email" : "Please fill name and e-mail",
-  "Send" : "Send",
+  "Select_a_department" : "Select a department",
+  "Skip" : "Skip",
   "Start_Chat" : "Start Chat",
   "Survey" : "Survey",
   "Survey_instructions" : "Rate each question according to your satisfaction, 1 meaning you are completely unsatisfied and 5 meaning you are completely satisfied.",
   "Thank_you_for_your_feedback" : "Thank you for your feedback",
-  "User_left" : "Has left the channel.",
   "We_are_offline_Sorry_for_the_inconvenience" : "We are offline. Sorry for the inconvenience."
-}
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/es.i18n.json b/packages/rocketchat-livechat/app/i18n/es.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..01ccecd14b5eaa236769cbd9e47523c2fbc5a79f 100644
--- a/packages/rocketchat-livechat/app/i18n/es.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/es.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Start_Chat" : "Iniciar chat"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/fa.i18n.json b/packages/rocketchat-livechat/app/i18n/fa.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..81ee6d2f85ebe073ceb6d3213f93b8d24a20127c 100644
--- a/packages/rocketchat-livechat/app/i18n/fa.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/fa.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Start_Chat" : "شروع چت"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/fi.i18n.json b/packages/rocketchat-livechat/app/i18n/fi.i18n.json
index f279ec41b30d2b8c334a5e4cf2ab84366c9e4454..b5820e4af81a628cf80aeb417a36f6d23386243b 100644
--- a/packages/rocketchat-livechat/app/i18n/fi.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/fi.i18n.json
@@ -1,14 +1,18 @@
 {
   "Additional_Feedback" : "Lisäpalaute",
-  "Skip" : "Ohita",
-  "How_friendly_was_the_chat_agent" : "Kuinka ystävällinen oli chat agentti?",
-  "How_knowledgeable_was_the_chat_agent" : "Miten osaava oli chat agentti?",
-  "How_responsive_was_the_chat_agent" : "Miten reagoiva oli chat agentti?",
-  "How_satisfied_were_you_with_this_chat" : "Kuinka tyytyväinen olet tähän chattiin?",
+  "Appearance" : "Ulkoasu",
+  "How_friendly_was_the_chat_agent" : "Kuinka ystävällinen chat agentti oli?",
+  "How_knowledgeable_was_the_chat_agent" : "Miten osaava chat agentti oli?",
+  "How_responsive_was_the_chat_agent" : "Miten reagoiva chat agentti oli?",
+  "How_satisfied_were_you_with_this_chat" : "Kuinka tyytyväinen olit tähän chattiin?",
+  "Installation" : "Asennus",
   "Please_answer_survey" : "Käytä hetki vastataksesi pikakyselyyn tästä chatista",
   "Please_fill_name_and_email" : "Täytä nimi ja sähköpostiosoite",
+  "Select_a_department" : "Valitse osasto",
+  "Skip" : "Ohita",
   "Start_Chat" : "Aloita chat",
   "Survey" : "Tutkimus",
   "Survey_instructions" : "Arvioi jokainen kysymys sen mukaan miten tyytyväinen olet, 1 tarkoittaa että olet täysin tyytymätön ja 5 tarkoittaa että olet täysin tyytyväinen.",
-  "Thank_you_for_your_feedback" : "Kiitos palautteestasi"
+  "Thank_you_for_your_feedback" : "Kiitos palautteestasi",
+  "We_are_offline_Sorry_for_the_inconvenience" : "Palvelu on offline-tilassa. Pahoittelut häiriöstä."
 }
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/fr.i18n.json b/packages/rocketchat-livechat/app/i18n/fr.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..80b42a8c814b609507f0a9d8c5b2f4e38e88a7ce 100644
--- a/packages/rocketchat-livechat/app/i18n/fr.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/fr.i18n.json
@@ -1 +1,16 @@
-{ }
\ No newline at end of file
+{
+  "Additional_Feedback" : "Commentaires supplémentaires",
+  "Appearance" : "Apparence",
+  "How_friendly_was_the_chat_agent" : "Le bot de chat était-il amical ?",
+  "How_knowledgeable_was_the_chat_agent" : "Le bot de chat était-il clair ?",
+  "How_responsive_was_the_chat_agent" : "Le bot de chat avait-il des réponses adaptées ?",
+  "How_satisfied_were_you_with_this_chat" : "Comment étiez-vous satisfait ce chat?",
+  "Installation" : "Installation",
+  "Please_answer_survey" : "Prenez un moment pour répondre à un court sondage à propos de ce chat si vous pouvez",
+  "Skip" : "Passer",
+  "Start_Chat" : "Démarrer un tchat",
+  "Survey" : "Enquête",
+  "Survey_instructions" : "Notez chaque question en fonction de votre satisfaction, 1 signifiant que vous êtes très insatisfait et 5 que vous êtes entièrement satisfait.",
+  "Thank_you_for_your_feedback" : "Merci pour votre réponse",
+  "We_are_offline_Sorry_for_the_inconvenience" : "Nous sommes hors ligne. Désolé pour le désagrément."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/he.i18n.json b/packages/rocketchat-livechat/app/i18n/he.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..7aacaa2a49c77365959547bc3a479e2548d3f187 100644
--- a/packages/rocketchat-livechat/app/i18n/he.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/he.i18n.json
@@ -1 +1,8 @@
-{ }
\ No newline at end of file
+{
+  "Additional_Feedback" : "משוב נוסף",
+  "Appearance" : "מראה",
+  "Installation" : "התקנה",
+  "Start_Chat" : "Start Chat",
+  "Survey" : "סקר",
+  "Thank_you_for_your_feedback" : "תודה לך על המשוב"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/hr.i18n.json b/packages/rocketchat-livechat/app/i18n/hr.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..0f5f0fa415ba9f415d14cb19177ef92500fbc834 100644
--- a/packages/rocketchat-livechat/app/i18n/hr.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/hr.i18n.json
@@ -1 +1,5 @@
-{ }
\ No newline at end of file
+{
+  "Appearance" : "Izgled",
+  "Installation" : "Instalacija",
+  "Start_Chat" : "Početak Chat"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/hu.i18n.json b/packages/rocketchat-livechat/app/i18n/hu.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..5e8b9b574e5f29d5ce4665477b08dc76e06691b4 100644
--- a/packages/rocketchat-livechat/app/i18n/hu.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/hu.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Start_Chat" : "Start Chat"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/it.i18n.json b/packages/rocketchat-livechat/app/i18n/it.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..dc6a25746c54c76a3032601c31194e885496cee2 100644
--- a/packages/rocketchat-livechat/app/i18n/it.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/it.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Start_Chat" : "Avvia chat"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/ja.i18n.json b/packages/rocketchat-livechat/app/i18n/ja.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..70a58ee9e7cfdd0dfbf831a062c6558d033bf476 100644
--- a/packages/rocketchat-livechat/app/i18n/ja.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/ja.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Start_Chat" : "チャットを開始"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/km.i18n.json b/packages/rocketchat-livechat/app/i18n/km.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..a5eb5069a36f7b0573dab9b3bd0d1270072822b3 100644
--- a/packages/rocketchat-livechat/app/i18n/km.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/km.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Start_Chat" : "ចាប់ផ្ដើម​ជជែក​កំសាន្ត"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/ko.i18n.json b/packages/rocketchat-livechat/app/i18n/ko.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..4bfdf5366f3ceb53d5d407f7059270acc115b344 100644
--- a/packages/rocketchat-livechat/app/i18n/ko.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/ko.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Start_Chat" : "채팅 시작"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/ku.i18n.json b/packages/rocketchat-livechat/app/i18n/ku.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..5e8b9b574e5f29d5ce4665477b08dc76e06691b4 100644
--- a/packages/rocketchat-livechat/app/i18n/ku.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/ku.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Start_Chat" : "Start Chat"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/lo.i18n.json b/packages/rocketchat-livechat/app/i18n/lo.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..88505c1c64a83db653f7790c7446f8c871f775a9 100644
--- a/packages/rocketchat-livechat/app/i18n/lo.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/lo.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Start_Chat" : "ການ​ເລີ່ມ​ຕົ້ນ​ສົນ​ທະ​ນາ"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/ms-MY.i18n.json b/packages/rocketchat-livechat/app/i18n/ms-MY.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..8dbe1bb222ef63442b3a11b4adb7af6031b6dfdf 100644
--- a/packages/rocketchat-livechat/app/i18n/ms-MY.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/ms-MY.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Start_Chat" : "Mula Chat"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/nl.i18n.json b/packages/rocketchat-livechat/app/i18n/nl.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..2bf171f8b5d5a4d902a4ae23fd5e37726a502427 100644
--- a/packages/rocketchat-livechat/app/i18n/nl.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/nl.i18n.json
@@ -1 +1,18 @@
-{ }
\ No newline at end of file
+{
+  "Additional_Feedback" : "Extra feedback",
+  "Appearance" : "Uiterlijk",
+  "How_friendly_was_the_chat_agent" : "Hoe vriendelijk was de chat-agent?",
+  "How_knowledgeable_was_the_chat_agent" : "Hoe deskundig was de chat-agent?",
+  "How_responsive_was_the_chat_agent" : "Hoe goed reageert de chat-agent?",
+  "How_satisfied_were_you_with_this_chat" : "Hoe tevreden bent u met deze chat?",
+  "Installation" : "Installatie",
+  "Please_answer_survey" : "Heeft u een moment om een korte enquête over deze chat te beantwoorden",
+  "Please_fill_name_and_email" : "Vul naam en e-mail in",
+  "Select_a_department" : "Selecteer een afdeling",
+  "Skip" : "Overslaan",
+  "Start_Chat" : "Start Chat",
+  "Survey" : "Enquête",
+  "Survey_instructions" : "Beoordeel elke vraag naar mate uw tevredenheid, 1 betekent dat u helemaal ontevreden  bent en 5 betekent volledig tevreden.",
+  "Thank_you_for_your_feedback" : "Hartelijk dank voor uw feedback",
+  "We_are_offline_Sorry_for_the_inconvenience" : "We zijn offline. Excuses voor het ongemak."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/pl.i18n.json b/packages/rocketchat-livechat/app/i18n/pl.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..f3e5e78e6998716f0e1306a239a0c927f089c644 100644
--- a/packages/rocketchat-livechat/app/i18n/pl.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/pl.i18n.json
@@ -1 +1,5 @@
-{ }
\ No newline at end of file
+{
+  "Skip" : "Pomiń",
+  "Start_Chat" : "Rozpocznij czat",
+  "Survey" : "Ankieta"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/pt.i18n.json b/packages/rocketchat-livechat/app/i18n/pt.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..b7e65b0c74f15e72a798a69dd063712d3bf44446 100644
--- a/packages/rocketchat-livechat/app/i18n/pt.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/pt.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Start_Chat" : "Iniciar bate-papo"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/ro.i18n.json b/packages/rocketchat-livechat/app/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..ab72db26d5d82b94134436486801d0b25331082a
--- /dev/null
+++ b/packages/rocketchat-livechat/app/i18n/ro.i18n.json
@@ -0,0 +1,18 @@
+{
+  "Additional_Feedback" : "Feedback suplimentar",
+  "Appearance" : "Aspect",
+  "How_friendly_was_the_chat_agent" : "Cât de prietenos  a fost agentul de chat?",
+  "How_knowledgeable_was_the_chat_agent" : "Cât de informat a fost agentul de chat?",
+  "How_responsive_was_the_chat_agent" : "Cât de rapid a fost agentul de chat?",
+  "How_satisfied_were_you_with_this_chat" : "Cât de mulțumit sunteți de acest chat?",
+  "Installation" : "Instalare",
+  "Please_answer_survey" : "Vă rugăm să acordați un moment pentru a răspunde la un sondaj rapid despre acest chat",
+  "Please_fill_name_and_email" : "Vă rugăm să completați numele și e-mail",
+  "Select_a_department" : "Selectați un departament",
+  "Skip" : "Sari peste asta",
+  "Start_Chat" : "Start chat",
+  "Survey" : "Sondaj de opinie",
+  "Survey_instructions" : "Da o nota fiecărei întrebări în funcție de gradul de satisfacție, 1 înseamnă că sunt complet nemulțumit și 5 înseamnă că sunt complet mulțumiți.",
+  "Thank_you_for_your_feedback" : "Vă mulțumim pentru feedback",
+  "We_are_offline_Sorry_for_the_inconvenience" : "Suntem offline. Scuze pentru neplăcerile provocate."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/ru.i18n.json b/packages/rocketchat-livechat/app/i18n/ru.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..9a8fba30e6ada21d583a5f575b91cfdf718c499f 100644
--- a/packages/rocketchat-livechat/app/i18n/ru.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/ru.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Start_Chat" : "Начать Чат"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/sq.i18n.json b/packages/rocketchat-livechat/app/i18n/sq.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..91b65876930da28d10f88a3cf24d6a7636871276 100644
--- a/packages/rocketchat-livechat/app/i18n/sq.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/sq.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Start_Chat" : "Fillo bisedën"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/sr.i18n.json b/packages/rocketchat-livechat/app/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..65656ff72264e736d19a158b8eb79ccdabc06f35
--- /dev/null
+++ b/packages/rocketchat-livechat/app/i18n/sr.i18n.json
@@ -0,0 +1,3 @@
+{
+  "Start_Chat" : "Почетак Чат"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/sv.i18n.json b/packages/rocketchat-livechat/app/i18n/sv.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..504f8b76303e142f22cac626621c1c6d4f75a799 100644
--- a/packages/rocketchat-livechat/app/i18n/sv.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/sv.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Start_Chat" : "Starta chatt"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/ta-IN.i18n.json b/packages/rocketchat-livechat/app/i18n/ta-IN.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..279a5141a32efd5cb9766e36645775fce76566d9 100644
--- a/packages/rocketchat-livechat/app/i18n/ta-IN.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/ta-IN.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Start_Chat" : "தொடக்க சேட்"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/tr.i18n.json b/packages/rocketchat-livechat/app/i18n/tr.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..370bbedcd2a3485316d9cd950c9f952a62b88659 100644
--- a/packages/rocketchat-livechat/app/i18n/tr.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/tr.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Start_Chat" : "Sohbete BaÅŸla"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/ug.i18n.json b/packages/rocketchat-livechat/app/i18n/ug.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..5e8b9b574e5f29d5ce4665477b08dc76e06691b4 100644
--- a/packages/rocketchat-livechat/app/i18n/ug.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/ug.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Start_Chat" : "Start Chat"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/uk.i18n.json b/packages/rocketchat-livechat/app/i18n/uk.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..530dc71418bd243c7dd1474b733457a47c439e41 100644
--- a/packages/rocketchat-livechat/app/i18n/uk.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/uk.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Start_Chat" : "Почати Чат"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/app/i18n/zh.i18n.json b/packages/rocketchat-livechat/app/i18n/zh.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..20a41fc2f8b5a657e3cbc98727183d6f0ff08e7a 100644
--- a/packages/rocketchat-livechat/app/i18n/zh.i18n.json
+++ b/packages/rocketchat-livechat/app/i18n/zh.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Start_Chat" : "开始聊天"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/assets/demo.html b/packages/rocketchat-livechat/assets/demo.html
index 8b3929901c4b27e06112db2ed447caae359a74a5..99cfead8c1eda84d781eabe1718cc21ae9646aec 100644
--- a/packages/rocketchat-livechat/assets/demo.html
+++ b/packages/rocketchat-livechat/assets/demo.html
@@ -19,6 +19,14 @@
 <body style="background-color: #EFEFEF">
 	<h1 style="color:#000">test</h1>
 	<p style="color:#000">Talk to us.</p>
+
+	<a href="#page-0" onclick="document.title='page-0'">page 0</a><br>
+	<a href="#page-1" onclick="document.title='page-1'">page 1</a><br>
+	<a href="#page-2" onclick="document.title='page-2'">page 2</a><br>
+	<a href="#page-3" onclick="document.title='page-3'">page 3</a><br>
+	<a href="#page-4" onclick="document.title='page-4'">page 4</a><br>
+	<a href="#page-5" onclick="document.title='page-5'">page 5</a><br>
+	<a href="#page-6" onclick="document.title='page-6'">page 6</a><br>
 </body>
 
 </html>
diff --git a/packages/rocketchat-livechat/assets/rocket-livechat.js b/packages/rocketchat-livechat/assets/rocket-livechat.js
index c16c5a7bd9277313415f0c8c371b05032f56aff7..f27762a53e05d8e2aca288a0d7c8b8e8d6c45157 100644
--- a/packages/rocketchat-livechat/assets/rocket-livechat.js
+++ b/packages/rocketchat-livechat/assets/rocket-livechat.js
@@ -9,22 +9,33 @@
 // 	})(window, document, 'script', 'initRocket', 'http://localhost:5000/livechat');
 // </script>
 
-;(function(w) {
-	var exports = {};
+;var RocketChat = (function(w) {
 	var config = {};
 	var widget;
+	var iframe;
+	var hookQueue = [];
+	var ready = false;
 
-	var closeWidget = () => {
+	var closeWidget = function() {
 		widget.dataset.state = 'closed';
 		widget.style.height = '30px';
 	};
 
-	var openWidget = () => {
+	var openWidget = function() {
 		widget.dataset.state = 'opened';
 		widget.style.height = '300px';
 	};
 
 	var api = {
+		ready: function() {
+			ready = true;
+			if (hookQueue.length > 0) {
+				hookQueue.forEach(function(hookParams) {
+					callHook.apply(this, hookParams);
+				});
+				hookQueue = [];
+			}
+		},
 		toggleWindow: function(forceClose) {
 			if (widget.dataset.state === 'closed') {
 				openWidget();
@@ -37,11 +48,49 @@
 			var popup = window.open(config.url + '?mode=popout', 'livechat-popout', 'width=400, height=450, toolbars=no');
 			popup.focus();
 		},
+		openWidget: function() {
+			openWidget();
+		},
 		removeWidget: function() {
 			document.getElementsByTagName('body')[0].removeChild(widget);
 		}
 	};
 
+	// hooks
+	var callHook = function(action, params) {
+		if (!ready) {
+			return hookQueue.push(arguments);
+		}
+		var data = {
+			src: 'rocketchat',
+			fn: action,
+			args: params
+		};
+		iframe.contentWindow.postMessage(data, '*');
+	};
+
+	var pageVisited = function() {
+		callHook('pageVisited', {
+			location: JSON.parse(JSON.stringify(document.location)),
+			title: document.title
+		});
+	};
+
+	var currentPage = {
+		href: null,
+		title: null
+	};
+	var trackNavigation = function() {
+		setInterval(function() {
+			if (document.location.href !== currentPage.href) {
+				pageVisited();
+
+				currentPage.href = document.location.href;
+				currentPage.title = document.title;
+			}
+		}, 800);
+	};
+
 	var initRocket = function(url) {
 		if (!url) {
 			return;
@@ -53,7 +102,7 @@
 		chatWidget.dataset.state = 'closed';
 		chatWidget.className = 'rocketchat-widget';
 		chatWidget.innerHTML = '<div class="rocketchat-container" style="width:100%;height:100%">' +
-								'<iframe src="' + url + '" style="width:100%;height:100%;border:none;background-color:transparent" allowTransparency="true"></iframe> '+
+								'<iframe id="rocketchat-iframe" src="' + url + '" style="width:100%;height:100%;border:none;background-color:transparent" allowTransparency="true"></iframe> '+
 								'</div><div class="rocketchat-overlay"></div>';
 
 		chatWidget.style.position = 'fixed';
@@ -68,11 +117,12 @@
 		document.getElementsByTagName('body')[0].appendChild(chatWidget);
 
 		widget = document.querySelector('.rocketchat-widget');
+		iframe = document.getElementById('rocketchat-iframe');
 
 		w.addEventListener('message', function(msg) {
 			if (typeof msg.data === 'object' && msg.data.src !== undefined && msg.data.src === 'rocketchat') {
 				if (api[msg.data.fn] !== undefined && typeof api[msg.data.fn] === 'function') {
-					var args = [].concat(msg.data.args || [])
+					var args = [].concat(msg.data.args || []);
 					api[msg.data.fn].apply(null, args);
 				}
 			}
@@ -93,6 +143,9 @@
 		var mql = window.matchMedia('screen and (max-device-width: 480px) and (orientation: portrait)');
 		mediaqueryresponse(mql);
 		mql.addListener(mediaqueryresponse);
+
+		// track user navigation
+		trackNavigation();
 	};
 
 	if (typeof w.initRocket !== 'undefined') {
@@ -107,5 +160,8 @@
 		initRocket.apply(null, [url]);
 	};
 
-	return exports;
+	// exports
+	return {
+		pageVisited: pageVisited
+	};
 })(window);
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/collections/LivechatPageVisited.js b/packages/rocketchat-livechat/client/collections/LivechatPageVisited.js
new file mode 100644
index 0000000000000000000000000000000000000000..f2f4fc2a60d79e222f5546b3bfe824eaa6500a53
--- /dev/null
+++ b/packages/rocketchat-livechat/client/collections/LivechatPageVisited.js
@@ -0,0 +1 @@
+this.LivechatPageVisited = new Mongo.Collection('rocketchat_livechat_page_visited');
diff --git a/packages/rocketchat-livechat/client/collections/LivechatTrigger.js b/packages/rocketchat-livechat/client/collections/LivechatTrigger.js
new file mode 100644
index 0000000000000000000000000000000000000000..8cca1caa586df3eea16cb87a42fa29d6d4a65e5e
--- /dev/null
+++ b/packages/rocketchat-livechat/client/collections/LivechatTrigger.js
@@ -0,0 +1 @@
+this.LivechatTrigger = new Mongo.Collection('rocketchat_livechat_trigger');
diff --git a/packages/rocketchat-livechat/client/lib/ua-parser.js b/packages/rocketchat-livechat/client/lib/ua-parser.js
new file mode 100644
index 0000000000000000000000000000000000000000..2f34b32f8f0fc3c85ab1bac53571127a87055f09
--- /dev/null
+++ b/packages/rocketchat-livechat/client/lib/ua-parser.js
@@ -0,0 +1,8 @@
+/**
+ * UAParser.js v0.7.10
+ * Lightweight JavaScript-based User-Agent string parser
+ * https://github.com/faisalman/ua-parser-js
+ *
+ * Copyright © 2012-2015 Faisal Salman <fyzlman@gmail.com>
+ * Dual licensed under GPLv2 & MIT
+ */(function(e,t){"use strict";var n="0.7.10",r="",i="?",s="function",o="undefined",u="object",a="string",f="major",l="model",c="name",h="type",p="vendor",d="version",v="architecture",m="console",g="mobile",y="tablet",b="smarttv",w="wearable",E="embedded",S={extend:function(e,t){for(var n in t)"browser cpu device engine os".indexOf(n)!==-1&&t[n].length%2===0&&(e[n]=t[n].concat(e[n]));return e},has:function(e,t){return typeof e=="string"?t.toLowerCase().indexOf(e.toLowerCase())!==-1:!1},lowerize:function(e){return e.toLowerCase()},major:function(e){return typeof e===a?e.split(".")[0]:t}},x={rgx:function(){var e,n=0,r,i,a,f,l,c,h=arguments;while(n<h.length&&!l){var p=h[n],d=h[n+1];if(typeof e===o){e={};for(a in d)d.hasOwnProperty(a)&&(f=d[a],typeof f===u?e[f[0]]=t:e[f]=t)}r=i=0;while(r<p.length&&!l){l=p[r++].exec(this.getUA());if(!!l)for(a=0;a<d.length;a++)c=l[++i],f=d[a],typeof f===u&&f.length>0?f.length==2?typeof f[1]==s?e[f[0]]=f[1].call(this,c):e[f[0]]=f[1]:f.length==3?typeof f[1]===s&&(!f[1].exec||!f[1].test)?e[f[0]]=c?f[1].call(this,c,f[2]):t:e[f[0]]=c?c.replace(f[1],f[2]):t:f.length==4&&(e[f[0]]=c?f[3].call(this,c.replace(f[1],f[2])):t):e[f]=c?c:t}n+=2}return e},str:function(e,n){for(var r in n)if(typeof n[r]===u&&n[r].length>0){for(var s=0;s<n[r].length;s++)if(S.has(n[r][s],e))return r===i?t:r}else if(S.has(n[r],e))return r===i?t:r;return e}},T={browser:{oldsafari:{version:{"1.0":"/8",1.2:"/1",1.3:"/3","2.0":"/412","2.0.2":"/416","2.0.3":"/417","2.0.4":"/419","?":"/"}}},device:{amazon:{model:{"Fire Phone":["SD","KF"]}},sprint:{model:{"Evo Shift 4G":"7373KT"},vendor:{HTC:"APA",Sprint:"Sprint"}}},os:{windows:{version:{ME:"4.90","NT 3.11":"NT3.51","NT 4.0":"NT4.0",2e3:"NT 5.0",XP:["NT 5.1","NT 5.2"],Vista:"NT 6.0",7:"NT 6.1",8:"NT 6.2",8.1:"NT 6.3",10:["NT 6.4","NT 10.0"],RT:"ARM"}}}},N={browser:[[/(opera\smini)\/([\w\.-]+)/i,/(opera\s[mobiletab]+).+version\/([\w\.-]+)/i,/(opera).+version\/([\w\.]+)/i,/(opera)[\/\s]+([\w\.]+)/i],[c,d],[/\s(opr)\/([\w\.]+)/i],[[c,"Opera"],d],[/(kindle)\/([\w\.]+)/i,/(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?([\w\.]+)*/i,/(avant\s|iemobile|slim|baidu)(?:browser)?[\/\s]?([\w\.]*)/i,/(?:ms|\()(ie)\s([\w\.]+)/i,/(rekonq)\/([\w\.]+)*/i,/(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs)\/([\w\.-]+)/i],[c,d],[/(trident).+rv[:\s]([\w\.]+).+like\sgecko/i],[[c,"IE"],d],[/(edge)\/((\d+)?[\w\.]+)/i],[c,d],[/(yabrowser)\/([\w\.]+)/i],[[c,"Yandex"],d],[/(comodo_dragon)\/([\w\.]+)/i],[[c,/_/g," "],d],[/(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i,/(qqbrowser)[\/\s]?([\w\.]+)/i],[c,d],[/(uc\s?browser)[\/\s]?([\w\.]+)/i,/ucweb.+(ucbrowser)[\/\s]?([\w\.]+)/i,/JUC.+(ucweb)[\/\s]?([\w\.]+)/i],[[c,"UCBrowser"],d],[/(dolfin)\/([\w\.]+)/i],[[c,"Dolphin"],d],[/((?:android.+)crmo|crios)\/([\w\.]+)/i],[[c,"Chrome"],d],[/XiaoMi\/MiuiBrowser\/([\w\.]+)/i],[d,[c,"MIUI Browser"]],[/android.+version\/([\w\.]+)\s+(?:mobile\s?safari|safari)/i],[d,[c,"Android Browser"]],[/FBAV\/([\w\.]+);/i],[d,[c,"Facebook"]],[/fxios\/([\w\.-]+)/i],[d,[c,"Firefox"]],[/version\/([\w\.]+).+?mobile\/\w+\s(safari)/i],[d,[c,"Mobile Safari"]],[/version\/([\w\.]+).+?(mobile\s?safari|safari)/i],[d,c],[/webkit.+?(mobile\s?safari|safari)(\/[\w\.]+)/i],[c,[d,x.str,T.browser.oldsafari.version]],[/(konqueror)\/([\w\.]+)/i,/(webkit|khtml)\/([\w\.]+)/i],[c,d],[/(navigator|netscape)\/([\w\.-]+)/i],[[c,"Netscape"],d],[/(swiftfox)/i,/(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i,/(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix)\/([\w\.-]+)/i,/(mozilla)\/([\w\.]+).+rv\:.+gecko\/\d+/i,/(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir)[\/\s]?([\w\.]+)/i,/(links)\s\(([\w\.]+)/i,/(gobrowser)\/?([\w\.]+)*/i,/(ice\s?browser)\/v?([\w\._]+)/i,/(mosaic)[\/\s]([\w\.]+)/i],[c,d]],cpu:[[/(?:(amd|x(?:(?:86|64)[_-])?|wow|win)64)[;\)]/i],[[v,"amd64"]],[/(ia32(?=;))/i],[[v,S.lowerize]],[/((?:i[346]|x)86)[;\)]/i],[[v,"ia32"]],[/windows\s(ce|mobile);\sppc;/i],[[v,"arm"]],[/((?:ppc|powerpc)(?:64)?)(?:\smac|;|\))/i],[[v,/ower/,"",S.lowerize]],[/(sun4\w)[;\)]/i],[[v,"sparc"]],[/((?:avr32|ia64(?=;))|68k(?=\))|arm(?:64|(?=v\d+;))|(?=atmel\s)avr|(?:irix|mips|sparc)(?:64)?(?=;)|pa-risc)/i],[[v,S.lowerize]]],device:[[/\((ipad|playbook);[\w\s\);-]+(rim|apple)/i],[l,p,[h,y]],[/applecoremedia\/[\w\.]+ \((ipad)/],[l,[p,"Apple"],[h,y]],[/(apple\s{0,1}tv)/i],[[l,"Apple TV"],[p,"Apple"]],[/(archos)\s(gamepad2?)/i,/(hp).+(touchpad)/i,/(kindle)\/([\w\.]+)/i,/\s(nook)[\w\s]+build\/(\w+)/i,/(dell)\s(strea[kpr\s\d]*[\dko])/i],[p,l,[h,y]],[/(kf[A-z]+)\sbuild\/[\w\.]+.*silk\//i],[l,[p,"Amazon"],[h,y]],[/(sd|kf)[0349hijorstuw]+\sbuild\/[\w\.]+.*silk\//i],[[l,x.str,T.device.amazon.model],[p,"Amazon"],[h,g]],[/\((ip[honed|\s\w*]+);.+(apple)/i],[l,p,[h,g]],[/\((ip[honed|\s\w*]+);/i],[l,[p,"Apple"],[h,g]],[/(blackberry)[\s-]?(\w+)/i,/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|huawei|meizu|motorola|polytron)[\s_-]?([\w-]+)*/i,/(hp)\s([\w\s]+\w)/i,/(asus)-?(\w+)/i],[p,l,[h,g]],[/\(bb10;\s(\w+)/i],[l,[p,"BlackBerry"],[h,g]],[/android.+(transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus 7)/i],[l,[p,"Asus"],[h,y]],[/(sony)\s(tablet\s[ps])\sbuild\//i,/(sony)?(?:sgp.+)\sbuild\//i],[[p,"Sony"],[l,"Xperia Tablet"],[h,y]],[/(?:sony)?(?:(?:(?:c|d)\d{4})|(?:so[-l].+))\sbuild\//i],[[p,"Sony"],[l,"Xperia Phone"],[h,g]],[/\s(ouya)\s/i,/(nintendo)\s([wids3u]+)/i],[p,l,[h,m]],[/android.+;\s(shield)\sbuild/i],[l,[p,"Nvidia"],[h,m]],[/(playstation\s[34portablevi]+)/i],[l,[p,"Sony"],[h,m]],[/(sprint\s(\w+))/i],[[p,x.str,T.device.sprint.vendor],[l,x.str,T.device.sprint.model],[h,g]],[/(lenovo)\s?(S(?:5000|6000)+(?:[-][\w+]))/i],[p,l,[h,y]],[/(htc)[;_\s-]+([\w\s]+(?=\))|\w+)*/i,/(zte)-(\w+)*/i,/(alcatel|geeksphone|huawei|lenovo|nexian|panasonic|(?=;\s)sony)[_\s-]?([\w-]+)*/i],[p,[l,/_/g," "],[h,g]],[/(nexus\s9)/i],[l,[p,"HTC"],[h,y]],[/[\s\(;](xbox(?:\sone)?)[\s\);]/i],[l,[p,"Microsoft"],[h,m]],[/(kin\.[onetw]{3})/i],[[l,/\./g," "],[p,"Microsoft"],[h,g]],[/\s(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?(:?\s4g)?)[\w\s]+build\//i,/mot[\s-]?(\w+)*/i,/(XT\d{3,4}) build\//i,/(nexus\s[6])/i],[l,[p,"Motorola"],[h,g]],[/android.+\s(mz60\d|xoom[\s2]{0,2})\sbuild\//i],[l,[p,"Motorola"],[h,y]],[/android.+((sch-i[89]0\d|shw-m380s|gt-p\d{4}|gt-n8000|sgh-t8[56]9|nexus 10))/i,/((SM-T\w+))/i],[[p,"Samsung"],l,[h,y]],[/((s[cgp]h-\w+|gt-\w+|galaxy\snexus|sm-n900))/i,/(sam[sung]*)[\s-]*(\w+-?[\w-]*)*/i,/sec-((sgh\w+))/i],[[p,"Samsung"],l,[h,g]],[/(samsung);smarttv/i],[p,l,[h,b]],[/\(dtv[\);].+(aquos)/i],[l,[p,"Sharp"],[h,b]],[/sie-(\w+)*/i],[l,[p,"Siemens"],[h,g]],[/(maemo|nokia).*(n900|lumia\s\d+)/i,/(nokia)[\s_-]?([\w-]+)*/i],[[p,"Nokia"],l,[h,g]],[/android\s3\.[\s\w;-]{10}(a\d{3})/i],[l,[p,"Acer"],[h,y]],[/android\s3\.[\s\w;-]{10}(lg?)-([06cv9]{3,4})/i],[[p,"LG"],l,[h,y]],[/(lg) netcast\.tv/i],[p,l,[h,b]],[/(nexus\s[45])/i,/lg[e;\s\/-]+(\w+)*/i],[l,[p,"LG"],[h,g]],[/android.+(ideatab[a-z0-9\-\s]+)/i],[l,[p,"Lenovo"],[h,y]],[/linux;.+((jolla));/i],[p,l,[h,g]],[/((pebble))app\/[\d\.]+\s/i],[p,l,[h,w]],[/android.+;\s(glass)\s\d/i],[l,[p,"Google"],[h,w]],[/android.+(\w+)\s+build\/hm\1/i,/android.+(hm[\s\-_]*note?[\s_]*(?:\d\w)?)\s+build/i,/android.+(mi[\s\-_]*(?:one|one[\s_]plus)?[\s_]*(?:\d\w)?)\s+build/i],[[l,/_/g," "],[p,"Xiaomi"],[h,g]],[/\s(tablet)[;\/\s]/i,/\s(mobile)[;\/\s]/i],[[h,S.lowerize],p,l]],engine:[[/windows.+\sedge\/([\w\.]+)/i],[d,[c,"EdgeHTML"]],[/(presto)\/([\w\.]+)/i,/(webkit|trident|netfront|netsurf|amaya|lynx|w3m)\/([\w\.]+)/i,/(khtml|tasman|links)[\/\s]\(?([\w\.]+)/i,/(icab)[\/\s]([23]\.[\d\.]+)/i],[c,d],[/rv\:([\w\.]+).*(gecko)/i],[d,c]],os:[[/microsoft\s(windows)\s(vista|xp)/i],[c,d],[/(windows)\snt\s6\.2;\s(arm)/i,/(windows\sphone(?:\sos)*|windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i],[c,[d,x.str,T.os.windows.version]],[/(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i],[[c,"Windows"],[d,x.str,T.os.windows.version]],[/\((bb)(10);/i],[[c,"BlackBerry"],d],[/(blackberry)\w*\/?([\w\.]+)*/i,/(tizen)[\/\s]([\w\.]+)/i,/(android|webos|palm\sos|qnx|bada|rim\stablet\sos|meego|contiki)[\/\s-]?([\w\.]+)*/i,/linux;.+(sailfish);/i],[c,d],[/(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]+)*/i],[[c,"Symbian"],d],[/\((series40);/i],[c],[/mozilla.+\(mobile;.+gecko.+firefox/i],[[c,"Firefox OS"],d],[/(nintendo|playstation)\s([wids34portablevu]+)/i,/(mint)[\/\s\(]?(\w+)*/i,/(mageia|vectorlinux)[;\s]/i,/(joli|[kxln]?ubuntu|debian|[open]*suse|gentoo|(?=\s)arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus)[\/\s-]?([\w\.-]+)*/i,/(hurd|linux)\s?([\w\.]+)*/i,/(gnu)\s?([\w\.]+)*/i],[c,d],[/(cros)\s[\w]+\s([\w\.]+\w)/i],[[c,"Chromium OS"],d],[/(sunos)\s?([\w\.]+\d)*/i],[[c,"Solaris"],d],[/\s([frentopc-]{0,4}bsd|dragonfly)\s?([\w\.]+)*/i],[c,d],[/(ip[honead]+)(?:.*os\s([\w]+)*\slike\smac|;\sopera)/i],[[c,"iOS"],[d,/_/g,"."]],[/(mac\sos\sx)\s?([\w\s\.]+\w)*/i,/(macintosh|mac(?=_powerpc)\s)/i],[[c,"Mac OS"],[d,/_/g,"."]],[/((?:open)?solaris)[\/\s-]?([\w\.]+)*/i,/(haiku)\s(\w+)/i,/(aix)\s((\d)(?=\.|\)|\s)[\w\.]*)*/i,/(plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos|openvms)/i,/(unix)\s?([\w\.]+)*/i],[c,d]]},C=function(t,n){if(this instanceof C){var i=t||(e&&e.navigator&&e.navigator.userAgent?e.navigator.userAgent:r),s=n?S.extend(N,n):N;return this.getBrowser=function(){var e=x.rgx.apply(this,s.browser);return e.major=S.major(e.version),e},this.getCPU=function(){return x.rgx.apply(this,s.cpu)},this.getDevice=function(){return x.rgx.apply(this,s.device)},this.getEngine=function(){return x.rgx.apply(this,s.engine)},this.getOS=function(){return x.rgx.apply(this,s.os)},this.getResult=function(){return{ua:this.getUA(),browser:this.getBrowser(),engine:this.getEngine(),os:this.getOS(),device:this.getDevice(),cpu:this.getCPU()}},this.getUA=function(){return i},this.setUA=function(e){return i=e,this},this.setUA(i),this}return(new C(t,n)).getResult()};C.VERSION=n,C.BROWSER={NAME:c,MAJOR:f,VERSION:d},C.CPU={ARCHITECTURE:v},C.DEVICE={MODEL:l,VENDOR:p,TYPE:h,CONSOLE:m,MOBILE:g,SMARTTV:b,TABLET:y,WEARABLE:w,EMBEDDED:E},C.ENGINE={NAME:c,VERSION:d},C.OS={NAME:c,VERSION:d},typeof exports!==o?(typeof module!==o&&module.exports&&(exports=module.exports=C),exports.UAParser=C):typeof define===s&&define.amd?define(function(){return C}):e.UAParser=C;var k=e.jQuery||e.Zepto;if(typeof k!==o){var L=new C;k.ua=L.getResult(),k.ua.get=function(){return L.getUA()},k.ua.set=function(e){L.setUA(e);var t=L.getResult();for(var n in t)k.ua[n]=t[n]}}})(typeof window=="object"?window:this);
diff --git a/packages/rocketchat-livechat/client/route.js b/packages/rocketchat-livechat/client/route.js
index a2029900297fcea39a1fa5e9ed044b144769cb0a..c5b0eb72ae780b8925aec90ef0b0de42856710b9 100644
--- a/packages/rocketchat-livechat/client/route.js
+++ b/packages/rocketchat-livechat/client/route.js
@@ -1,32 +1,68 @@
-FlowRouter.route('/live/:name', {
-	name: 'live',
+livechatManagerRoutes = FlowRouter.group({
+	prefix: '/livechat-manager',
+	name: 'livechat-manager'
+});
 
-	action: function(params, queryParams) {
-		console.log('action route livechat');
-		Session.set('showUserInfo');
-		openRoom('l', params.name);
-	},
+AccountBox.addRoute({
+	name: 'livechat-dashboard',
+	path: '/dashboard',
+	sideNav: 'livechatFlex',
+	i18nPageTitle: 'Livechat_Dashboard',
+	pageTemplate: 'livechatDashboard'
+}, livechatManagerRoutes);
 
-	triggersExit: [roomExit]
-});
+AccountBox.addRoute({
+	name: 'livechat-users',
+	path: '/users',
+	sideNav: 'livechatFlex',
+	i18nPageTitle: 'Livechat_Users',
+	pageTemplate: 'livechatUsers'
+}, livechatManagerRoutes);
 
-FlowRouter.route('/livechat-manager/departments', {
+AccountBox.addRoute({
 	name: 'livechat-departments',
+	path: '/departments',
+	sideNav: 'livechatFlex',
+	i18nPageTitle: 'Departments',
+	pageTemplate: 'livechatDepartments'
+}, livechatManagerRoutes);
 
-	action: function(params, queryParams) {
-		BlazeLayout.render('main', { center: 'pageContainer', pageTemplate: 'livechatDepartments', pageTitle: t('Departments') });
-	}
-});
+AccountBox.addRoute({
+	name: 'livechat-department-edit',
+	path: '/departments/:_id/edit',
+	sideNav: 'livechatFlex',
+	i18nPageTitle: 'Edit_Department',
+	pageTemplate: 'livechatDepartmentForm'
+}, livechatManagerRoutes);
 
-FlowRouter.route('/livechat-manager/department/:_id?', {
-	name: 'livechat-department',
-
-	action: function(params, queryParams) {
-		if (params._id) {
-			pageTitle = t('Edit_Department');
-		} else {
-			pageTitle = t('New_Department');
-		}
-		BlazeLayout.render('main', { center: 'pageContainer', pageTemplate: 'livechatDepartmentForm', pageTitle: pageTitle});
-	}
-});
+AccountBox.addRoute({
+	name: 'livechat-department-new',
+	path: '/departments/new',
+	sideNav: 'livechatFlex',
+	i18nPageTitle: 'New_Department',
+	pageTemplate: 'livechatDepartmentForm'
+}, livechatManagerRoutes);
+
+AccountBox.addRoute({
+	name: 'livechat-triggers',
+	path: '/triggers',
+	sideNav: 'livechatFlex',
+	i18nPageTitle: 'Triggers',
+	pageTemplate: 'livechatTriggers'
+}, livechatManagerRoutes);
+
+AccountBox.addRoute({
+	name: 'livechat-installation',
+	path: '/installation',
+	sideNav: 'livechatFlex',
+	i18nPageTitle: 'Installation',
+	pageTemplate: 'livechatInstallation'
+}, livechatManagerRoutes);
+
+AccountBox.addRoute({
+	name: 'livechat-appearance',
+	path: '/appearance',
+	sideNav: 'livechatFlex',
+	i18nPageTitle: 'Appearance',
+	pageTemplate: 'livechatAppearance'
+}, livechatManagerRoutes);
diff --git a/packages/rocketchat-livechat/client/stylesheets/livechat.less b/packages/rocketchat-livechat/client/stylesheets/livechat.less
new file mode 100644
index 0000000000000000000000000000000000000000..24c80d0d8087829373dd473650a51e6a4558e321
--- /dev/null
+++ b/packages/rocketchat-livechat/client/stylesheets/livechat.less
@@ -0,0 +1,492 @@
+.calc(...) {
+	@process: ~`(function(e){function t(t,r){var a=");\n",c=n.split(","),i=c[0]+":"+t+"("+(c[1].trim()||0)+a;"start"==r?e="0;\n"+i:e+=i}e=e||8121991;var r="@{state}",n=e;if(8121991==e)return e;switch(r){case"1":t("-webkit-calc","start"),t("-moz-calc"),t("calc");break;case"2":t("-webkit-calc","start"),t("-moz-calc");break;case"3":t("-webkit-calc","start"),t("calc");break;case"4":t("-webkit-calc","start");break;case"5":t("-moz-calc","start"),t("calc");break;case"6":t("-moz-calc","start");break;case"7":t("calc","start")}return e=e.replace(/;$/g,"")})((function(){var e="@{arguments}";return e=e.replace(/^\[|\]$/g,"")})())`;
+	@state: 1; -lh-property: @process;
+
+}
+
+.transition(...) {
+	@process_webkit: ~`(function(e){e=e||"all 0 ease 0";var r=["background-size","border-radius","border-bottom-left-radius","border-bottom-right-radius","border-top-left-radius","border-top-right-radius","box-shadow","column","transform","filter"],t="-webkit-",n=/(?:\d)(?:ms|s)/gi,a=/(?:\s|^)(\.?\d+\.?\d*)(?![^(]*\)|\w|%)/gi;return/^[^, ]*,/.test(e)&&(e=e.replace(/(?:,)(?![^(]*\))/g,"")),r.forEach(function(r){-1!==e.indexOf(r)&&(e=e.replace(new RegExp(r,"g"),function(e){return t+e}))}),n.test(e)||"0"===e||(e=e.replace(a,function(e){return e+=parseFloat(e,10)>10?"ms":"s"})),e})((function(){var e="@{arguments}";return e=e.replace(/^\[|\]$/g,"")})())`;
+	@process_moz: ~`(function(e){e=e||"all 0 ease 0";var r=["background-size","box-shadow","column","transform","filter"],t="-moz-",n=/(?:\d)(?:ms|s)/gi,a=/(?:\s|^)(\.?\d+\.?\d*)(?![^(]*\)|\w|%)/gi;return/^[^, ]*,/.test(e)&&(e=e.replace(/(?:,)(?![^(]*\))/g,"")),r.forEach(function(r){-1!==e.indexOf(r)&&(e=e.replace(new RegExp(r,"g"),function(e){return t+e}))}),n.test(e)||"0"===e||(e=e.replace(a,function(e){return e+=parseFloat(e,10)>10?"ms":"s"})),e})((function(){var e="@{arguments}";return e=e.replace(/^\[|\]$/g,"")})())`;
+	@process_opera: ~`(function(e){e=e||"all 0 ease 0";var r=["transform"],t="-o-",n=/(?:\d)(?:ms|s)/gi,a=/(?:\s|^)(\.?\d+\.?\d*)(?![^(]*\)|\w|%)/gi;return/^[^, ]*,/.test(e)&&(e=e.replace(/(?:,)(?![^(]*\))/g,"")),r.forEach(function(r){-1!==e.indexOf(r)&&(e=e.replace(new RegExp(r,"g"),function(e){return t+e}))}),n.test(e)||"0"===e||(e=e.replace(a,function(e){return e+=parseFloat(e,10)>10?"ms":"s"})),e})((function(){var e="@{arguments}";return e=e.replace(/^\[|\]$/g,"")})())`;
+	@process: ~`(function(e){e=e||"all 0 ease 0";var r=["-webkit-","-moz-","-o-",""],t=["column","transform","filter"],n=/(?:\d)(?:ms|s)/gi,a=/(?:\s|^)(\.?\d+\.?\d*)(?![^(]*\)|\w|%)/gi;/^[^, ]*,/.test(e)&&(e=e.replace(/(?:,)(?![^(]*\))/g,""));var c=e.split(/(?:,)(?![^(]*\))/g);return c.forEach(function(e,n){t.forEach(function(t){-1!==e.indexOf(t)&&(c[n]="",r.forEach(function(a,u){c[n]+=e.trim().replace(new RegExp(t,"g"),function(e){return a+e}),u<r.length-1&&(c[n]+=",")}))})}),e=c.join(","),n.test(e)||"0"===e||(e=e.replace(a,function(e){return e+=parseFloat(e,10)>10?"ms":"s"})),e})((function(){var e="@{arguments}";return e=e.replace(/^\[|\]$/g,"")})())`;
+	-webkit-transition: @process_webkit;
+	-moz-transition: @process_moz;
+	-o-transition: @process_opera;
+	transition: @process;
+}
+
+.transform(...) {
+	@process: ~`(function(e){e=e||"none";var r={translate:"px",rotate:"deg",rotate3d:"deg",skew:"deg"};/^\w*\(?[a-z0-9.]*\)?/.test(e)&&(e=e.replace(/(?:,)(?![^(]*\))/g,""));for(var t in r)e.indexOf(t)>=0&&(e=e.replace(new RegExp(t+"[\\w]?\\([a-z0-9, %]*\\)"),function(e){var n=/(\d+\.?\d*)(?!\w|%)/g;return"rotate3d"==t&&(n=/,\s*\d+$/),e.replace(n,function(e){return e+r[t]})}));return e})((function(){var e="@{arguments}";return e=e.replace(/^\[|\]$/g,"")})())`;
+	-webkit-transform: @process;
+	-moz-transform: @process;
+	-o-transform: @process;
+	-ms-transform: @process;
+	transform: @process;
+}
+
+.flex-list {
+	.active {
+		background-color: rgba(255,255,255,0.075);
+	}
+}
+
+.trigger-option, .trigger-value {
+	float: left;
+	display: inline-block;
+}
+
+.trigger-option {
+	width: 30%;
+	max-width: 300px;
+	padding-right: 4px;
+}
+
+.trigger-value {
+	width: 70%;
+
+	input {
+		display: inline-block !important;
+		width: auto !important;
+	}
+}
+
+.livechat-code {
+	width: 90%;
+	max-width: 750px;
+	text-align: right;
+
+	textarea {
+		text-align: left;
+		width: 100%;
+		height: 200px;
+		background-color: #EFEFEF;
+		font-family: courier;
+		font-size: 12px;
+		display: block;
+	}
+}
+
+.preview-mode {
+	width: auto;
+	margin-bottom: 1em;
+}
+
+.livechat-settings-div, .livechat-preview-div {
+	width: 50%;
+	float: left;
+	height: 95%;
+	margin-bottom: 0 !important;
+	padding: 1em;
+}
+
+.livechat-settings-div {
+	border-right: 1px solid #CCC;
+}
+
+.livechat-preview {
+	width: 340px;
+	height: 350px;
+	margin: 0 auto;
+
+	border-bottom: 1px solid #CCC;
+	position: relative;
+
+	.preview-wrapper {
+		position: absolute;
+		width: 100%;
+		padding: 0 20px;
+		height: 350px;
+		bottom: 0;
+
+		@header-min-height: 30px;
+		@footer-min-height: 42px;
+		@link-font-color: #008CE3;
+		@primary-font-color: #444444;
+		@secondary-font-color: #7f7f7f;
+		@info-font-color: #AAAAAA;
+
+		.livechat-room {
+			display: flex;
+			flex-direction: column;
+			height: 100%;
+
+			.title {
+				flex: 1 0 @header-min-height;
+
+				line-height: @header-min-height;
+
+				border-top-right-radius: 5px;
+				border-top-left-radius: 5px;
+				color: #FFF;
+				z-index: 10;
+				cursor: pointer;
+				h1 {
+					margin: 0;
+					padding: 0 5px;
+					font-size: 9pt;
+					display: inline-block;
+					text-transform: none;
+				}
+
+				.toolbar {
+					display: inline-block;
+					float: right;
+					padding-right: 5px;
+				}
+			}
+			.messages {
+				flex: 1 1 100%;
+
+				background-color: #FFF;
+				border-left: 1px solid #E7E7E7;
+				border-right: 1px solid #E7E7E7;
+				overflow-y: auto;
+				.wrapper {
+					padding-bottom: 6px;
+
+					ul {
+						list-style-type: none;
+						padding: 0;
+						li {
+							padding: 0;
+						}
+					}
+
+					.message {
+						font-size: 12px;
+						padding-left: 40px;
+						position: relative;
+						line-height: 18px;
+						margin: 12px 10px 0;
+						min-height: 36px;
+						&:nth-child(1) {
+							margin-top: 0;
+						}
+						&.new-day {
+							margin-top: 60px;
+						}
+						&.new-day {
+							&:before {
+								content: attr(data-date);
+								display: block;
+								position: absolute;
+								top: -30px;
+								left: 0;
+								font-size: 10px;
+								font-weight: 600;
+								text-align: center;
+								.calc(left, ~'50% - 70px');
+								color: @secondary-font-color;
+								z-index: 10;
+								padding: 0 10px;
+								background-color: #FFF;
+								min-width: 120px;
+							}
+							&:after {
+								content: " ";
+								display: block;
+								position: absolute;
+								top: -20px;
+								left: 0;
+								width: 100%;
+								border-top: 1px solid #ddd;
+							}
+						}
+						.edit-message {
+							display: none;
+							cursor: pointer;
+						}
+						&.own:hover:not(.system) .edit-message {
+							display: inline-block;
+						}
+						.delete-message {
+							display: none;
+							cursor: pointer;
+						}
+						&.own:hover:not(.system) .delete-message {
+							display: inline-block;
+						}
+						.user {
+							display: inline-block;
+							font-weight: 600;
+							color: #444444;
+							margin-right: 5px;
+							outline: none;
+							&:hover {
+								color: #333;
+							}
+						}
+						.thumb {
+							position: absolute;
+							left: 0;
+							top: 0;
+							display: block;
+							width: 30px;
+							height: 30px;
+						}
+						.info {
+							font-size: 10px;
+							color: @info-font-color;
+						}
+						&.sequential {
+							// margin-top: 5px;
+							padding-top: 5px;
+							margin-top: 0;
+							margin-bottom: 0;
+							min-height: 20px;
+							.user {
+								display: none;
+							}
+							.thumb {
+								display: none;
+							}
+							.info {
+								position: absolute;
+								text-align: right;
+								left: -20px;
+								width: 55px;
+								.time {
+									display: none;
+								}
+								.edited {
+									display: inline-block;
+								}
+								.edit-message {
+									float: left;
+									margin-left: 1px;
+								}
+								.delete-message {
+									float: left;
+								}
+							}
+							&:hover {
+								.time {
+									display: inline-block;
+								}
+								.edited {
+									display: none;
+								}
+							}
+						}
+						&.system {
+							.body {
+								color: @info-font-color;
+								font-style: italic;
+								text-transform: lowercase;
+								em {
+									font-weight: 600;
+								}
+							}
+						}
+						.avatar-initials {
+							line-height: 40px;
+						}
+						a {
+							color: @link-font-color;
+							font-weight: 400;
+							&:hover {
+								color: darken(@link-font-color, 10%);
+								text-decoration: underline;
+							}
+						}
+						.body {
+							opacity: 1;
+							.transition(opacity 1s linear);
+						}
+						&.temp .body {
+							opacity: .5;
+						}
+						&.msg-error .body {
+							text-decoration: line-through;
+						}
+
+						.avatar .avatar-image {
+							height: 100%;
+							width: 100%;
+							min-height: 20px;
+							min-width: 20px;
+							display: block;
+							position: relative;
+							background-color: transparent;
+							background-size: cover;
+							background-repeat: no-repeat;
+							background-position: center;
+							border-radius: 4px;
+						}
+					}
+				}
+				.new-message {
+					margin: 0 -65px;
+					position: absolute;
+					background: #428bca;
+					border-radius: 20px;
+					width: 130px;
+					height: 30px;
+					text-align: center;
+					color: #FFF;
+					line-height: 30px;
+					font-size: 0.8em;
+					cursor: pointer;
+					bottom: 8px;
+					left: 50%;
+					z-index: 5;
+					.transition(transform 0.3s ease-out);
+					.transform(translateY(-40px));
+					&.not {
+						.transform(translateY(100%));
+					}
+				}
+
+				.error {
+					bottom: 40px;
+					position: fixed;
+					width: 100%;
+					background-color: #F7D799;
+					padding: 5px;
+					z-index: 8;
+
+					.transition(transform 0.2s ease-out);
+					.transform(translateY(100%));
+
+					&.show {
+						.transform(translateY(0));
+					}
+				}
+			}
+			.footer {
+				flex: 1 0 @footer-min-height;
+
+				z-index: 10;
+
+				background-color: #FCFCFC;
+				border-top: 1px solid #E7E7E7;
+				border-left: 1px solid #E7E7E7;
+				border-right: 1px solid #E7E7E7;
+
+				.input-wrapper {
+					padding: 6px;
+					textarea {
+						display: block;
+						padding: 6px 8px;
+						padding-right: 38px;
+						overflow-y: auto;
+						resize: none;
+						border: 1px solid #E7E7E7;
+						// margin: 10px;
+						border-radius: 5px;
+						max-height: 200px;
+						width: 100%;
+						font-size: 12px;
+						-webkit-appearance: none;
+						height: 28px;
+						line-height: normal;
+						background-color: #fff;
+						position: relative;
+						outline: none;
+					}
+				}
+			}
+			.offline {
+				flex: 1 1 100%;
+				font-weight: bold;
+				background-color: white;
+				padding: 2em 0;
+				text-align: center;
+			}
+		}
+	}
+
+	&.closed {
+		.preview-wrapper {
+			height: 32px;
+			.livechat-room .title .toolbar {
+				display: none;
+			}
+			.messages {
+				display: none;
+			}
+			.footer {
+				display: none;
+			}
+		}
+	}
+}
+
+.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;
+	}
+}
+
+.user-view {
+	li {
+		color: @secondary-font-color;
+		line-height: 18px;
+		font-size: 12px;
+		font-weight: 300;
+	}
+}
+
+.icon-chat-empty.status-offline {
+	color: @status-offline;
+}
+
+.icon-chat-empty.status-online {
+	color: @status-online;
+}
+
+.icon-chat-empty.status-busy {
+	color: @status-busy;
+}
+
+.icon-chat-empty.status-away {
+	color: @status-away;
+}
+
+.visitor-navigation {
+	height: 130px;
+	overflow-y: auto;
+	border: 1px solid #E7E7E7;
+	border-radius: 4px;
+	padding: 4px;
+	margin-top: 4px;
+
+	ul {
+		li {
+			white-space: nowrap;
+
+			a {
+				text-overflow: ellipsis;
+				display: block;
+				overflow: hidden;
+
+				color: @secondary-font-color;
+				text-decoration: underline;
+
+				&:hover {
+					text-decoration: none;
+				}
+			}
+		}
+	}
+}
diff --git a/packages/rocketchat-livechat/client/stylesheets/load.js b/packages/rocketchat-livechat/client/stylesheets/load.js
new file mode 100644
index 0000000000000000000000000000000000000000..3376dd0f6fd87d5408e7d56a33fc30e95f7b8bc3
--- /dev/null
+++ b/packages/rocketchat-livechat/client/stylesheets/load.js
@@ -0,0 +1,3 @@
+RocketChat.theme.addPackageAsset(() => {
+	return Assets.getText('client/stylesheets/livechat.less');
+});
diff --git a/packages/rocketchat-livechat/client/ui.js b/packages/rocketchat-livechat/client/ui.js
index ea863114c22fdbcfd6350ea8c71e743187d4d183..1041cfc75e6cad1157bb6eace4282008755e3791 100644
--- a/packages/rocketchat-livechat/client/ui.js
+++ b/packages/rocketchat-livechat/client/ui.js
@@ -7,6 +7,7 @@ RocketChat.roomTypes.add('l', 5, {
 		action: (params, queryParams) => {
 			Session.set('showUserInfo');
 			openRoom('l', params.name);
+			RocketChat.TabBar.showGroup('livechat', 'search');
 		},
 		link: (sub) => {
 			return {
@@ -14,21 +15,30 @@ RocketChat.roomTypes.add('l', 5, {
 			}
 		}
 	},
-	permissions: ['view-l-room']
+	condition: () => {
+		return RocketChat.settings.get('Livechat_enabled') && RocketChat.authz.hasAllPermission('view-l-room');
+	}
 });
 
 AccountBox.addItem({
 	name: 'Livechat',
 	icon: 'icon-chat-empty',
-	href: 'livechat-manager',
+	href: 'livechat-users',
 	sideNav: 'livechatFlex',
-	permissions: ['view-livechat-manager'],
+	condition: () => {
+		return RocketChat.settings.get('Livechat_enabled') && RocketChat.authz.hasAllPermission('view-livechat-manager');
+	},
 });
 
-AccountBox.addRoute({
-	name: 'livechat-manager',
-	path: '/livechat-manager',
-	sideNav: 'livechatFlex',
-	pageTitle: t('Livechat_Manager'),
-	pageTemplate: 'livechatManager'
+RocketChat.TabBar.addButton({
+	groups: ['livechat'],
+	id: 'visitor-info',
+	i18nTitle: 'Visitor_Info',
+	icon: 'octicon octicon-info',
+	template: 'visitorInfo',
+	order: 0
 });
+
+RocketChat.TabBar.addGroup('message-search', ['livechat']);
+RocketChat.TabBar.addGroup('starred-messages', ['livechat']);
+RocketChat.TabBar.addGroup('uploaded-files-list', ['livechat']);
diff --git a/packages/rocketchat-livechat/client/views/app/livechatAppearance.html b/packages/rocketchat-livechat/client/views/app/livechatAppearance.html
new file mode 100644
index 0000000000000000000000000000000000000000..d6b03dd458d75b4dabdf1f55896de38fbbf599b1
--- /dev/null
+++ b/packages/rocketchat-livechat/client/views/app/livechatAppearance.html
@@ -0,0 +1,68 @@
+<template name="livechatAppearance">
+	<div class="livechat-settings-div">
+		<h2>{{_ "Settings"}}</h2>
+
+		<form class="rocket-form">
+			<div class="input-line">
+				<label for="title">{{_ "Title"}}</label>
+				<input type="text" class="preview-settings" name="title" value="{{title}}">
+			</div>
+			<div class="input-line">
+				<label for="color">{{_ "Title_bar_color"}}</label>
+				<input type="text" class="preview-settings minicolors" name="color" value="{{color}}">
+			</div>
+			<div class="submit">
+				<button class="button secondary reset-settings"><i class="icon-ccw"></i>{{_ "Reset"}}</button>
+				<button class="button"><i class="icon-floppy"></i>{{_ "Save"}}</button>
+			</div>
+		</form>
+	</div>
+
+	<div class="livechat-preview-div">
+		<h2>{{_ "Preview"}}</h2>
+
+		<select class="preview-mode">
+			<option value="opened">{{_ "Opened"}}</option>
+			<option value="closed">{{_ "Closed"}}</option>
+		</select>
+
+		<div class="livechat-preview {{previewState}}">
+			<div class="preview-wrapper">
+				{{#with sampleData}}
+					<div class="livechat-room">
+						<div class="title" style="background-color:{{color}}">
+							<div class="toolbar">
+								&nbsp;
+								<i class="popout icon-link-ext" title="Open in a new window"></i>
+							</div>
+							<h1>{{title}}</h1>
+						</div>
+						<div class="messages">
+							<div class="wrapper">
+								<ul>
+									{{#each messages}}
+										<li id="{{_id}}" class="message {{sequential}}" data-username="{{u.username}}" data-date="{{date}}">
+											<span class="thumb thumb-small" href="#" data-username="{{u.username}}" tabindex="1">{{> avatar username=u.username}}</span>
+											<span class="user" href="#" data-username="{{u.username}}" tabindex="1">{{u.username}}</span>
+											<span class="info">
+												<span class="time">{{time}}</span>
+											</span>
+											<div class="body" dir="auto">
+												{{{body}}}
+											</div>
+										</li>
+									{{/each}}
+								</ul>
+							</div>
+						</div>
+						<div class="footer">
+							<div class="input-wrapper">
+								<textarea class="input-message" placeholder="Type your message"></textarea>
+							</div>
+						</div>
+					</div>
+				{{/with}}
+			</div>
+		</div>
+	</div>
+</template>
diff --git a/packages/rocketchat-livechat/client/views/app/livechatAppearance.js b/packages/rocketchat-livechat/client/views/app/livechatAppearance.js
new file mode 100644
index 0000000000000000000000000000000000000000..94e56f6f9ca8750a9c6d02bb8bb76d91912bb030
--- /dev/null
+++ b/packages/rocketchat-livechat/client/views/app/livechatAppearance.js
@@ -0,0 +1,139 @@
+Template.livechatAppearance.helpers({
+	previewState () {
+		return Template.instance().previewState.get();
+	},
+	color () {
+		return Template.instance().color.get();
+	},
+	title () {
+		return Template.instance().title.get();
+	},
+	sampleData () {
+		return {
+			color: RocketChat.settings.get('Livechat_title_color'),
+			title: RocketChat.settings.get('Livechat_title'),
+			messages: [
+				{
+					_id: Random.id(),
+					u: {
+						username: 'guest'
+					},
+					time: moment(this.ts).format('LT'),
+					date: moment(this.ts).format('LL'),
+					body: 'Hello',
+					sequential: null
+				},
+				{
+					_id: Random.id(),
+					u: {
+						username: 'rocketchat-agent'
+					},
+					time: moment(this.ts).format('LT'),
+					date: moment(this.ts).format('LL'),
+					body: 'Hey, what can I help you with?',
+					sequential: null
+				},
+				{
+					_id: Random.id(),
+					u: {
+						username: 'guest'
+					},
+					time: moment(this.ts).format('LT'),
+					date: moment(this.ts).format('LL'),
+					body: 'I\'m looking for informations about your product.',
+					sequential: null
+				},
+				{
+					_id: Random.id(),
+					u: {
+						username: 'rocketchat-agent'
+					},
+					time: moment(this.ts).format('LT'),
+					date: moment(this.ts).format('LL'),
+					body: 'Our product is open source, you can do what you want with it! =D',
+					sequential: null
+				},
+				{
+					_id: Random.id(),
+					u: {
+						username: 'guest'
+					},
+					time: moment(this.ts).format('LT'),
+					date: moment(this.ts).format('LL'),
+					body: 'Yay, thanks. That\'s awesome.',
+					sequential: null
+				},
+				{
+					_id: Random.id(),
+					u: {
+						username: 'rocketchat-agent'
+					},
+					time: moment(this.ts).format('LT'),
+					date: moment(this.ts).format('LL'),
+					body: 'You\'re welcome.',
+					sequential: null
+				}
+			]
+		};
+	}
+});
+
+Template.livechatAppearance.onCreated(function() {
+	this.previewState = new ReactiveVar('opened');
+
+	this.title = new ReactiveVar(null);
+	this.color = new ReactiveVar(null);
+
+	this.autorun(() => {
+		this.title.set(RocketChat.settings.get('Livechat_title'));
+	});
+	this.autorun(() => {
+		this.color.set(RocketChat.settings.get('Livechat_title_color'));
+	});
+});
+
+Template.livechatAppearance.events({
+	'change .preview-mode' (e, instance) {
+		instance.previewState.set(e.currentTarget.value);
+	},
+	'change .preview-settings, keyup .preview-settings' (e, instance) {
+		instance[e.currentTarget.name].set(e.currentTarget.value);
+	},
+	'click .reset-settings' (e, instance) {
+		e.preventDefault();
+
+		instance.title.set(RocketChat.settings.get('Livechat_title'));
+		instance.color.set(RocketChat.settings.get('Livechat_title_color'));
+
+		instance.$('input.preview-settings[name=color]').minicolors('value', instance.color.get());
+	},
+	'submit .rocket-form' (e, instance) {
+		e.preventDefault();
+
+		var settings = [
+			{
+				_id: 'Livechat_title',
+				value: instance.title.get()
+			},
+			{
+				_id: 'Livechat_title_color',
+				value: instance.color.get()
+			}
+		];
+		RocketChat.settings.batchSet(settings, (err, success) => {
+			if (err) {
+				return toastr.error(t('Error_updating_settings'));
+			}
+			toastr.success(t('Settings_updated'));
+		});
+	}
+})
+
+Template.livechatAppearance.onRendered(function() {
+	Meteor.setTimeout(() => {
+		$('input.minicolors').minicolors({
+			theme: 'rocketchat',
+			letterCase: 'uppercase'
+		});
+	}, 500);
+});
diff --git a/packages/rocketchat-livechat/client/views/app/livechatDashboard.html b/packages/rocketchat-livechat/client/views/app/livechatDashboard.html
new file mode 100644
index 0000000000000000000000000000000000000000..ae5a2b7df4fffcd938e5e53b0283ee761966c868
--- /dev/null
+++ b/packages/rocketchat-livechat/client/views/app/livechatDashboard.html
@@ -0,0 +1,3 @@
+<template name="livechatDashboard">
+	<h1>Dashboard</h1>
+</template>
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.html b/packages/rocketchat-livechat/client/views/app/livechatDepartments.html
index a334421e88e34715b460b107269f72be9a1d9898..2c92e7b07cc6dc5d59372fde3560774963ab606f 100644
--- a/packages/rocketchat-livechat/client/views/app/livechatDepartments.html
+++ b/packages/rocketchat-livechat/client/views/app/livechatDepartments.html
@@ -24,8 +24,5 @@
 		</table>
 	</div>
 
-	<form id="form-manager" class="inline">
-		<button name="newDepartment" class="button primary">{{_ "New_Department"}}</button>
-	</form>
-
+	<a href="{{pathFor 'livechat-department-new'}}" class="button primary">{{_ "New_Department"}}</a>
 </template>
diff --git a/packages/rocketchat-livechat/client/views/app/livechatDepartments.js b/packages/rocketchat-livechat/client/views/app/livechatDepartments.js
index 274f1d1876e597cf27e302f83ed81e2dcc2718dd..e5d0746485dc5ca44f2183e639372807151d4e8e 100644
--- a/packages/rocketchat-livechat/client/views/app/livechatDepartments.js
+++ b/packages/rocketchat-livechat/client/views/app/livechatDepartments.js
@@ -1,20 +1,10 @@
 Template.livechatDepartments.helpers({
 	"departments": () => {
 		return LivechatDepartment.find();
-	},
-	"numAgents"() {
-		if (Array.isArray(this.agents)) {
-			return this.agents.length;
-		}
 	}
 });
 
 Template.livechatDepartments.events({
-	"click button[name=newDepartment]": (event, instance) => {
-		event.preventDefault();
-		FlowRouter.go('livechat-department');
-	},
-
 	'click .remove-department' (e, instance) {
 		e.preventDefault();
 		e.stopPropagation();
@@ -46,7 +36,7 @@ Template.livechatDepartments.events({
 
 	'click .department-info' (e, instance) {
 		e.preventDefault();
-		FlowRouter.go('livechat-department', { _id: this._id });
+		FlowRouter.go('livechat-department-edit', { _id: this._id });
 	}
 });
 
diff --git a/packages/rocketchat-livechat/client/views/app/livechatInstallation.html b/packages/rocketchat-livechat/client/views/app/livechatInstallation.html
new file mode 100644
index 0000000000000000000000000000000000000000..6d912bb3cca378198721177f7d2cefa6f1f5d4b3
--- /dev/null
+++ b/packages/rocketchat-livechat/client/views/app/livechatInstallation.html
@@ -0,0 +1,8 @@
+<template name="livechatInstallation">
+	<p>{{{_ "To_install_RocketChat_Livechat_in_your_website_copy_paste_this_code_above_the_last_body_tag_on_your_site"}}}</p>
+
+	<div class="livechat-code">
+		<textarea class="clipboard" data-clipboard-target=".livechat-code textarea">{{script}}</textarea>
+		<button class="button clipboard" data-clipboard-target=".livechat-code textarea"><i class="icon-docs"></i>{{_ "Copy_to_clipboard"}}</button>
+	</div>
+</template>
diff --git a/packages/rocketchat-livechat/client/views/app/livechatInstallation.js b/packages/rocketchat-livechat/client/views/app/livechatInstallation.js
new file mode 100644
index 0000000000000000000000000000000000000000..339d894e6904f91ee620495bb7b850aecd790003
--- /dev/null
+++ b/packages/rocketchat-livechat/client/views/app/livechatInstallation.js
@@ -0,0 +1,17 @@
+Template.livechatInstallation.helpers({
+	script () {
+		return `<!-- Start of Rocket.Chat Livechat Script -->
+<script type="text/javascript">
+(function(w, d, s, f, u) {
+	w[f] = w[f] || [];
+	w[f].push(u);
+	var h = d.getElementsByTagName(s)[0],
+		j = d.createElement(s);
+	j.async = true;
+	j.src = '${RocketChat.settings.get('Site_Url')}/packages/rocketchat_livechat/assets/rocket-livechat.js';
+	h.parentNode.insertBefore(j, h);
+})(window, document, 'script', 'initRocket', '${RocketChat.settings.get('Site_Url')}/livechat');
+</script>
+<!-- End of Rocket.Chat Livechat Script -->`;
+	}
+})
diff --git a/packages/rocketchat-livechat/client/views/app/livechatTriggers.html b/packages/rocketchat-livechat/client/views/app/livechatTriggers.html
new file mode 100644
index 0000000000000000000000000000000000000000..98e5bd9b9e50aeecbed1a2240d142aa0d825f435
--- /dev/null
+++ b/packages/rocketchat-livechat/client/views/app/livechatTriggers.html
@@ -0,0 +1,32 @@
+<template name="livechatTriggers">
+	<form id="trigger-form">
+		<div class="rocket-form">
+			<fieldset>
+				<legend>{{_ "Condition"}}</legend>
+				<div class="conditions">
+					{{#each conditions}}
+						{{> livechatTriggerCondition}}
+					{{/each}}
+					{{#unless conditions}}
+						{{> livechatTriggerCondition}}
+					{{/unless}}
+				</div>
+			</fieldset>
+			<fieldset>
+				<legend>{{_ "Action"}}</legend>
+				<div class="actions">
+					{{#each actions}}
+						{{> livechatTriggerAction}}
+					{{/each}}
+					{{#unless actions}}
+						{{> livechatTriggerAction}}
+					{{/unless}}
+				</div>
+			</fieldset>
+			<div class="submit">
+				<button type="button" class="button red delete-trigger">{{_ "Delete"}}</button>
+				<button class="button save"><i class="icon-floppy"></i><span>{{_ "Save"}}</span></button>
+			</div>
+		</div>
+	</form>
+</template>
diff --git a/packages/rocketchat-livechat/client/views/app/livechatTriggers.js b/packages/rocketchat-livechat/client/views/app/livechatTriggers.js
new file mode 100644
index 0000000000000000000000000000000000000000..d36632f0f7f0d66b80b4d93d961aa134be77c97b
--- /dev/null
+++ b/packages/rocketchat-livechat/client/views/app/livechatTriggers.js
@@ -0,0 +1,98 @@
+Template.livechatTriggers.helpers({
+	conditions() {
+		var trigger = Template.instance().trigger.get();
+		if (!trigger) return [];
+
+		return trigger.conditions;
+	},
+	actions() {
+		var trigger = Template.instance().trigger.get();
+		if (!trigger) return [];
+
+		return trigger.actions;
+	}
+});
+
+Template.livechatTriggers.events({
+	'submit #trigger-form' (e, instance) {
+		e.preventDefault();
+		var $btn = instance.$('button.save');
+
+		var oldBtnValue = $btn.html();
+		$btn.html(t('Saving'));
+
+		var data = {
+			conditions: [],
+			actions: []
+		};
+
+		$('.each-condition').each(function() {
+			data.conditions.push({
+				name: $('.trigger-condition', this).val(),
+				value: $('.' + $('.trigger-condition', this).val() + '-value').val()
+			});
+		});
+
+		$('.each-action').each(function() {
+			if ($('.trigger-action', this).val() === 'send-message') {
+				data.actions.push({
+					name: $('.trigger-action', this).val(),
+					params: {
+						name: $('[name=send-message-name]', this).val(),
+						msg: $('[name=send-message-msg]', this).val()
+					}
+				});
+			} else {
+				data.actions.push({
+					name: $('.trigger-action', this).val(),
+					value: $('.' + $('.trigger-action', this).val() + '-value').val()
+				});
+			}
+		});
+
+		Meteor.call('livechat:saveTrigger', data, function(error, result) {
+			$btn.html(oldBtnValue);
+			if (error) {
+				return toastr.error(t(error.reason || error.error));
+			}
+
+			toastr.success(t('Saved'));
+		});
+	},
+	'click .delete-trigger' (e, instance) {
+		e.preventDefault()
+
+		swal({
+			title: t('Are_you_sure'),
+			type: 'warning',
+			showCancelButton: true,
+			confirmButtonColor: '#DD6B55',
+			confirmButtonText: t('Yes'),
+			cancelButtonText: t('Cancel'),
+			closeOnConfirm: false,
+			html: false,
+		}, () => {
+			Meteor.call('livechat:removeTrigger', function(error, result) {
+				if (error) {
+					return toastr.error(t(error.reason || error.error));
+				}
+
+				swal({
+					title: t('Removed'),
+					text: t('Trigger_removed'),
+					type: 'success',
+					timer: 1000,
+					showConfirmButton: false,
+				});
+			});
+		});
+	}
+});
+
+Template.livechatTriggers.onCreated(function() {
+	this.subscribe('livechat:trigger');
+	this.trigger = new ReactiveVar(null);
+	this.autorun(() => {
+		this.trigger.set(LivechatTrigger.findOne());
+	});
+});
diff --git a/packages/rocketchat-livechat/client/views/app/livechatManager.html b/packages/rocketchat-livechat/client/views/app/livechatUsers.html
similarity index 95%
rename from packages/rocketchat-livechat/client/views/app/livechatManager.html
rename to packages/rocketchat-livechat/client/views/app/livechatUsers.html
index fc90993a0c2a168bcdb928d1eb00b451ace573d6..9bdb3f99dbd31a6495adab4572de979f07942818 100644
--- a/packages/rocketchat-livechat/client/views/app/livechatManager.html
+++ b/packages/rocketchat-livechat/client/views/app/livechatUsers.html
@@ -1,4 +1,4 @@
-<template name="livechatManager">
+<template name="livechatUsers">
 	<h2>{{_ "Livechat_managers"}}</h2>
 	<form id="form-manager" class="inline">
 		<label>{{_ "Add_manager"}}</label>
@@ -27,7 +27,7 @@
 						<td>{{name}}</td>
 						<td>{{username}}</td>
 						<td>{{emailAddress}}</td>
-						<td><a href="#remove" class="remove-manager"><i class="icon-block"></i></a></td>
+						<td><a href="#remove" class="remove-manager"><i class="icon-trash"></i></a></td>
 					</tr>
 				{{/each}}
 			</tbody>
@@ -61,7 +61,7 @@
 						<td>{{name}}</td>
 						<td>{{username}}</td>
 						<td>{{emailAddress}}</td>
-						<td><a href="#remove" class="remove-agent"><i class="icon-block"></i></a></td>
+						<td><a href="#remove" class="remove-agent"><i class="icon-trash"></i></a></td>
 					</tr>
 				{{/each}}
 			</tbody>
diff --git a/packages/rocketchat-livechat/client/views/app/livechatManager.js b/packages/rocketchat-livechat/client/views/app/livechatUsers.js
similarity index 94%
rename from packages/rocketchat-livechat/client/views/app/livechatManager.js
rename to packages/rocketchat-livechat/client/views/app/livechatUsers.js
index 173cb633a50cf64cd14ebcc420cbf195345f3b44..eeb2d1dfa783871db0ac7e895ea3ec79d40ff31a 100644
--- a/packages/rocketchat-livechat/client/views/app/livechatManager.js
+++ b/packages/rocketchat-livechat/client/views/app/livechatUsers.js
@@ -1,12 +1,10 @@
-var AgentUsers;
 var ManagerUsers;
 
 Meteor.startup(function() {
-	AgentUsers = new Mongo.Collection('agentUsers');
 	ManagerUsers = new Mongo.Collection('managerUsers');
 });
 
-Template.livechatManager.helpers({
+Template.livechatUsers.helpers({
 	managers() {
 		return ManagerUsers.find({}, { sort: { name: 1 } });
 	},
@@ -20,7 +18,7 @@ Template.livechatManager.helpers({
 	}
 });
 
-Template.livechatManager.events({
+Template.livechatUsers.events({
 	'click .remove-manager' (e, instance) {
 		e.preventDefault();
 
@@ -119,7 +117,7 @@ Template.livechatManager.events({
 	}
 });
 
-Template.livechatManager.onCreated(function() {
+Template.livechatUsers.onCreated(function() {
 	this.subscribe('livechat:agents');
 	this.subscribe('livechat:managers');
 });
diff --git a/packages/rocketchat-livechat/client/views/app/tabbar/visitorInfo.html b/packages/rocketchat-livechat/client/views/app/tabbar/visitorInfo.html
new file mode 100644
index 0000000000000000000000000000000000000000..77872c89773683fe1f7a6434e5caa91b277e945e
--- /dev/null
+++ b/packages/rocketchat-livechat/client/views/app/tabbar/visitorInfo.html
@@ -0,0 +1,46 @@
+<template name="visitorInfo">
+	<div class="content">
+		<div class="user-view">
+
+			{{#with user}}
+			<div class="about clearfix">
+				<div class="thumb">
+					{{> avatar username=username}}
+				</div>
+				<div class="info">
+					<h3 title="{{username}}"><i class="status-{{status}}"></i> {{username}}</h3>
+					<p>{{name}}</p>
+
+					<ul>
+						{{#if utc}}<li><i class="icon-clock"></i>{{userTime}} (UTC {{utc}})</li>{{/if}}
+						{{#each emails}} <li><i class="icon-mail"></i> {{address}}{{#if verified}}&nbsp;<i class="icon-ok"></i>{{/if}}</li> {{/each}}
+						{{#each phone}} <li><i class="icon-phone"></i> {{phoneNumber}}</li> {{/each}}
+						{{#if lastLogin}} <li><i class="icon-calendar"></i> {{_ "Created_at"}}: {{createdAt}}</li> {{/if}}
+						{{#if lastLogin}} <li><i class="icon-calendar"></i> {{_ "Last_login"}}: {{lastLogin}}</li> {{/if}}
+						{{#if ip}}<li><i class="icon-laptop"></i><span>{{ip}}</span></li>{{/if}}
+						{{#if os}}<li><i class="{{osIcon}}"></i><span>{{os}}</span></li>{{/if}}
+						{{#if browser}}<li><i class="{{browserIcon}}"></i><span>{{browser}}</span></li>{{/if}}
+					</ul>
+				</div>
+			</div>
+			{{/with}}
+			<nav>
+				<!-- <button class="button pvt-msg"><span><i class="icon-forward"></i> {{_ "Forward"}}</span></button> -->
+			</nav>
+
+			<h4>{{_ "Navigation_History_20_last_pages"}}</h4>
+
+			<div class="visitor-navigation">
+				{{#if loadingNavigation}}
+					{{_ "Loading..."}}
+				{{else}}
+					<ul>
+						{{#each pageVisited}}
+							<li><a href="{{page.location.href}}" target="_blank" title="{{accessDateTime}}">{{pageTitle}}</a></li>
+						{{/each}}
+					</ul>
+				{{/if}}
+			</div>
+		</div>
+	</div>
+</template>
diff --git a/packages/rocketchat-livechat/client/views/app/tabbar/visitorInfo.js b/packages/rocketchat-livechat/client/views/app/tabbar/visitorInfo.js
new file mode 100644
index 0000000000000000000000000000000000000000..48feb1fdd129a9f164165ee5f68b3523fc9d3df7
--- /dev/null
+++ b/packages/rocketchat-livechat/client/views/app/tabbar/visitorInfo.js
@@ -0,0 +1,70 @@
+Template.visitorInfo.helpers({
+	user() {
+		var user = Meteor.users.findOne({ "profile.token": Template.instance().visitorToken.get() });
+		if (user && user.userAgent) {
+			var ua = new UAParser();
+			ua.setUA(user.userAgent);
+
+			user.os = ua.getOS().name + ' ' + ua.getOS().version;
+			if (['Mac OS', 'iOS'].indexOf(ua.getOS().name) !== -1) {
+				user.osIcon = 'icon-apple';
+			} else {
+				user.osIcon = 'icon-' +  ua.getOS().name.toLowerCase();
+			}
+			user.browser = ua.getBrowser().name + ' ' + ua.getBrowser().version;
+			user.browserIcon = 'icon-' + ua.getBrowser().name.toLowerCase();
+		}
+
+		return user;
+	},
+
+	loadingNavigation() {
+		return !Template.instance().pageVisited.ready();
+	},
+
+	pageVisited() {
+		return LivechatPageVisited.find({ token: Template.instance().visitorToken.get() }, { sort: { ts: -1 } });
+	},
+
+	pageTitle() {
+		return this.page.title || t('Empty_title');
+	},
+
+	accessDateTime() {
+		return moment(this.ts).format('L LTS');
+	},
+
+	createdAt() {
+		if (!this.createdAt) {
+			return '';
+		}
+		return moment(this.createdAt).format('L LTS');
+	},
+
+	lastLogin() {
+		if (!this.lastLogin) {
+			return '';
+		}
+		return moment(this.lastLogin).format('L LTS');
+	}
+});
+
+Template.visitorInfo.onCreated(function() {
+	this.visitorToken = new ReactiveVar(null);
+
+	var currentData = Template.currentData();
+
+	if (currentData && currentData.rid) {
+		this.autorun(() => {
+			var room = ChatRoom.findOne(currentData.rid);
+			if (room && room.v && room.v.token) {
+				this.visitorToken.set(room.v.token);
+			} else {
+				this.visitorToken.set();
+			}
+		});
+
+		this.subscribe('livechat:visitorInfo', currentData.rid);
+		this.pageVisited = this.subscribe('livechat:visitorPageVisited', currentData.rid);
+	}
+})
diff --git a/packages/rocketchat-livechat/client/views/app/triggers/livechatTriggerAction.html b/packages/rocketchat-livechat/client/views/app/triggers/livechatTriggerAction.html
new file mode 100644
index 0000000000000000000000000000000000000000..4a4328b7ae87f2f898e936d3886fd66ec7b550a4
--- /dev/null
+++ b/packages/rocketchat-livechat/client/views/app/triggers/livechatTriggerAction.html
@@ -0,0 +1,15 @@
+<template name="livechatTriggerAction">
+	<div class="input-line each-action">
+		<div class="trigger-option">
+			<select name="action" class="trigger-action">
+				<option value="send-message">{{_ "Send_a_message"}}</option>
+			</select>
+		</div>
+		<div class="trigger-value">
+			<div class="send-message {{hiddenValue 'send-message'}}">
+				<input type="text" name="send-message-name" placeholder="{{_ "Name_of_agent"}}" value="{{params.name}}" size="15">
+				<input type="text" name="send-message-msg" placeholder="{{_ "Message"}}" value="{{params.msg}}">
+			</div>
+		</div>
+	</div>
+</template>
diff --git a/packages/rocketchat-livechat/client/views/app/triggers/livechatTriggerAction.js b/packages/rocketchat-livechat/client/views/app/triggers/livechatTriggerAction.js
new file mode 100644
index 0000000000000000000000000000000000000000..7ef854e593fe17fd1d77d5fc04537b2b5654284a
--- /dev/null
+++ b/packages/rocketchat-livechat/client/views/app/triggers/livechatTriggerAction.js
@@ -0,0 +1,23 @@
+Template.livechatTriggerAction.helpers({
+	hiddenValue (current) {
+		if (this.name === undefined && Template.instance().firstAction) {
+			Template.instance().firstAction = false;
+			return '';
+		} else {
+			if (this.name !== current) {
+				return 'hidden';
+			}
+		}
+	}
+});
+
+Template.livechatTriggerAction.events({
+	'change .trigger-action' (e, instance) {
+		instance.$('.trigger-action-value ').addClass('hidden');
+		instance.$('.' + e.currentTarget.value).removeClass('hidden');
+	}
+});
+
+Template.livechatTriggerAction.onCreated(function() {
+	this.firstAction = true;
+});
diff --git a/packages/rocketchat-livechat/client/views/app/triggers/livechatTriggerCondition.html b/packages/rocketchat-livechat/client/views/app/triggers/livechatTriggerCondition.html
new file mode 100644
index 0000000000000000000000000000000000000000..3e61db95a66c5b0dec87ad8cd25f49705a8ac4d4
--- /dev/null
+++ b/packages/rocketchat-livechat/client/views/app/triggers/livechatTriggerCondition.html
@@ -0,0 +1,18 @@
+<template name="livechatTriggerCondition">
+	<div class="input-line each-condition">
+		<div class="trigger-option">
+			<select name="condition" class="trigger-condition">
+				<option value="page-url" selected="{{conditionSelected 'page-url'}}">{{_ "Visitor_page_URL"}}</option>
+				<option value="time-on-site" selected="{{conditionSelected 'time-on-site'}}">{{_ "Visitor_time_on_site"}}</option>
+			</select>
+		</div>
+		<div class="trigger-value">
+			<div class="page-url trigger-condition-value {{hiddenValue 'page-url'}}">
+				<input type="text" name="page-url-value" class="page-url-value" placeholder="{{_ "Enter_a_regex"}}" value="{{valueFor 'page-url'}}">
+			</div>
+			<div class="time-on-site trigger-condition-value {{hiddenValue 'time-on-site'}}">
+				<input type="number" name="time-on-site-value" class="time-on-site-value" placeholder="{{_ "Time_in_seconds"}}" value="{{valueFor 'time-on-site'}}">
+			</div>
+		</div>
+	</div>
+</template>
diff --git a/packages/rocketchat-livechat/client/views/app/triggers/livechatTriggerCondition.js b/packages/rocketchat-livechat/client/views/app/triggers/livechatTriggerCondition.js
new file mode 100644
index 0000000000000000000000000000000000000000..a99fa0213e104280d543c906dad247297b01dd56
--- /dev/null
+++ b/packages/rocketchat-livechat/client/views/app/triggers/livechatTriggerCondition.js
@@ -0,0 +1,33 @@
+Template.livechatTriggerCondition.helpers({
+	hiddenValue (current) {
+		if (this.name === undefined && Template.instance().firstCondition) {
+			Template.instance().firstCondition = false;
+			return '';
+		} else {
+			if (this.name !== current) {
+				return 'hidden';
+			}
+		}
+	},
+	conditionSelected (current) {
+		if (this.name === current) {
+			return 'selected';
+		}
+	},
+	valueFor (condition) {
+		if (this.name === condition) {
+			return this.value;
+		}
+	}
+});
+
+Template.livechatTriggerCondition.events({
+	'change .trigger-condition' (e, instance) {
+		instance.$('.trigger-condition-value ').addClass('hidden');
+		instance.$('.' + e.currentTarget.value).removeClass('hidden');
+	}
+});
+
+Template.livechatTriggerCondition.onCreated(function() {
+	this.firstCondition = true;
+})
diff --git a/packages/rocketchat-livechat/client/views/sideNav/livechatFlex.html b/packages/rocketchat-livechat/client/views/sideNav/livechatFlex.html
index ae76e6746d9fd67fb5d2e9b9bc5701d572004270..15d3ed86810d5ea9900b2019a5a1e405bcaf0040 100644
--- a/packages/rocketchat-livechat/client/views/sideNav/livechatFlex.html
+++ b/packages/rocketchat-livechat/client/views/sideNav/livechatFlex.html
@@ -6,14 +6,14 @@
 	</header>
 	<div class="content">
 		<div class="wrapper">
-			<ul>
+			<ul class="flex-list">
 				<li>
-					<a href="#link" class="admin-link">{{_ "Dashboard"}}</a>
-					<a href="#link" class="admin-link">{{_ "User_management"}}</a>
-					<a href="{{pathFor 'livechat-departments'}}" class="admin-link">{{_ "Departments"}}</a>
-					<a href="#link" class="admin-link">{{_ "Theme"}}</a>
-					<a href="#link" class="admin-link">{{_ "Integrations"}}</a>
-					<a href="#link" class="admin-link">{{_ "Live_sessions"}}</a>
+					<!-- <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' '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>
 				</li>
 			</ul>
 		</div>
diff --git a/packages/rocketchat-livechat/client/views/sideNav/livechatFlex.js b/packages/rocketchat-livechat/client/views/sideNav/livechatFlex.js
index 2fa2ed15adfadd4849720b5c52705b8b69361848..f7a8f2f0accfa20b5f6c2ac43157e25744ef432b 100644
--- a/packages/rocketchat-livechat/client/views/sideNav/livechatFlex.js
+++ b/packages/rocketchat-livechat/client/views/sideNav/livechatFlex.js
@@ -1,3 +1,12 @@
+Template.livechatFlex.helpers({
+	active (...routes) {
+		FlowRouter.watchPathChange();
+		if (routes.indexOf(FlowRouter.current().route.name) !== -1) {
+			return 'active';
+		}
+	}
+});
+
 Template.livechatFlex.events({
 	'mouseenter header' () {
 		SideNav.overArrow()
@@ -10,4 +19,4 @@ Template.livechatFlex.events({
 	'click header' () {
 		SideNav.closeFlex()
 	}
-})
+});
diff --git a/packages/rocketchat-livechat/config.js b/packages/rocketchat-livechat/config.js
index 9ae62a8ecb133a1be17de7141630519ed4812c1e..424768e39a961145a991b1392d876437449bc6bd 100644
--- a/packages/rocketchat-livechat/config.js
+++ b/packages/rocketchat-livechat/config.js
@@ -2,5 +2,6 @@ Meteor.startup(function() {
 	RocketChat.settings.addGroup('Livechat');
 	RocketChat.settings.add('Livechat_title'       , 'Rocket.Chat', { type: 'string', group: 'Livechat', public: true });
 	RocketChat.settings.add('Livechat_title_color' , '#C1272D',     { type: 'string', group: 'Livechat', public: true });
-	RocketChat.settings.add('Livechat_enabled' ,     true,          { type: 'boolean', group: 'Livechat', public: true });
+	RocketChat.settings.add('Livechat_enabled' ,     false,          { type: 'boolean', group: 'Livechat', public: true });
+	RocketChat.settings.add('Livechat_registration_form' , true,    { type: 'boolean', group: 'Livechat', public: true, i18nLabel: 'Show_preregistration_form' });
 });
diff --git a/packages/rocketchat-livechat/i18n/ar.i18n.json b/packages/rocketchat-livechat/i18n/ar.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..5d22fd60b4c8e95d9b5dc6c5ad4abaa43fd478ff 100644
--- a/packages/rocketchat-livechat/i18n/ar.i18n.json
+++ b/packages/rocketchat-livechat/i18n/ar.i18n.json
@@ -1 +1,17 @@
-{ }
\ No newline at end of file
+{
+  "Add" : "إضافة",
+  "Back" : "العودة",
+  "Closed" : "مغلق",
+  "Copy_to_clipboard" : "نسخ إلى الحافظة",
+  "Description" : "الوصف",
+  "Enable" : "تمكين",
+  "Enter_a_username" : "أدخل اسم المستخدم",
+  "Livechat_enabled" : "مكنت LIVECHAT",
+  "Livechat_title" : "عنوان الدردشة الحية",
+  "Livechat_title_color" : "لون خلفية عنوان الدردشة الحية",
+  "Please_fill_a_username" : "يرجى ملء اسم المستخدم",
+  "Saved" : "تم الحفظ",
+  "Send_a_message" : "إرسال رسالة",
+  "Theme" : "سمات",
+  "Time_in_seconds" : "الوقت بالثواني"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/cs.i18n.json b/packages/rocketchat-livechat/i18n/cs.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..6ad288846f91d3de48ed4fcb65fa96b547442e4c 100644
--- a/packages/rocketchat-livechat/i18n/cs.i18n.json
+++ b/packages/rocketchat-livechat/i18n/cs.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Livechat_enabled" : "Livechat povoleno"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/de.i18n.json b/packages/rocketchat-livechat/i18n/de.i18n.json
index 30411a053d4faec2a9b25e7d934391bdbf21d76c..cf1cb71ca41362ce6f12cd69b717cff91dcfefdc 100644
--- a/packages/rocketchat-livechat/i18n/de.i18n.json
+++ b/packages/rocketchat-livechat/i18n/de.i18n.json
@@ -1,4 +1,58 @@
 {
-  "Livechat_title" : "Livechat Titel",
-  "Livechat_title_color" : "Livechat Titel Hintergrundfarbe"
+  "Add" : "Hinzufügen",
+  "Add_agent" : "Agent hinzufügen",
+  "Add_manager" : "Manager hinzufügen",
+  "Agent_added" : "Der Agent wurde hinzugefügt.",
+  "Agent_removed" : "Der Agent wurde gelöscht.",
+  "Available_agents" : "Verfügbare Agenten",
+  "Back" : "Zurück",
+  "Closed" : "Geschlossen",
+  "Copy_to_clipboard" : "In die Zwischenablage kopieren",
+  "Count" : "Zähler",
+  "Dashboard" : "Dashboard",
+  "Department_not_found" : "Abteilung konnte nicht gefunden werden.",
+  "Department_removed" : "Die Abteilung wurde gelöscht.",
+  "Departments" : "Abteilungen",
+  "Description" : "Beschreibung",
+  "Edit_Department" : "Abteilung bearbeiten",
+  "Empty_title" : "Es wurde kein Titel angegeben.",
+  "Enable" : "Aktivieren",
+  "Enabled" : "Aktiviert",
+  "Enter_a_regex" : "Geben Sie einen regex ein.",
+  "Enter_a_username" : "Geben Sie einen Benutzernamen ein",
+  "Live_sessions" : "Live-Sitzungen",
+  "Livechat_agents" : "LiveChat-Agent",
+  "Livechat_Dashboard" : "LiveChat-Dashboard",
+  "Livechat_enabled" : "LiveChat aktiviert",
+  "Livechat_Manager" : "LiveChat-Manager",
+  "Livechat_managers" : "LiveChat-Manager",
+  "Livechat_title" : "LiveChat-Titel",
+  "Livechat_title_color" : "Hintergrundfarbe des LiveChat-Titels",
+  "Livechat_Users" : "LiveChat-Benutzer",
+  "Manager_added" : "Der Manager wurde hinzugefügt.\n",
+  "Manager_removed" : "Der Manager wurde gelöscht.",
+  "Name_of_agent" : "Name des Agents",
+  "Navigation_History_20_last_pages" : "Navigationsverlauf (die letzten 20 Seiten)",
+  "New_Department" : "Neue Abteilung",
+  "Num_Agents" : "# Agents",
+  "Opened" : "Geöffnet",
+  "Order" : "Auftrag",
+  "Please_fill_a_name" : "Bitte geben Sie einen Namen ein.",
+  "Please_fill_a_username" : "Bitte geben Sie einen Benutzernamen ein.",
+  "Please_select_enabled_yes_or_no" : "Bitte wählen Sie eine Option für \"aktiviert\".",
+  "Saved" : "Gespeichert",
+  "Selected_agents" : "Ausgewählte Agenten",
+  "Send_a_message" : "Eine Nachricht schicken",
+  "Show_preregistration_form" : "Vorregistrierungsformular zeigen",
+  "Theme" : "Theme",
+  "There_are_no_agents_added_to_this_department_yet" : "Es wurden bisher keine Agenten zu dieser Abteilung hinzugefügt.",
+  "Time_in_seconds" : "Zeit in Sekunden",
+  "Title_bar_color" : "Farbe der Titelleiste",
+  "To_install_RocketChat_Livechat_in_your_website_copy_paste_this_code_above_the_last_body_tag_on_your_site" : "Um den Rocket.Chat-LiveChat auf Ihrer Webseite zu installieren, kopieren und fügen Sie den Code über den letzten <strong>&lt;/body&gt;</strong>-Tag Ihrer Seite ein.",
+  "Trigger_removed" : "Auslöser entfernt",
+  "Triggers" : "Auslöser",
+  "User_management" : "Benutzerverwaltung",
+  "Username_not_found" : "Der Benutzername konnte nicht gefunden werden.",
+  "Visitor_page_URL" : "URL der Besucherseite",
+  "Visitor_time_on_site" : "Besucherzeit auf der Seite"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/el.i18n.json b/packages/rocketchat-livechat/i18n/el.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..53f32128d5635f649de4dabf01ab5f239e3c6a0e 100644
--- a/packages/rocketchat-livechat/i18n/el.i18n.json
+++ b/packages/rocketchat-livechat/i18n/el.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Livechat_enabled" : "Livechat ενεργοποιημένη"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/en.i18n.json b/packages/rocketchat-livechat/i18n/en.i18n.json
index a6db675dc4f139b15ae2d59d3d35e1355d3c41a1..58602f022d7fd485d15484f974d61b4ddada3d9c 100644
--- a/packages/rocketchat-livechat/i18n/en.i18n.json
+++ b/packages/rocketchat-livechat/i18n/en.i18n.json
@@ -4,33 +4,55 @@
   "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",
   "Departments" : "Departments",
   "Description" : "Description",
   "Edit_Department" : "Edit Department",
+  "Empty_title" : "Empty title",
   "Enable" : "Enable",
   "Enabled" : "Enabled",
+  "Enter_a_regex" : "Enter a regex",
   "Enter_a_username" : "Enter a username",
   "Live_sessions" : "Live sessions",
   "Livechat_agents" : "Livechat agents",
+  "Livechat_Dashboard" : "Livechat Dashboard",
   "Livechat_enabled" : "Livechat enabled",
   "Livechat_Manager" : "Livechat Manager",
   "Livechat_managers" : "Livechat managers",
   "Livechat_title" : "Livechat Title",
   "Livechat_title_color" : "Livechat Title Background Color",
+  "Livechat_Users" : "Livechat Users",
   "Manager_added" : "Manager added",
   "Manager_removed" : "Manager removed",
+  "Name_of_agent" : "Name of agent",
+  "Navigation_History_20_last_pages" : "Navigation History (20 last pages)",
   "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",
+  "Show_preregistration_form" : "Show pre-registration form",
   "Theme" : "Theme",
   "There_are_no_agents_added_to_this_department_yet" : "There are no agents added to this department yet.",
+  "Time_in_seconds" : "Time in seconds",
+  "Title_bar_color" : "Title bar color",
+  "To_install_RocketChat_Livechat_in_your_website_copy_paste_this_code_above_the_last_body_tag_on_your_site" : "To install Rocket.Chat Livechat in your website, copy &amp; paste this code above the last <strong>&lt;/body&gt;</strong> tag on your site.",
+  "Trigger_removed" : "Trigger removed",
+  "Triggers" : "Triggers",
   "User_management" : "User Management",
-  "Username_not_found" : "Username not found"
+  "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/i18n/es.i18n.json b/packages/rocketchat-livechat/i18n/es.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..b777b5b19e9af7733e166bfd8aa325ae4fea3f2a 100644
--- a/packages/rocketchat-livechat/i18n/es.i18n.json
+++ b/packages/rocketchat-livechat/i18n/es.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Livechat_enabled" : "Livechat habilitado"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/fa.i18n.json b/packages/rocketchat-livechat/i18n/fa.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..f69ec3552e0a1fc8ca2be1a4ded9405fe8f36cb8 100644
--- a/packages/rocketchat-livechat/i18n/fa.i18n.json
+++ b/packages/rocketchat-livechat/i18n/fa.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Livechat_enabled" : "livechat در فعال"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/fi.i18n.json b/packages/rocketchat-livechat/i18n/fi.i18n.json
index c3913e2b43c34656dad0c713ef29aacbfd73aeaf..deac2b104c7a52dc4c2b5a7940879440fe9e207a 100644
--- a/packages/rocketchat-livechat/i18n/fi.i18n.json
+++ b/packages/rocketchat-livechat/i18n/fi.i18n.json
@@ -4,32 +4,55 @@
   "Add_manager" : "Lisää manageri",
   "Agent_added" : "Agentti lisätty",
   "Agent_removed" : "Agentti poistettu",
+  "Available_agents" : "Vapaat agentit",
   "Back" : "Takaisin",
-  "Dashboard" : "Kojelauta",
-  "Department_not_found" : "Osasto ei löytynyt",
+  "Closed" : "Suljettu",
+  "Copy_to_clipboard" : "Kopioi leikepöydälle",
+  "Count" : "Lukumäärä",
+  "Dashboard" : "Ohjauspaneeli",
+  "Department_not_found" : "Osastoa ei löytynyt",
   "Department_removed" : "Osasto poistettu",
   "Departments" : "Osastot",
   "Description" : "Kuvaus",
   "Edit_Department" : "Muokkaa osastoa",
+  "Empty_title" : "Tyhjä otsikko",
   "Enable" : "Ota käyttöön",
   "Enabled" : "Käytössä",
+  "Enter_a_regex" : "Syötä säännöllinen lause (regex)",
   "Enter_a_username" : "Syötä käyttäjätunnus",
   "Live_sessions" : "Live-istunnot",
   "Livechat_agents" : "Livechat agentit",
+  "Livechat_Dashboard" : "Livechat ohjauspaneeli",
+  "Livechat_enabled" : "LiveChat käytössä",
   "Livechat_Manager" : "Livechat manageri",
   "Livechat_managers" : "Livechat managerit",
   "Livechat_title" : "Livechat otsikko",
   "Livechat_title_color" : "Livechat otsikon taustaväri",
+  "Livechat_Users" : "Livechat käyttäjät",
   "Manager_added" : "Manageri lisätty",
   "Manager_removed" : "Manageri poistettu",
+  "Name_of_agent" : "Agentin nimi",
+  "Navigation_History_20_last_pages" : "Navigointihistoria (viimeiset 20 sivua)",
   "New_Department" : "Uusi osasto",
   "Num_Agents" : "# Agenttia",
+  "Opened" : "Avattu",
+  "Order" : "Järjestys",
   "Please_fill_a_name" : "Täytä nimi",
   "Please_fill_a_username" : "Täytä käyttäjätunnus",
   "Please_select_enabled_yes_or_no" : "Valitse vaihtoehto Käytössä",
   "Saved" : "Tallennettu",
-  "Theme" : "Teema",
+  "Selected_agents" : "Valitut agentit",
+  "Send_a_message" : "Lähetä viesti",
+  "Show_preregistration_form" : "Näytä esirekisteröintilomake",
+  "Theme" : "Ulkoasu",
   "There_are_no_agents_added_to_this_department_yet" : "Yhtään agenttia ei ole vielä lisätty tähän osastoon.",
-  "User_management" : "Käyttäjien hallinta",
-  "Username_not_found" : "Käyttäjätunnusta ei löydy"
+  "Time_in_seconds" : "Aika sekunneissa",
+  "Title_bar_color" : "Otsikkorivin väri",
+  "To_install_RocketChat_Livechat_in_your_website_copy_paste_this_code_above_the_last_body_tag_on_your_site" : "Asentaaksesi Rocket.Chat Livechatin sivustollesi, kopioi ja liitä seuraava sivusi <strong>&lt;/body&gt;</strong> osion yläpuolelle.",
+  "Trigger_removed" : "Laukaisija poistettu",
+  "Triggers" : "Laukaisijat",
+  "User_management" : "Käyttäjähallinta",
+  "Username_not_found" : "Käyttäjätunnusta ei löydy",
+  "Visitor_page_URL" : "Vierailijan sivun URL",
+  "Visitor_time_on_site" : "Vierailijan aika sivustolla"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/fr.i18n.json b/packages/rocketchat-livechat/i18n/fr.i18n.json
index 27798a2d83489847a49ce6d497078374b780013a..5a5f097e8ba8bd1a1397cd2d5c49514f6e96a0c0 100644
--- a/packages/rocketchat-livechat/i18n/fr.i18n.json
+++ b/packages/rocketchat-livechat/i18n/fr.i18n.json
@@ -1,4 +1,25 @@
 {
-  "Livechat_title" : "Titre du chat en direct",
-  "Livechat_title_color" : "Couleur de fond du titre du chat en direct"
+  "Add" : "Ajouter",
+  "Available_agents" : "Agents disponibles",
+  "Closed" : "Fermé",
+  "Copy_to_clipboard" : "Copier dans le presse-papier",
+  "Count" : "Nombre",
+  "Enter_a_regex" : "Entrez une expression rationnelle",
+  "Livechat_Dashboard" : "Dashboard du chat",
+  "Livechat_enabled" : "Chat en direct activé",
+  "Livechat_title" : "Titre du tchat en direct",
+  "Livechat_title_color" : "Couleur de fond du titre du tchat en direct",
+  "Livechat_Users" : "Utilisateurs du chat",
+  "Name_of_agent" : "Nom de l'assistant de chat",
+  "Opened" : "Ouvert",
+  "Order" : "Ordre",
+  "Selected_agents" : "Agents sélectionnés",
+  "Send_a_message" : "Envoyez un message",
+  "Show_preregistration_form" : "Afficher le formulaire de pré-inscription",
+  "Time_in_seconds" : "Temps en secondes",
+  "Title_bar_color" : "Couleur de la barre de titre",
+  "Trigger_removed" : "Déclencheur retiré",
+  "Triggers" : "Déclencheurs",
+  "Visitor_page_URL" : "Page d'accueil visiteur (URL)",
+  "Visitor_time_on_site" : "Temps des visiteurs sur le site"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/he.i18n.json b/packages/rocketchat-livechat/i18n/he.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..3efd17b9562c66f30c3764fdd72578ea88af811a 100644
--- a/packages/rocketchat-livechat/i18n/he.i18n.json
+++ b/packages/rocketchat-livechat/i18n/he.i18n.json
@@ -1 +1,25 @@
-{ }
\ No newline at end of file
+{
+  "Add" : "הוספה",
+  "Add_agent" : "הוספת סוכן",
+  "Add_manager" : "הוספת מנהל",
+  "Agent_added" : "נוסף סוכן",
+  "Agent_removed" : "הוסר סוכן",
+  "Back" : "חזרה",
+  "Copy_to_clipboard" : "העתקה ללוח הגזירים",
+  "Department_not_found" : "המחלקה לא נמצאה",
+  "Description" : "תיאור",
+  "Empty_title" : "כותרת ריקה",
+  "Enter_a_regex" : "נא להזין ביטוי רגולרי",
+  "Enter_a_username" : "נא להזין שם משתמש",
+  "Livechat_enabled" : "Livechat enabled",
+  "Manager_added" : "נוסף מנהל",
+  "Manager_removed" : "הוסר מנהל",
+  "Name_of_agent" : "שם הסוכן",
+  "Please_fill_a_name" : "נא למלא שם",
+  "Please_fill_a_username" : "נא למלא שם משתמש",
+  "Saved" : "נשמר",
+  "Send_a_message" : "שליחת הודעה",
+  "Time_in_seconds" : "זמן בשניות",
+  "User_management" : "ניהול משתמשים",
+  "Username_not_found" : "שם המשתמש לא נמצא"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/hr.i18n.json b/packages/rocketchat-livechat/i18n/hr.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..99a14df1af08c9afbf3686d2bd910ef685abcb25 100644
--- a/packages/rocketchat-livechat/i18n/hr.i18n.json
+++ b/packages/rocketchat-livechat/i18n/hr.i18n.json
@@ -1 +1,16 @@
-{ }
\ No newline at end of file
+{
+  "Add" : "Dodaj",
+  "Back" : "Natrag",
+  "Closed" : "Zatvoreno",
+  "Copy_to_clipboard" : "Kopiraj u međuspremnik",
+  "Description" : "Opis",
+  "Enabled" : "Omogućeno",
+  "Enter_a_username" : "Unesite korisničko ime",
+  "Livechat_enabled" : "LiveChat omogućeno",
+  "Please_fill_a_name" : "Molimo ispunite ime",
+  "Saved" : "Spremljeno",
+  "Send_a_message" : "Pošalji Poruku",
+  "Time_in_seconds" : "Vrijeme u sekundama",
+  "Trigger_removed" : "Okidač uklonjen",
+  "Triggers" : "Okidači"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/hu.i18n.json b/packages/rocketchat-livechat/i18n/hu.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..049e289a6b8c02d66a30eb5c977211ebb0a31560 100644
--- a/packages/rocketchat-livechat/i18n/hu.i18n.json
+++ b/packages/rocketchat-livechat/i18n/hu.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Livechat_enabled" : "LiveChat engedélyezve"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/it.i18n.json b/packages/rocketchat-livechat/i18n/it.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..af31f8b349913faca2c8e6f35b8c36c7677e7dcb 100644
--- a/packages/rocketchat-livechat/i18n/it.i18n.json
+++ b/packages/rocketchat-livechat/i18n/it.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Livechat_enabled" : "Livechat abilitato"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/ko.i18n.json b/packages/rocketchat-livechat/i18n/ko.i18n.json
index 6a58a7a6ee1968166b84658a2fc044f5343bc085..27f11f7b38525f1de2c2284dae5a8d04fc8c4f7e 100644
--- a/packages/rocketchat-livechat/i18n/ko.i18n.json
+++ b/packages/rocketchat-livechat/i18n/ko.i18n.json
@@ -1,4 +1,8 @@
 {
+  "Add" : "추가",
+  "Description" : "설명",
+  "Enter_a_username" : "사용자 이름 입력",
   "Livechat_title" : "Livechat 제목",
-  "Livechat_title_color" : "Livechat 제목 배경색"
+  "Livechat_title_color" : "Livechat 제목 배경색",
+  "Saved" : "저장됨"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/lo.i18n.json b/packages/rocketchat-livechat/i18n/lo.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..a9acf8c81be41e8fedc7879cd1fe4a4fc03514ac 100644
--- a/packages/rocketchat-livechat/i18n/lo.i18n.json
+++ b/packages/rocketchat-livechat/i18n/lo.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Livechat_enabled" : "Livechat ເປີດ​ໃຫ້​ໃຊ້​ງານ"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/nl.i18n.json b/packages/rocketchat-livechat/i18n/nl.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..f185cf0c6c352fef230c4620c12a289adec4dd2a 100644
--- a/packages/rocketchat-livechat/i18n/nl.i18n.json
+++ b/packages/rocketchat-livechat/i18n/nl.i18n.json
@@ -1 +1,47 @@
-{ }
\ No newline at end of file
+{
+  "Add" : "Toevoegen",
+  "Add_manager" : "Manager toevoegen",
+  "Back" : "Terug",
+  "Closed" : "Gesloten",
+  "Copy_to_clipboard" : "Kopieer naar klembord",
+  "Count" : "Aantal",
+  "Dashboard" : "Dashboard",
+  "Department_not_found" : "Afdeling niet gevonden",
+  "Department_removed" : "Afdeling verwijderd",
+  "Departments" : "Afdelingen",
+  "Description" : "Beschrijving",
+  "Edit_Department" : "Afdeling bewerken",
+  "Enable" : "Inschakelen",
+  "Enabled" : "Ingeschakeld",
+  "Enter_a_regex" : "Voer een reguliere expressie in",
+  "Enter_a_username" : "Voer een gebruikersnaam in",
+  "Live_sessions" : "Live sessies",
+  "Livechat_Dashboard" : "Livechat Dashboard",
+  "Livechat_enabled" : "Livechat beschikbaar",
+  "Livechat_Manager" : "Livechat Manager",
+  "Livechat_managers" : "Livechat managers",
+  "Livechat_title" : "Livechat Titel",
+  "Livechat_title_color" : "Livechat Titel Achtergrond Kleur",
+  "Livechat_Users" : "Livechat Gebruikers",
+  "Manager_added" : "Manager toegevoegd",
+  "Manager_removed" : "Manager verwijderd",
+  "Name_of_agent" : "Naam agent",
+  "New_Department" : "Nieuwe afdeling",
+  "Opened" : "Geopend",
+  "Please_fill_a_name" : "Vul een naam in",
+  "Please_fill_a_username" : "Vul een gebruikersnaam in",
+  "Please_select_enabled_yes_or_no" : "Selecteer een optie voor Ingeschakeld",
+  "Saved" : "Opgeslagen",
+  "Send_a_message" : "Stuur een bericht",
+  "Theme" : "Thema",
+  "There_are_no_agents_added_to_this_department_yet" : "Er zijn nog geen agenten aan deze afdeling toegevoegd.",
+  "Time_in_seconds" : "Tijd in seconden",
+  "Title_bar_color" : "Titelbalk kleur",
+  "To_install_RocketChat_Livechat_in_your_website_copy_paste_this_code_above_the_last_body_tag_on_your_site" : "Om Rocket.Chat Livechat te installeren op uw website, kopiëert u de volgende code boven de laatste <strong>&lt;/body&gt;</strong> html tag op uw web pagina's.",
+  "Trigger_removed" : "Trigger verwijderd",
+  "Triggers" : "Triggers",
+  "User_management" : "Gebruikersbeheer",
+  "Username_not_found" : "Gebruikersnaam niet gevonden",
+  "Visitor_page_URL" : "Bezoeker URL",
+  "Visitor_time_on_site" : "Bezoeker tijd aanwezig op de site"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/pl.i18n.json b/packages/rocketchat-livechat/i18n/pl.i18n.json
index 743f3732748d19d6e6cb7694ccacef5014791ce4..9a1059cc5e70eaf3e9c52edd15dd3af7c99ddfe9 100644
--- a/packages/rocketchat-livechat/i18n/pl.i18n.json
+++ b/packages/rocketchat-livechat/i18n/pl.i18n.json
@@ -1,4 +1,13 @@
 {
+  "Add" : "Dodaj",
+  "Description" : "Opis",
+  "Enable" : "WÅ‚Ä…cz",
+  "Enabled" : "WÅ‚Ä…czone",
+  "Enter_a_username" : "Nazwa użytkownika",
   "Livechat_title" : "Tytuł Livechatu",
-  "Livechat_title_color" : "Kolor tła nagłówka Livechat"
+  "Livechat_title_color" : "Kolor tła nagłówka Livechat",
+  "Please_fill_a_username" : "Proszę wypełnić nazwę użytkownika",
+  "Saved" : "Zapisano",
+  "Send_a_message" : "Wyślij wiadomość",
+  "Theme" : "Motyw"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/ro.i18n.json b/packages/rocketchat-livechat/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..83a8cd26ccacf284836f802b7c3c5c1908ca162f
--- /dev/null
+++ b/packages/rocketchat-livechat/i18n/ro.i18n.json
@@ -0,0 +1,58 @@
+{
+  "Add" : "Adăugă",
+  "Add_agent" : "Adaugă agent",
+  "Add_manager" : "Adauga manager",
+  "Agent_added" : "Agent adăugat",
+  "Agent_removed" : "Agent eliminat",
+  "Available_agents" : "Agenți disponibili",
+  "Back" : "ÃŽnapoi",
+  "Closed" : "ÃŽnchis",
+  "Copy_to_clipboard" : "Copiați în clipboard",
+  "Count" : "Număr",
+  "Dashboard" : "Tablou de comandă",
+  "Department_not_found" : "Departamentul nu a fost găsit",
+  "Department_removed" : "Departament eliminat",
+  "Departments" : "Departamente",
+  "Description" : "Descriere",
+  "Edit_Department" : "Editează departament",
+  "Empty_title" : "Titlu gol",
+  "Enable" : "Activează",
+  "Enabled" : "Activat",
+  "Enter_a_regex" : "Introduceți un regex",
+  "Enter_a_username" : "Introduceți un nume de utilizator",
+  "Live_sessions" : "Sesiuni live",
+  "Livechat_agents" : "Agenți Livechat",
+  "Livechat_Dashboard" : "Tabloul de bord Livechat",
+  "Livechat_enabled" : "Livechat activat",
+  "Livechat_Manager" : "Manager Livechat",
+  "Livechat_managers" : "Manageri Livechat",
+  "Livechat_title" : "Titlu Livechat",
+  "Livechat_title_color" : "Culoare de fundal titlu Livechat ",
+  "Livechat_Users" : "Utilizatorii Livechat",
+  "Manager_added" : "Manager adăugat",
+  "Manager_removed" : "Manager eliminat",
+  "Name_of_agent" : "Numele agentului",
+  "Navigation_History_20_last_pages" : "Istoria de navigare (ultimele 20 de pagini)",
+  "New_Department" : "Departament nou",
+  "Num_Agents" : "# Agenți",
+  "Opened" : "Deschis",
+  "Order" : "Sortare",
+  "Please_fill_a_name" : "Vă rugăm să completați un nume",
+  "Please_fill_a_username" : "Vă rugăm să completați un nume de utilizator",
+  "Please_select_enabled_yes_or_no" : "Vă rugăm să selectați o opțiune pentru Enabled",
+  "Saved" : "Salvat",
+  "Selected_agents" : "Agenți selectați",
+  "Send_a_message" : "Trimite un mesaj",
+  "Show_preregistration_form" : "Arată formularul de pre-înregistrare",
+  "Theme" : "Temă",
+  "There_are_no_agents_added_to_this_department_yet" : "Încă există agenți adăugați la acest departament.",
+  "Time_in_seconds" : "Timpul în secunde",
+  "Title_bar_color" : "Culoare bară de titlu",
+  "To_install_RocketChat_Livechat_in_your_website_copy_paste_this_code_above_the_last_body_tag_on_your_site" : "Pentru a instala Rocket.Chat Livechat în site-ul dvs., copiați & lipiți acest cod chiar înaintea ultimului tag <strong>&lt;/body&gt;</strong> din pagină.",
+  "Trigger_removed" : "Declanșator eliminat",
+  "Triggers" : "Declanșatori",
+  "User_management" : "Managementul utilizatorilor",
+  "Username_not_found" : "Numele de utilizator nu a fost găsit",
+  "Visitor_page_URL" : "Pagina  URL a vizitatorului",
+  "Visitor_time_on_site" : "Timpul vizitatorului pe site"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/ru.i18n.json b/packages/rocketchat-livechat/i18n/ru.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..ea345d96bfec4d43cec8dc71f039b245e23e0410 100644
--- a/packages/rocketchat-livechat/i18n/ru.i18n.json
+++ b/packages/rocketchat-livechat/i18n/ru.i18n.json
@@ -1 +1,4 @@
-{ }
\ No newline at end of file
+{
+  "Livechat_enabled" : "Включен Livechat",
+  "Livechat_title" : "Название чата"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/sq.i18n.json b/packages/rocketchat-livechat/i18n/sq.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..4252cafab36f4526d3616adbdf4ef32ed5cdf3ab 100644
--- a/packages/rocketchat-livechat/i18n/sq.i18n.json
+++ b/packages/rocketchat-livechat/i18n/sq.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Livechat_enabled" : "LiveChat aktivizuar"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/sr.i18n.json b/packages/rocketchat-livechat/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-livechat/i18n/sr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/sv.i18n.json b/packages/rocketchat-livechat/i18n/sv.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..2a24e6702158107a8808cae2b4d66696b647880d 100644
--- a/packages/rocketchat-livechat/i18n/sv.i18n.json
+++ b/packages/rocketchat-livechat/i18n/sv.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Livechat_enabled" : "Livechat aktiverat"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/tr.i18n.json b/packages/rocketchat-livechat/i18n/tr.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..008b9ca305b2e61b3e8961357d7d6a53b1dcdc87 100644
--- a/packages/rocketchat-livechat/i18n/tr.i18n.json
+++ b/packages/rocketchat-livechat/i18n/tr.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Livechat_enabled" : "Canlı etkin"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/ug.i18n.json b/packages/rocketchat-livechat/i18n/ug.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..7e724987836b6afe91b6686a6830452987e682c6 100644
--- a/packages/rocketchat-livechat/i18n/ug.i18n.json
+++ b/packages/rocketchat-livechat/i18n/ug.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Livechat_enabled" : "Livechat Enabled"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/uk.i18n.json b/packages/rocketchat-livechat/i18n/uk.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..13a9ea9ca687d64fdf0128c1f5bd6d8cedcac80d 100644
--- a/packages/rocketchat-livechat/i18n/uk.i18n.json
+++ b/packages/rocketchat-livechat/i18n/uk.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Livechat_enabled" : "Включений Livechat"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/i18n/zh.i18n.json b/packages/rocketchat-livechat/i18n/zh.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..c83357d2db2f5bfc5cc6dc35a4e9624d0aaabaec 100644
--- a/packages/rocketchat-livechat/i18n/zh.i18n.json
+++ b/packages/rocketchat-livechat/i18n/zh.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Livechat_enabled" : "在线咨询启用"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-livechat/livechat.js b/packages/rocketchat-livechat/livechat.js
index b33e6eb59094273cca8dd1dd573c9d9d55cab518..1e854bd8f64b2b74a243b988a789f12446ea985f 100644
--- a/packages/rocketchat-livechat/livechat.js
+++ b/packages/rocketchat-livechat/livechat.js
@@ -2,7 +2,7 @@ WebApp = Package.webapp.WebApp;
 Autoupdate = Package.autoupdate.Autoupdate;
 
 WebApp.connectHandlers.use('/livechat/', (req, res, next) => {
-	res.setHeader('content-type', 'html');
+	res.setHeader('content-type', 'text/html; charset=utf-8');
 
 	head = Assets.getText('public/head.html');
 
diff --git a/packages/rocketchat-livechat/package.js b/packages/rocketchat-livechat/package.js
index dc6d77ad8f184f666f5a2d4b3d4a0fb1b37aedeb..a43697f53401f55a0dc46d584a5511487b86c5b8 100644
--- a/packages/rocketchat-livechat/package.js
+++ b/packages/rocketchat-livechat/package.js
@@ -20,14 +20,15 @@ Package.onUse(function(api) {
 
 	api.use(['webapp', 'autoupdate'], 'server');
 	api.use('ecmascript');
-	api.use('alanning:roles@1.2.12');
 	api.use('rocketchat:lib');
+	api.use('rocketchat:authorization');
+	api.use('rocketchat:ui');
 	api.use('kadira:flow-router', 'client');
 	api.use('templating', 'client');
 	api.use('mongo');
+	api.use('less@2.5.1');
 
 	api.addFiles('livechat.js', 'server');
-	api.addFiles('server/methods.js', 'server');
 	api.addFiles('server/startup.js', 'server');
 	api.addFiles('permissions.js', 'server');
 
@@ -36,39 +37,80 @@ Package.onUse(function(api) {
 	api.addFiles('client/ui.js', 'client');
 	api.addFiles('client/route.js', 'client');
 
+	// add stylesheets to theme compiler
+	api.addAssets('client/stylesheets/livechat.less', 'server');
+	api.addFiles('client/stylesheets/load.js', 'server');
+
+	// 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/LivechatPageVisited.js', 'client');
+	api.addFiles('client/collections/LivechatTrigger.js', 'client');
+
 	// client views
-	api.addFiles('client/views/app/livechatManager.html', 'client');
-	api.addFiles('client/views/app/livechatManager.js', 'client');
-	api.addFiles('client/views/app/livechatDepartments.html', 'client');
-	api.addFiles('client/views/app/livechatDepartments.js', 'client');
+	api.addFiles('client/views/app/livechatAppearance.html', 'client');
+	api.addFiles('client/views/app/livechatAppearance.js', 'client');
+	api.addFiles('client/views/app/livechatDashboard.html', 'client');
 	api.addFiles('client/views/app/livechatDepartmentForm.html', 'client');
 	api.addFiles('client/views/app/livechatDepartmentForm.js', 'client');
+	api.addFiles('client/views/app/livechatDepartments.html', 'client');
+	api.addFiles('client/views/app/livechatDepartments.js', 'client');
+	api.addFiles('client/views/app/livechatInstallation.html', 'client');
+	api.addFiles('client/views/app/livechatInstallation.js', 'client');
+	api.addFiles('client/views/app/livechatTriggers.html', 'client');
+	api.addFiles('client/views/app/livechatTriggers.js', 'client');
+	api.addFiles('client/views/app/livechatUsers.html', 'client');
+	api.addFiles('client/views/app/livechatUsers.js', 'client');
+
+	api.addFiles('client/views/app/tabbar/visitorInfo.html', 'client');
+	api.addFiles('client/views/app/tabbar/visitorInfo.js', 'client');
+
 	api.addFiles('client/views/sideNav/livechat.html', 'client');
 	api.addFiles('client/views/sideNav/livechat.js', 'client');
 	api.addFiles('client/views/sideNav/livechatFlex.html', 'client');
 	api.addFiles('client/views/sideNav/livechatFlex.js', 'client');
 
+	api.addFiles('client/views/app/triggers/livechatTriggerAction.html', 'client');
+	api.addFiles('client/views/app/triggers/livechatTriggerAction.js', 'client');
+	api.addFiles('client/views/app/triggers/livechatTriggerCondition.html', 'client');
+	api.addFiles('client/views/app/triggers/livechatTriggerCondition.js', 'client');
+
 	// methods
 	api.addFiles('server/methods/addAgent.js', 'server');
 	api.addFiles('server/methods/addManager.js', 'server');
+	api.addFiles('server/methods/pageVisited.js', 'server');
+	api.addFiles('server/methods/registerGuest.js', 'server');
+	api.addFiles('server/methods/removeAgent.js', 'server');
+	api.addFiles('server/methods/removeDepartment.js', 'server');
+	api.addFiles('server/methods/removeManager.js', 'server');
+	api.addFiles('server/methods/removeTrigger.js', 'server');
 	api.addFiles('server/methods/saveDepartment.js', 'server');
 	api.addFiles('server/methods/saveSurveyFeedback.js', 'server');
+	api.addFiles('server/methods/saveTrigger.js', 'server');
 	api.addFiles('server/methods/searchAgent.js', 'server');
-	api.addFiles('server/methods/removeAgent.js', 'server');
-	api.addFiles('server/methods/removeManager.js', 'server');
-	api.addFiles('server/methods/removeDepartment.js', 'server');
+	api.addFiles('server/methods/sendMessageLivechat.js', 'server');
+
 	// models
 	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/LivechatPageVisited.js', 'server');
+	api.addFiles('server/models/LivechatTrigger.js', 'server');
 
-	// collections
-	api.addFiles('client/lib/LivechatDepartment.js', 'client');
+	// server lib
+	api.addFiles('server/lib/getNextAgent.js', 'server');
 
 	// publications
+	api.addFiles('server/publications/availableDepartments.js', 'server');
+	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');
+	api.addFiles('server/publications/livechatManagers.js', 'server');
+	api.addFiles('server/publications/trigger.js', 'server');
+	api.addFiles('server/publications/visitorInfo.js', 'server');
+	api.addFiles('server/publications/visitorPageVisited.js', 'server');
 	api.addFiles('server/publications/visitorRoom.js', 'server');
 
 	// livechat app
@@ -86,7 +128,6 @@ Package.onUse(function(api) {
 			return 'i18n/' + filename;
 		}
 	}));
-	api.use('tap:i18n', ['client', 'server']);
-	// api.imply('tap:i18n');
-	api.addFiles(tapi18nFiles, ['client', 'server']);
+	api.use('tap:i18n');
+	api.addFiles(tapi18nFiles);
 });
diff --git a/packages/rocketchat-livechat/permissions.js b/packages/rocketchat-livechat/permissions.js
index 98bf89e1be0e0da2e924b66c6aae3d53d92bb8c1..ad5a5a3c8432579935162307bdfcc041e42a4ae3 100644
--- a/packages/rocketchat-livechat/permissions.js
+++ b/packages/rocketchat-livechat/permissions.js
@@ -1,10 +1,13 @@
 Meteor.startup(() => {
-	var roles = _.pluck(Roles.getAllRoles().fetch(), 'name');
+	var roles = _.pluck(RocketChat.models.Roles.find().fetch(), 'name');
 	if (roles.indexOf('livechat-agent') === -1) {
-		Roles.createRole('livechat-agent');
+		RocketChat.models.Roles.createOrUpdate('livechat-agent');
 	}
 	if (roles.indexOf('livechat-manager') === -1) {
-		Roles.createRole('livechat-manager');
+		RocketChat.models.Roles.createOrUpdate('livechat-manager');
+	}
+	if (roles.indexOf('livechat-guest') === -1) {
+		RocketChat.models.Roles.createOrUpdate('livechat-guest');
 	}
 	if (RocketChat.models && RocketChat.models.Permissions) {
 		RocketChat.models.Permissions.createOrUpdate('view-l-room', ['livechat-agent', 'livechat-manager', 'admin']);
diff --git a/packages/rocketchat-livechat/server/lib/getNextAgent.js b/packages/rocketchat-livechat/server/lib/getNextAgent.js
new file mode 100644
index 0000000000000000000000000000000000000000..63a484b49b912bbd5643b74ca8b21e86dc163f41
--- /dev/null
+++ b/packages/rocketchat-livechat/server/lib/getNextAgent.js
@@ -0,0 +1,9 @@
+this.getNextAgent = function(department) {
+	var agentFilter = {};
+
+	if (department) {
+		return RocketChat.models.LivechatDepartmentAgents.getNextAgentForDepartment(department);
+	} else {
+		return RocketChat.models.Users.getNextAgent();
+	}
+};
diff --git a/packages/rocketchat-livechat/server/methods.js b/packages/rocketchat-livechat/server/methods.js
deleted file mode 100644
index 8b7b0dd70e7233cd4e00b02c3254154dcc2eae3e..0000000000000000000000000000000000000000
--- a/packages/rocketchat-livechat/server/methods.js
+++ /dev/null
@@ -1,109 +0,0 @@
-Meteor.methods({
-	registerGuest: function(token, name, email) {
-		console.log('registerGuest ->'.green, token);
-		var pass, qt, user, userData, userExists, userId, inc = 0;
-		check(token, String);
-		user = Meteor.users.findOne({
-			"profile.token": token
-		}, {
-			fields: {
-				_id: 1
-			}
-		});
-		if (user != null) {
-			throw new Meteor.Error('token-already-exists', 'Token already exists');
-		}
-		pass = Meteor.uuid();
-		while (true) {
-			qt = Meteor.users.find({
-				'profile.guest': true
-			}).count() + 1;
-			user = 'guest-' + (qt + inc++);
-			userExists = Meteor.users.findOne({
-				'username': user
-			}, {
-				fields: {
-					_id: 1
-				}
-			});
-			console.log('userExists ->',userExists);
-			if (!userExists) {
-				break;
-			}
-		}
-		userData = {
-			username: user,
-			password: pass
-		};
-		userId = Accounts.createUser(userData);
-
-		updateUser = {
-			name: name || user,
-			"profile.guest": true,
-			"profile.token": token
-		}
-
-		if (email && email.trim() !== "") {
-			updateUser.emails = [{ "address": email }];
-		}
-
-		Meteor.users.update(userId, {
-			$set: updateUser
-		});
-		return {
-			user: user,
-			pass: pass
-		};
-	},
-	sendMessageLivechat: function(message) {
-		var guest, operator, room;
-		console.log('sendMessageLivechat ->', arguments);
-		check(message.rid, String);
-		check(message.token, String);
-		guest = Meteor.users.findOne(Meteor.userId(), {
-			fields: {
-				username: 1
-			}
-		});
-		room = RocketChat.models.Rooms.findOneById(message.rid);
-		if (room == null) {
-			operator = Meteor.users.findOne({
-				operator: true,
-				status: 'online'
-			});
-			if (!operator) {
-				throw new Meteor.Error('no-operators', 'Sorry, no online operators');
-			}
-			RocketChat.models.Rooms.insert({
-				_id: message.rid,
-				name: guest.username,
-				msgs: 1,
-				lm: new Date(),
-				usernames: [operator.username, guest.username],
-				t: 'l',
-				ts: new Date(),
-				v: {
-					token: message.token
-				}
-			});
-			RocketChat.models.Subscriptions.insert({
-				rid: message.rid,
-				name: guest.username,
-				alert: true,
-				open: true,
-				unread: 1,
-				answered: false,
-				u: {
-					_id: operator._id,
-					username: operator.username
-				},
-				t: 'l'
-			});
-		}
-		room = Meteor.call('canAccessRoom', message.rid, guest._id);
-		if (!room) {
-			throw new Meteor.Error('cannot-acess-room');
-		}
-		return RocketChat.sendMessage(guest, message, room);
-	}
-});
diff --git a/packages/rocketchat-livechat/server/methods/addAgent.js b/packages/rocketchat-livechat/server/methods/addAgent.js
index e94c5bee12fe8ec0021478cb47305874f4f00cca..e236bc2c41a2f70ef0436a0239434ce0822d8b48 100644
--- a/packages/rocketchat-livechat/server/methods/addAgent.js
+++ b/packages/rocketchat-livechat/server/methods/addAgent.js
@@ -8,15 +8,13 @@ Meteor.methods({
 			throw new Meteor.Error('invalid-arguments');
 		}
 
-		console.log('[methods] livechat:addAgent -> '.green, 'arguments:', arguments);
-
 		var user = RocketChat.models.Users.findOneByUsername(username, { fields: { _id: 1 } });
 
 		if (!user) {
 			throw new Meteor.Error('user-not-found', 'Username_not_found');
 		}
 
-		if (RocketChat.authz.addUsersToRoles(user._id, 'livechat-agent')) {
+		if (RocketChat.authz.addUserRoles(user._id, 'livechat-agent')) {
 			return RocketChat.models.Users.setOperator(user._id, true);
 		}
 
diff --git a/packages/rocketchat-livechat/server/methods/addManager.js b/packages/rocketchat-livechat/server/methods/addManager.js
index 6519a406bf3849ac5f96dbab1094b1fb86803807..9f4af3713a4647d0d0d2feb43197c93d89f6e753 100644
--- a/packages/rocketchat-livechat/server/methods/addManager.js
+++ b/packages/rocketchat-livechat/server/methods/addManager.js
@@ -8,14 +8,12 @@ Meteor.methods({
 			throw new Meteor.Error('invalid-arguments');
 		}
 
-		console.log('[methods] livechat:addManager -> '.green, 'arguments:', arguments);
-
 		var user = RocketChat.models.Users.findOneByUsername(username, { fields: { _id: 1 } });
 
 		if (!user) {
 			throw new Meteor.Error('user-not-found', 'Username_not_found');
 		}
 
-		return RocketChat.authz.addUsersToRoles(user._id, 'livechat-manager');
+		return RocketChat.authz.addUserRoles(user._id, 'livechat-manager');
 	}
 });
diff --git a/packages/rocketchat-livechat/server/methods/pageVisited.js b/packages/rocketchat-livechat/server/methods/pageVisited.js
new file mode 100644
index 0000000000000000000000000000000000000000..97729d57f5579f2960ddcf5fe6b1ff60286ebae8
--- /dev/null
+++ b/packages/rocketchat-livechat/server/methods/pageVisited.js
@@ -0,0 +1,5 @@
+Meteor.methods({
+	'livechat:pageVisited' (token, pageInfo) {
+		return RocketChat.models.LivechatPageVisitied.saveByToken(token, pageInfo);
+	}
+});
diff --git a/packages/rocketchat-livechat/server/methods/registerGuest.js b/packages/rocketchat-livechat/server/methods/registerGuest.js
new file mode 100644
index 0000000000000000000000000000000000000000..ee258a8a345615cfb7a051363218ede2f99c0de9
--- /dev/null
+++ b/packages/rocketchat-livechat/server/methods/registerGuest.js
@@ -0,0 +1,81 @@
+Meteor.methods({
+	'livechat:registerGuest': function({ token, name, email, department } = {}) {
+		var pass, qt, user, userData, userExists, userId, inc = 0;
+
+		check(token, String);
+
+		user = Meteor.users.findOne({
+			"profile.token": token
+		}, {
+			fields: {
+				_id: 1
+			}
+		});
+
+		if (user != null) {
+			throw new Meteor.Error('token-already-exists', 'Token already exists');
+		}
+
+		while (true) {
+			qt = Meteor.users.find({
+				'profile.guest': true
+			}).count() + 1;
+
+			user = 'guest-' + (qt + inc++);
+
+			userExists = Meteor.users.findOne({
+				'username': user
+			}, {
+				fields: {
+					_id: 1
+				}
+			});
+
+			if (!userExists) {
+				break;
+			}
+		}
+		userData = {
+			username: user,
+			globalRoles: ['livechat-guest'],
+			department: department
+		};
+
+		userData.userAgent = this.connection.httpHeaders['user-agent'];
+		userData.ip = this.connection.httpHeaders['x-real-ip'] || this.connection.clientAddress;
+		userData.host = this.connection.httpHeaders['host'];
+
+		userId = Accounts.insertUserDoc({}, userData);
+
+		updateUser = {
+			name: name || user,
+			"profile.guest": true,
+			"profile.token": token
+		}
+
+		if (email && email.trim() !== "") {
+			updateUser.emails = [{ "address": email }];
+		}
+
+		var stampedToken = Accounts._generateStampedLoginToken();
+		var hashStampedToken = Accounts._hashStampedToken(stampedToken);
+
+		updateUser.services = {
+			resume: {
+				loginTokens: [ hashStampedToken ]
+			}
+		};
+
+		Meteor.users.update(userId, {
+			$set: updateUser
+		});
+
+		// update visited page history to not expire
+		RocketChat.models.LivechatPageVisitied.keepHistoryForToken(token);
+
+		return {
+			userId: userId,
+			token: stampedToken.token
+		};
+	}
+});
diff --git a/packages/rocketchat-livechat/server/methods/removeAgent.js b/packages/rocketchat-livechat/server/methods/removeAgent.js
index bc6dd5bd4c98c85845d49c5e39f534a2cdddf4ae..adbf4ae47739efcb49602609dade49d4e62c6fc0 100644
--- a/packages/rocketchat-livechat/server/methods/removeAgent.js
+++ b/packages/rocketchat-livechat/server/methods/removeAgent.js
@@ -8,15 +8,13 @@ Meteor.methods({
 			throw new Meteor.Error('invalid-arguments');
 		}
 
-		console.log('[methods] livechat:removeAgent -> '.green, 'arguments:', arguments);
-
 		var user = RocketChat.models.Users.findOneByUsername(username, { fields: { _id: 1 } });
 
 		if (!user) {
 			throw new Meteor.Error('user-not-found', 'Username_not_found');
 		}
 
-		if (RocketChat.authz.removeUsersFromRoles(user._id, 'livechat-agent')) {
+		if (RocketChat.authz.removeUserFromRoles(user._id, 'livechat-agent')) {
 			return RocketChat.models.Users.setOperator(user._id, false);
 		}
 
diff --git a/packages/rocketchat-livechat/server/methods/removeDepartment.js b/packages/rocketchat-livechat/server/methods/removeDepartment.js
index 8fb2b620dff4ecd50d97a3563c94cab37d49ca4a..5419602088c7c05b784e4847e992667476fb5457 100644
--- a/packages/rocketchat-livechat/server/methods/removeDepartment.js
+++ b/packages/rocketchat-livechat/server/methods/removeDepartment.js
@@ -6,8 +6,6 @@ Meteor.methods({
 
 		check(_id, String);
 
-		console.log('[methods] livechat:removeDepartment -> '.green, 'arguments:', arguments);
-
 		var department = RocketChat.models.LivechatDepartment.findOneById(_id, { fields: { _id: 1 } });
 
 		if (!department) {
diff --git a/packages/rocketchat-livechat/server/methods/removeManager.js b/packages/rocketchat-livechat/server/methods/removeManager.js
index 38e462d3f0e03ef8e8dd89ebd7dc9de82c60d5f9..31ad6cd337b8f01524536b12474e7ce0440cec7f 100644
--- a/packages/rocketchat-livechat/server/methods/removeManager.js
+++ b/packages/rocketchat-livechat/server/methods/removeManager.js
@@ -6,14 +6,12 @@ Meteor.methods({
 
 		check(username, String);
 
-		console.log('[methods] livechat:removeManager -> '.green, 'arguments:', arguments);
-
 		var user = RocketChat.models.Users.findOneByUsername(username, { fields: { _id: 1 } });
 
 		if (!user) {
 			throw new Meteor.Error('user-not-found', 'Username_not_found');
 		}
 
-		return RocketChat.authz.removeUsersFromRoles(user._id, 'livechat-manager');
+		return RocketChat.authz.removeUserFromRoles(user._id, 'livechat-manager');
 	}
 });
diff --git a/packages/rocketchat-livechat/server/methods/removeTrigger.js b/packages/rocketchat-livechat/server/methods/removeTrigger.js
new file mode 100644
index 0000000000000000000000000000000000000000..a2249b1459416ef3507aae902e71efcc741b9bc1
--- /dev/null
+++ b/packages/rocketchat-livechat/server/methods/removeTrigger.js
@@ -0,0 +1,9 @@
+Meteor.methods({
+	'livechat:removeTrigger' (trigger) {
+		if (!Meteor.userId() || !RocketChat.authz.hasPermission(Meteor.userId(), 'view-livechat-manager')) {
+			throw new Meteor.Error("not-authorized");
+		}
+
+		return RocketChat.models.LivechatTrigger.removeAll();
+	}
+});
diff --git a/packages/rocketchat-livechat/server/methods/saveDepartment.js b/packages/rocketchat-livechat/server/methods/saveDepartment.js
index 526b32134f28956e33201cf1fa2b156bf480a70a..2f626c395720add0dfd8b8e533a5363c955b21ea 100644
--- a/packages/rocketchat-livechat/server/methods/saveDepartment.js
+++ b/packages/rocketchat-livechat/server/methods/saveDepartment.js
@@ -1,7 +1,5 @@
 Meteor.methods({
-	'livechat:saveDepartment' (_id, departmentData) {
-		console.log('[methods] livechat:saveDepartment -> '.green, 'arguments:', arguments);
-
+	'livechat:saveDepartment' (_id, departmentData, departmentAgents) {
 		if (!Meteor.userId() || !RocketChat.authz.hasPermission(Meteor.userId(), 'view-livechat-manager')) {
 			throw new Meteor.Error("not-authorized");
 		}
@@ -19,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/methods/saveSurveyFeedback.js b/packages/rocketchat-livechat/server/methods/saveSurveyFeedback.js
index 44d8fd05767bd36b4423d22f0c00aca2b1c3d4f3..5d7421876166203de801a0cde6424f42b84182f0 100644
--- a/packages/rocketchat-livechat/server/methods/saveSurveyFeedback.js
+++ b/packages/rocketchat-livechat/server/methods/saveSurveyFeedback.js
@@ -4,8 +4,6 @@ Meteor.methods({
 		check(visitorRoom, String);
 		check(formData, [Match.ObjectIncluding({ name: String, value: String })]);
 
-		console.log('[methods] livechat:saveSurveyFeedback -> '.green, 'arguments:', arguments);
-
 		visitor = RocketChat.models.Users.getVisitorByToken(visitorToken);
 		room = RocketChat.models.Rooms.findOneById(visitorRoom);
 
diff --git a/packages/rocketchat-livechat/server/methods/saveTrigger.js b/packages/rocketchat-livechat/server/methods/saveTrigger.js
new file mode 100644
index 0000000000000000000000000000000000000000..4077fc46d5b3568e7b587486c86fa13be81de169
--- /dev/null
+++ b/packages/rocketchat-livechat/server/methods/saveTrigger.js
@@ -0,0 +1,9 @@
+Meteor.methods({
+	'livechat:saveTrigger' (trigger) {
+		if (!Meteor.userId() || !RocketChat.authz.hasPermission(Meteor.userId(), 'view-livechat-manager')) {
+			throw new Meteor.Error("not-authorized");
+		}
+
+		return RocketChat.models.LivechatTrigger.save(trigger);
+	}
+});
diff --git a/packages/rocketchat-livechat/server/methods/searchAgent.js b/packages/rocketchat-livechat/server/methods/searchAgent.js
index 72b9d3d9bb0830deb8aced3d1c9ac47375803448..80bf6159baea80d08eb2387596bb47aa3b37ff49 100644
--- a/packages/rocketchat-livechat/server/methods/searchAgent.js
+++ b/packages/rocketchat-livechat/server/methods/searchAgent.js
@@ -8,8 +8,6 @@ Meteor.methods({
 			throw new Meteor.Error('invalid-arguments');
 		}
 
-		console.log('[methods] livechat:searchAgent -> '.green, 'arguments:', arguments);
-
 		var user = RocketChat.models.Users.findOneByUsername(username, { fields: { _id: 1, username: 1 } });
 
 		if (!user) {
diff --git a/packages/rocketchat-livechat/server/methods/sendMessageLivechat.js b/packages/rocketchat-livechat/server/methods/sendMessageLivechat.js
new file mode 100644
index 0000000000000000000000000000000000000000..2f9983768dd2ce32d07e8d784a2db6ef02efcc74
--- /dev/null
+++ b/packages/rocketchat-livechat/server/methods/sendMessageLivechat.js
@@ -0,0 +1,62 @@
+Meteor.methods({
+	sendMessageLivechat: function(message) {
+		var guest, agent, room;
+
+		check(message.rid, String);
+		check(message.token, String);
+
+		guest = Meteor.users.findOne(Meteor.userId(), {
+			fields: {
+				username: 1,
+				department: 1
+			}
+		});
+
+		room = RocketChat.models.Rooms.findOneById(message.rid);
+		if (room == null) {
+
+			// if no department selected verify if there is only one active and use it
+			if (!guest.department) {
+				var departments = RocketChat.models.LivechatDepartment.findEnabledWithAgents();
+				if (departments.count() === 1) {
+					guest.department = departments.fetch()[0]._id;
+				}
+			}
+
+			agent = getNextAgent(guest.department);
+			if (!agent) {
+				throw new Meteor.Error('no-agent-online', 'Sorry, no online agents');
+			}
+			RocketChat.models.Rooms.insert({
+				_id: message.rid,
+				name: guest.username,
+				msgs: 1,
+				lm: new Date(),
+				usernames: [agent.username, guest.username],
+				t: 'l',
+				ts: new Date(),
+				v: {
+					token: message.token
+				}
+			});
+			RocketChat.models.Subscriptions.insert({
+				rid: message.rid,
+				name: guest.username,
+				alert: true,
+				open: true,
+				unread: 1,
+				answered: false,
+				u: {
+					_id: agent.agentId,
+					username: agent.username
+				},
+				t: 'l'
+			});
+		}
+		room = Meteor.call('canAccessRoom', message.rid, guest._id);
+		if (!room) {
+			throw new Meteor.Error('cannot-acess-room');
+		}
+		return RocketChat.sendMessage(guest, message, room);
+	}
+});
diff --git a/packages/rocketchat-livechat/server/models/LivechatDepartment.js b/packages/rocketchat-livechat/server/models/LivechatDepartment.js
index 41141b8d68ef4943ed85dfe3b10ec25c8058b010..5cbd7f35bbd3e412e161350875bc55620d35a458 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
+		};
 
-		if (!_.isEmpty(agents)) {
-			for (agent of agents) {
-				record.agents.push({ _id: agent._id, username: agent.username });
-			}
+		_.extend(record, extraData);
+
+		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 });
 	}
 
@@ -44,6 +63,14 @@ class LivechatDepartment extends RocketChat.models._Base {
 		query = { _id: _id };
 		return this.remove(query);
 	}
+
+	findEnabledWithAgents() {
+		var query = {
+			numAgents: { $gt: 0 },
+			enabled: true
+		};
+		return this.find(query);
+	}
 }
 
 RocketChat.models.LivechatDepartment = new LivechatDepartment();
diff --git a/packages/rocketchat-livechat/server/models/LivechatDepartmentAgents.js b/packages/rocketchat-livechat/server/models/LivechatDepartmentAgents.js
new file mode 100644
index 0000000000000000000000000000000000000000..551a00e1aebdac4ddd9059015656d6072c4c6d2e
--- /dev/null
+++ b/packages/rocketchat-livechat/server/models/LivechatDepartmentAgents.js
@@ -0,0 +1,79 @@
+/**
+ * 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);
+
+		var agent = findAndModify(query, sort, update);
+		if (agent) {
+			return {
+				agentId: agent.agentId,
+				username: agent.username
+			}
+		} else {
+			return null;
+		}
+	}
+}
+
+RocketChat.models.LivechatDepartmentAgents = new LivechatDepartmentAgents();
diff --git a/packages/rocketchat-livechat/server/models/LivechatPageVisited.js b/packages/rocketchat-livechat/server/models/LivechatPageVisited.js
new file mode 100644
index 0000000000000000000000000000000000000000..36ecd8272657ccd6a7a693ff6a7e2fafd8d9b2d5
--- /dev/null
+++ b/packages/rocketchat-livechat/server/models/LivechatPageVisited.js
@@ -0,0 +1,48 @@
+/**
+ * Livechat Page Visited model
+ */
+class LivechatPageVisitied extends RocketChat.models._Base {
+	constructor() {
+		super();
+		this._initModel('livechat_page_visited');
+
+		this.tryEnsureIndex({ 'token': 1 });
+		this.tryEnsureIndex({ 'ts': 1 });
+
+		// keep history for 1 month if the visitor does not register
+		this.tryEnsureIndex({ 'expireAt': 1 }, { sparse: 1, expireAfterSeconds: 0 });
+	}
+
+	saveByToken(token, pageInfo) {
+		// keep history of unregistered visitors for 1 month
+		var keepHistoryMiliseconds = 2592000000;
+
+		return this.insert({
+			token: token,
+			page: pageInfo,
+			ts: new Date(),
+			expireAt: new Date().getTime() + keepHistoryMiliseconds
+		});
+	}
+
+	findByToken(token) {
+		return this.find({ token: token }, { sort : { ts: -1 }, limit: 20 });
+	}
+
+	keepHistoryForToken(token) {
+		return this.update({
+			token: token,
+			expireAt: {
+				$exists: true
+			}
+		}, {
+			$unset: {
+				expireAt: 1
+			}
+		}, {
+			multi: true
+		});
+	}
+}
+
+RocketChat.models.LivechatPageVisitied = new LivechatPageVisitied();
diff --git a/packages/rocketchat-livechat/server/models/LivechatTrigger.js b/packages/rocketchat-livechat/server/models/LivechatTrigger.js
new file mode 100644
index 0000000000000000000000000000000000000000..4873a44f1c25bc45fc762a94523fa4a5f0c19e21
--- /dev/null
+++ b/packages/rocketchat-livechat/server/models/LivechatTrigger.js
@@ -0,0 +1,26 @@
+/**
+ * Livechat Trigger model
+ */
+class LivechatTrigger extends RocketChat.models._Base {
+	constructor() {
+		super();
+		this._initModel('livechat_trigger');
+	}
+
+	// FIND
+	save(data) {
+		trigger = this.findOne();
+
+		if (trigger) {
+			return this.update({ _id: trigger._id }, { $set: data });
+		} else {
+			return this.insert(data);
+		}
+	}
+
+	removeAll() {
+		this.remove({});
+	}
+}
+
+RocketChat.models.LivechatTrigger = new LivechatTrigger();
diff --git a/packages/rocketchat-livechat/server/models/Users.js b/packages/rocketchat-livechat/server/models/Users.js
index 1481564cf1d669ea0e33a147781265730bb09cf2..7a9d212867d8f84a6cd1861d63d5770642eb4f80 100644
--- a/packages/rocketchat-livechat/server/models/Users.js
+++ b/packages/rocketchat-livechat/server/models/Users.js
@@ -13,6 +13,70 @@ RocketChat.models.Users.setOperator = function(_id, operator) {
 	return this.update(_id, update);
 };
 
+/**
+ * Gets all online agents
+ * @return
+ */
+RocketChat.models.Users.findOnlineAgents = function() {
+	var query = {
+		status: 'online',
+		roles: 'livechat-agent'
+	};
+
+	return this.find(query);
+};
+
+/**
+ * Find online users from a list
+ * @param {array} userList - array of usernames
+ * @return
+ */
+RocketChat.models.Users.findOnlineUserFromList = function(userList) {
+	var query = {
+		status: 'online',
+		username: {
+			$in: [].concat(userList)
+		}
+	};
+
+	return this.find(query);
+};
+
+/**
+ * Get next user agent in order
+ * @return {object} User from db
+ */
+RocketChat.models.Users.getNextAgent = function() {
+	var query = {
+		status: 'online',
+		roles: 'livechat-agent'
+	};
+
+	var collectionObj = this.model.rawCollection();
+	var findAndModify = Meteor.wrapAsync(collectionObj.findAndModify, collectionObj);
+
+	var sort = {
+		livechatCount: 1,
+		username: 1
+	};
+
+	var update = {
+		$inc: {
+			livechatCount: 1
+		}
+	};
+
+	var user = findAndModify(query, sort, update);
+	if (user) {
+		return {
+			agentId: user._id,
+			username: user.username
+		}
+	} else {
+		return null;
+	}
+};
+
 /**
  * Gets visitor by token
  * @param {string} token - Visitor token
@@ -25,3 +89,16 @@ RocketChat.models.Users.getVisitorByToken = function(token, options) {
 
 	return this.findOne(query, options);
 };
+
+/**
+ * Gets visitor by token
+ * @param {string} token - Visitor token
+ */
+RocketChat.models.Users.findVisitorByToken = function(token) {
+	var query = {
+		"profile.guest": true,
+		"profile.token": token
+	};
+
+	return this.find(query);
+};
diff --git a/packages/rocketchat-livechat/server/publications/availableDepartments.js b/packages/rocketchat-livechat/server/publications/availableDepartments.js
new file mode 100644
index 0000000000000000000000000000000000000000..6ab277d73cecdcf214c4a1dea6644738762bf3f4
--- /dev/null
+++ b/packages/rocketchat-livechat/server/publications/availableDepartments.js
@@ -0,0 +1,3 @@
+Meteor.publish('livechat:availableDepartments', function() {
+	return RocketChat.models.LivechatDepartment.findEnabledWithAgents();
+});
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-livechat/server/publications/livechatAgents.js b/packages/rocketchat-livechat/server/publications/livechatAgents.js
index b68dba1459c21601c902d9f2a67998d022093bce..77be3cde55ec2e3918215add18d8890df41cdaec 100644
--- a/packages/rocketchat-livechat/server/publications/livechatAgents.js
+++ b/packages/rocketchat-livechat/server/publications/livechatAgents.js
@@ -7,8 +7,6 @@ Meteor.publish('livechat:agents', function() {
 		throw new Meteor.Error('not-authorized');
 	}
 
-	console.log('[publish] livechat:agents -> '.green, 'arguments:', arguments);
-
 	var self = this;
 
 	var handle = RocketChat.authz.getUsersInRole('livechat-agent').observeChanges({
diff --git a/packages/rocketchat-livechat/server/publications/livechatDepartments.js b/packages/rocketchat-livechat/server/publications/livechatDepartments.js
index ab35d5dd88c2c7b3acac8d85f893284cabcdece1..a7566722d58e09066b483cdc30b57ffbb5270c00 100644
--- a/packages/rocketchat-livechat/server/publications/livechatDepartments.js
+++ b/packages/rocketchat-livechat/server/publications/livechatDepartments.js
@@ -7,8 +7,6 @@ Meteor.publish('livechat:departments', function(_id) {
 		throw new Meteor.Error('not-authorized');
 	}
 
-	console.log('[publish] livechat:departments -> '.green, 'arguments:', arguments);
-
 	if (_id !== undefined) {
 		return RocketChat.models.LivechatDepartment.findByDepartmentId(_id);
 	} else {
diff --git a/packages/rocketchat-livechat/server/publications/livechatManagers.js b/packages/rocketchat-livechat/server/publications/livechatManagers.js
index 639c1305c6df0970858dd410777ce2928fbd006f..042a2acb50ac579000ce5c73b1d655ac3a1119c5 100644
--- a/packages/rocketchat-livechat/server/publications/livechatManagers.js
+++ b/packages/rocketchat-livechat/server/publications/livechatManagers.js
@@ -7,8 +7,6 @@ Meteor.publish('livechat:managers', function() {
 		throw new Meteor.Error('not-authorized');
 	}
 
-	console.log('[publish] livechat:managers -> '.green, 'arguments:', arguments);
-
 	var self = this;
 
 	var handle = RocketChat.authz.getUsersInRole('livechat-manager').observeChanges({
diff --git a/packages/rocketchat-livechat/server/publications/trigger.js b/packages/rocketchat-livechat/server/publications/trigger.js
new file mode 100644
index 0000000000000000000000000000000000000000..61d7d6831f41d0013ff2e1efc106b24d907eb86a
--- /dev/null
+++ b/packages/rocketchat-livechat/server/publications/trigger.js
@@ -0,0 +1,3 @@
+Meteor.publish('livechat:trigger', function() {
+	return RocketChat.models.LivechatTrigger.find();
+});
diff --git a/packages/rocketchat-livechat/server/publications/visitorInfo.js b/packages/rocketchat-livechat/server/publications/visitorInfo.js
new file mode 100644
index 0000000000000000000000000000000000000000..a4fe7a17761329df24b160391e37b35ea6b3040b
--- /dev/null
+++ b/packages/rocketchat-livechat/server/publications/visitorInfo.js
@@ -0,0 +1,17 @@
+Meteor.publish('livechat:visitorInfo', function(roomId) {
+	if (!this.userId) {
+		throw new Meteor.Error('not-authorized');
+	}
+
+	if (!RocketChat.authz.hasPermission(this.userId, 'view-l-room')) {
+		throw new Meteor.Error('not-authorized');
+	}
+
+	var room = RocketChat.models.Rooms.findOneById(roomId);
+
+	if (room && room.v && room.v.token) {
+		return RocketChat.models.Users.findVisitorByToken(room.v.token);
+	} else {
+		return this.ready();
+	}
+});
diff --git a/packages/rocketchat-livechat/server/publications/visitorPageVisited.js b/packages/rocketchat-livechat/server/publications/visitorPageVisited.js
new file mode 100644
index 0000000000000000000000000000000000000000..72aa424c6737f85caad54111e766d84b27bf4b2b
--- /dev/null
+++ b/packages/rocketchat-livechat/server/publications/visitorPageVisited.js
@@ -0,0 +1,17 @@
+Meteor.publish('livechat:visitorPageVisited', function(roomId) {
+	if (!this.userId) {
+		throw new Meteor.Error('not-authorized');
+	}
+
+	if (!RocketChat.authz.hasPermission(this.userId, 'view-l-room')) {
+		throw new Meteor.Error('not-authorized');
+	}
+
+	var room = RocketChat.models.Rooms.findOneById(roomId);
+
+	if (room && room.v && room.v.token) {
+		return RocketChat.models.LivechatPageVisitied.findByToken(room.v.token);
+	} else {
+		return this.ready();
+	}
+});
diff --git a/packages/rocketchat-livechat/server/publications/visitorRoom.js b/packages/rocketchat-livechat/server/publications/visitorRoom.js
index 52b4fab49f6c249cae1742b92a9d4e7a8f440bc0..cb0570f7a7e8a736605bd737100a00c0395b475f 100644
--- a/packages/rocketchat-livechat/server/publications/visitorRoom.js
+++ b/packages/rocketchat-livechat/server/publications/visitorRoom.js
@@ -1,6 +1,4 @@
 Meteor.publish('livechat:visitorRoom', function(visitorToken) {
-	console.log('[publish] livechat:visitorRoom -> '.green, 'arguments:', arguments);
-
 	return RocketChat.models.Rooms.findByVisitorToken(visitorToken, {
 		fields: {
 			name: 1,
diff --git a/packages/rocketchat-mailer/client/router.coffee b/packages/rocketchat-mailer/client/router.coffee
index 5205c1f2a693efdc02359bcd2a9b30f2e8b3793d..4260c1719c3fa4e9b0bb5578d64f975b362f48af 100644
--- a/packages/rocketchat-mailer/client/router.coffee
+++ b/packages/rocketchat-mailer/client/router.coffee
@@ -1,11 +1,7 @@
-tabReset = ->
-	RocketChat.TabBar.reset()
-
 FlowRouter.route '/mailer',
 	name: 'mailer'
-	triggersEnter: [tabReset]
-	triggersExit: [tabReset]
 	action: ->
+		RocketChat.TabBar.showGroup 'mailer'
 		BlazeLayout.render 'main', {center: 'mailer'}
 
 FlowRouter.route '/mailer/unsubscribe/:_id/:createdAt',
diff --git a/packages/rocketchat-mailer/i18n/ar.i18n.json b/packages/rocketchat-mailer/i18n/ar.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..d93ff17e2eae5acb0ebf7285199c339714e20f56 100644
--- a/packages/rocketchat-mailer/i18n/ar.i18n.json
+++ b/packages/rocketchat-mailer/i18n/ar.i18n.json
@@ -1 +1,11 @@
-{ }
\ No newline at end of file
+{
+  "Dry_run" : "تنفيذ تجريبي",
+  "Dry_run_description" : "سيتم إرسال رسالة بريدية واحدة إلى نفس العنوان الموجود في خانة \"من\". تأكد من كون ذلك العنوان البريدي فعال",
+  "Email_from" : "من",
+  "Email_subject" : "الموضوع",
+  "Send_email" : "إرسال البريد الإلكتروني",
+  "The_emails_are_being_sent" : "يتم إرسال رسائل البريد الإلكتروني.",
+  "You_are_not_authorized_to_view_this_page" : "لا تملك الصلاحية لمشاهدة هذه الصفحة.",
+  "You_have_successfully_unsubscribed" : "لقد تم إلغاء اشتراكك بنجاح من القائمة البريدية لدينا.",
+  "You_must_provide_the_unsubscribe_link" : "يجب توفير رابط [إلغاء الاشتراك]."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-mailer/i18n/de.i18n.json b/packages/rocketchat-mailer/i18n/de.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..d70199a35e43e80bfea6e20a7e86f73a689c1955 100644
--- a/packages/rocketchat-mailer/i18n/de.i18n.json
+++ b/packages/rocketchat-mailer/i18n/de.i18n.json
@@ -1 +1,19 @@
-{ }
\ No newline at end of file
+{
+  "From_email_warning" : "<b>Warnung</b>: Der <b>Absender</b> ist Gegenstand deiner Mail-Server-Einstellungen.",
+  "From_email_is_required" : "Ein Absender muss angegeben werden.",
+  "Dry_run" : "Probelauf",
+  "Dry_run_description" : "Es wird nur eine E-Mail an den Empfänger gesendet. Die E-Mail muss einem gültigen Benutzer gehören.",
+  "Email_from" : "Absender",
+  "Email_subject" : "Betreff",
+  "Email_body" : "Nachricht",
+  "Mailer" : "Mailer",
+  "Mailer_body_tags" : "Sie <b>müssen</b> [unsubscribe] verwenden, um einen Link zum Abmelden aus dem Verteiler zur Verfügung zu stellen. <br /> Sie können [name] für den Vor- und Nachnamen, [fname] für den Vornamen oder [lname] für den Nachnamen des Benutzers verwenden. <br />Ebenfalls können Sie [email] verwenden, um die E-Mail-Adresse des Benutzers anzugeben.",
+  "Query" : "Abfrage",
+  "Query_description" : "Zusätzliche Bedingungen für die Bestimmung, an welche Benutzer die E-Mails gesendet werden sollen. Ausgetragene Benutzer werden automatisch aus der Abfrage entfernt. Es muss ein gültiger JSON sein. Beispiel: \"{\"createdAt\":{\"$gt\":{\"$date\": \"2015-01-01T00:00:00.000Z\"}}}\"",
+  "Send_email" : "E-Mail senden",
+  "The_emails_are_being_sent" : "Die E-Mails werden gesendet.",
+  "You_are_not_authorized_to_view_this_page" : "Sie sind nicht berechtigt, diese Seite zu sehen.",
+  "You_have_successfully_unsubscribed" : "Sie haben sich erfolgreich von unserem Verteiler abgemeldet.",
+  "You_informed_an_invalid_FROM_address" : "Sie haben eine ungültige E-Mail-Adresse als Empfänger angegeben.",
+  "You_must_provide_the_unsubscribe_link" : "Sie müssen einen Link zum Abmelden vom Verteiler angeben."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-mailer/i18n/fr.i18n.json b/packages/rocketchat-mailer/i18n/fr.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..71edb96248f9bba001000e80e9e03d7f5d0fb219 100644
--- a/packages/rocketchat-mailer/i18n/fr.i18n.json
+++ b/packages/rocketchat-mailer/i18n/fr.i18n.json
@@ -1 +1,14 @@
-{ }
\ No newline at end of file
+{
+  "From_email_warning" : "<b>Attention</b> : le champ <b>De</b> est forcé par vos paramètres de serveur mail",
+  "From_email_is_required" : "Le champ \"De\" est requis.",
+  "Email_from" : "De",
+  "Email_subject" : "Sujet",
+  "Email_body" : "Corps du mail",
+  "Mailer_body_tags" : "Vous <b>devez</b> utiliser [unsubscribe] pour le lien de désinscription.<br />Vous pouvez utiliser [name], [fname], [lname] pour le nom complet de l'utilisateur, le prénom et le nom de famille respectivement.<br />Vous pouvez utiliser [email] pour le mail de l'utilisateur.",
+  "Send_email" : "Envoyer le courriel",
+  "The_emails_are_being_sent" : "Les courriels sont en train d'être envoyés.",
+  "You_are_not_authorized_to_view_this_page" : "Vous n'avez pas l'autorisation de voir cette page.",
+  "You_have_successfully_unsubscribed" : "Vous êtes désabonné avec succès de notre Liste de diffusion.",
+  "You_informed_an_invalid_FROM_address" : "Vous avez entré un expéditeur invalide (champ FROM).",
+  "You_must_provide_the_unsubscribe_link" : "Vous devez fournir le lien de désinscription [unsubscribe]."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-mailer/i18n/hr.i18n.json b/packages/rocketchat-mailer/i18n/hr.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..6408a16fb887470db3fee31a2e2224f83cbfcf2e 100644
--- a/packages/rocketchat-mailer/i18n/hr.i18n.json
+++ b/packages/rocketchat-mailer/i18n/hr.i18n.json
@@ -1 +1,6 @@
-{ }
\ No newline at end of file
+{
+  "Email_from" : "Od",
+  "Send_email" : "Pošalji e-mail",
+  "The_emails_are_being_sent" : "E-mailovi su poslani.",
+  "You_are_not_authorized_to_view_this_page" : "Nemate dopuštenje za pregled ove stranice."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-mailer/i18n/km.i18n.json b/packages/rocketchat-mailer/i18n/km.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..a99a6eb6c8c273a8d2057197e6a4e038e6ce6a6f 100644
--- a/packages/rocketchat-mailer/i18n/km.i18n.json
+++ b/packages/rocketchat-mailer/i18n/km.i18n.json
@@ -1 +1,11 @@
-{ }
\ No newline at end of file
+{
+  "From_email_is_required" : "From អ៊ីមែលគឺត្រូវបំពេញ",
+  "Email_from" : "ពី",
+  "Email_subject" : "ប្រធានបទ",
+  "Email_body" : "រាងកាយអ៊ីមែល",
+  "Send_email" : "ផ្ញើ​រ​អ៊ី​ម៉ែ​ល",
+  "The_emails_are_being_sent" : "នេះ​អ៊ីមែល​ត្រូវ​បាន​បញ្ជូន​។",
+  "You_are_not_authorized_to_view_this_page" : "អ្នក​មិន​ត្រូវ​បាន​អនុញ្ញាត​ឱ្យ​មើល​ទំព័រ​នេះ​។",
+  "You_have_successfully_unsubscribed" : "អ្នក​បាន unsubscribed ដោយ​ជោគជ័យ​ពី​បញ្ជី Mailling របស់​យើង​។",
+  "You_must_provide_the_unsubscribe_link" : "អ្នកត្រូវតែផ្ដល់តំណភ្ជាប់ [unsubscribe] ។"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-mailer/i18n/ko.i18n.json b/packages/rocketchat-mailer/i18n/ko.i18n.json
index 0b3dccd1255d7a416029a249cc733148d5f53d9e..ffc9e58b9aa7483860d392115df5bd6bf494f3d6 100644
--- a/packages/rocketchat-mailer/i18n/ko.i18n.json
+++ b/packages/rocketchat-mailer/i18n/ko.i18n.json
@@ -3,5 +3,7 @@
   "Email_subject" : "제목",
   "Email_body" : "이메일 본문",
   "Send_email" : "이메일 보내기",
-  "You_are_not_authorized_to_view_this_page" : "당신은 이 페이지를 볼 수 있는 권한이 없습니다."
+  "The_emails_are_being_sent" : "이메일을 전송 중입니다.",
+  "You_are_not_authorized_to_view_this_page" : "당신은 이 페이지를 볼 수 있는 권한이 없습니다.",
+  "You_have_successfully_unsubscribed" : "지금부터 당신은 메일링 리스트를 수신하지 않습니다."
 }
\ No newline at end of file
diff --git a/packages/rocketchat-mailer/i18n/nl.i18n.json b/packages/rocketchat-mailer/i18n/nl.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..3c6d8dec0b99c85c79296219872046884d6ad52e 100644
--- a/packages/rocketchat-mailer/i18n/nl.i18n.json
+++ b/packages/rocketchat-mailer/i18n/nl.i18n.json
@@ -1 +1,11 @@
-{ }
\ No newline at end of file
+{
+  "From_email_is_required" : "Afzender e-mailadres is verplicht",
+  "Dry_run_description" : "Zal slechts één e-mail sturen naar hetzelfde adres als in afzenderveld. De e-mail moet horen bij een geldige gebruiker.",
+  "Email_from" : "Afzender",
+  "Email_subject" : "Onderwerp",
+  "Email_body" : "E-mail tekst",
+  "Send_email" : "Verstuur e-mail",
+  "The_emails_are_being_sent" : "De e-mails worden verzonden.",
+  "You_are_not_authorized_to_view_this_page" : "U bent niet bevoegd om deze pagina te bekijken.",
+  "You_have_successfully_unsubscribed" : "U bent uitgeschreven van onze mailinglijst."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-mailer/i18n/pl.i18n.json b/packages/rocketchat-mailer/i18n/pl.i18n.json
index 292bea7592fb7b5349479bd1e7112a78681b196f..e44e595d29f1b7c8e9978619c9445648fcbd11d1 100644
--- a/packages/rocketchat-mailer/i18n/pl.i18n.json
+++ b/packages/rocketchat-mailer/i18n/pl.i18n.json
@@ -6,6 +6,7 @@
   "Email_body" : "Treść wiadomości",
   "Mailer" : "Wyślij email użytkownikom",
   "Mailer_body_tags" : "<b>Musisz</b> użyć znacznika [unsubscribe] aby zawrzeć w treści odnośnik do rezygnacji z subskrypcji.<br />Możesz użyć znaczników [name], [fname], [lname] by wstawić odpowiednio pełną nazwę użytkownika, jego imię, nazwisko.<br />\nMożesz użyć znacznika [email] by wstawić adres email użytkownika.",
+  "Query" : "Zapytanie",
   "Send_email" : "Wyślij wiadomość",
   "The_emails_are_being_sent" : "Wiadomości e-mail są wysyłane.",
   "You_are_not_authorized_to_view_this_page" : "Nie masz uprawnień, aby zobaczyć tę stronę.",
diff --git a/packages/rocketchat-mailer/i18n/ro.i18n.json b/packages/rocketchat-mailer/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..957380946206560f1bea7d650745bf8cfa81cdbe
--- /dev/null
+++ b/packages/rocketchat-mailer/i18n/ro.i18n.json
@@ -0,0 +1,19 @@
+{
+  "From_email_warning" : "b>Atenție</b>:Câmpul <b>De la</b> depinde de setările serverului dumneavoastră de email.",
+  "From_email_is_required" : "E nevoie de adresa de email \"De la\"",
+  "Dry_run" : "Dry run",
+  "Dry_run_description" : "Va trimite un singur e-mail, la adresa specificată în CĂTRE. E-mail-ul trebuie să aparțină unui utilizator valid.",
+  "Email_from" : "De la",
+  "Email_subject" : "Subiect",
+  "Email_body" : "Corp E-mail",
+  "Mailer" : "Mailer",
+  "Mailer_body_tags" : "<b>Trebuie</b> să folosiți [unsubscribe] pentru link-ul de unsuscribe.<br />Puteți utiliza [name], [fname], [lname] pentru numele întreg, prenume respectiv nume.<br />Puteți folosi [email] pentru e-mailul utilizatorului.",
+  "Query" : "Interogare",
+  "Query_description" : "Condiții suplimentare pentru a determina către ce utilizatori se trimite e-mail. Utilizatorii dezabonați sunt eliminați automat din interogare. Trebuie să fie un JSON valid. Exemplu: \"{\" createdAt \": {\" $ GT \": {\" $ data \":\" 2015-01-01T00: 00: 00.000Z \"}}}\"",
+  "Send_email" : "Trimite email",
+  "The_emails_are_being_sent" : "E-mail-urile sunt trimise.",
+  "You_are_not_authorized_to_view_this_page" : "Nu sunteți autorizat pentru a vizualiza această pagină.",
+  "You_have_successfully_unsubscribed" : "V-ați dezabonat cu succes din lista noastră de email.",
+  "You_informed_an_invalid_FROM_address" : "Ați utilizat o adresă DE LA invalidă.",
+  "You_must_provide_the_unsubscribe_link" : "Trebuie să furnizați link-ul de [unsubscribe]."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-mailer/i18n/ru.i18n.json b/packages/rocketchat-mailer/i18n/ru.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..980d68b0494d5b054981f8108cda65beaf4a6b24 100644
--- a/packages/rocketchat-mailer/i18n/ru.i18n.json
+++ b/packages/rocketchat-mailer/i18n/ru.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Dry_run_description" : "Мы отправим только один e-mail на адрес указанный в поле \"От\". E-mail адрес должен принадлежать действительному пользователю."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-mailer/i18n/sr.i18n.json b/packages/rocketchat-mailer/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mailer/i18n/sr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mailer/package.js b/packages/rocketchat-mailer/package.js
index 7dd1c4cd5a8fe12f0a6a54e3daf76fcf5e554c0f..ab47e1a98efa82f25c0f6a1415665143357f02f3 100644
--- a/packages/rocketchat-mailer/package.js
+++ b/packages/rocketchat-mailer/package.js
@@ -11,7 +11,7 @@ Package.onUse(function(api) {
 		'coffeescript',
 		'ddp-rate-limiter',
 		'kadira:flow-router',
-		'rocketchat:lib@0.0.1',
+		'rocketchat:lib',
 		'rocketchat:authorization@0.0.1'
 	]);
 
@@ -43,9 +43,8 @@ Package.onUse(function(api) {
 			return 'i18n/' + filename;
 		}
 	}));
-	api.use('tap:i18n@1.6.1', ['client', 'server']);
-	api.imply('tap:i18n');
-	api.addFiles(tapi18nFiles, ['client', 'server']);
+	api.use('tap:i18n');
+	api.addFiles(tapi18nFiles);
 
 	api.export('Mailer');
 });
diff --git a/packages/rocketchat-mailer/server/methods/sendMail.coffee b/packages/rocketchat-mailer/server/methods/sendMail.coffee
index a4b7fd4194b5ba030077e74bc8a577251485427f..d12e7b18dff7cce61a920f4fffabf9d9a5aeedd2 100644
--- a/packages/rocketchat-mailer/server/methods/sendMail.coffee
+++ b/packages/rocketchat-mailer/server/methods/sendMail.coffee
@@ -1,8 +1,6 @@
 Meteor.methods
 	'Mailer.sendMail': (from, subject, body, dryrun, query) ->
 
-		console.log '[method] Mailer.sendMail', from, subject, body, dryrun, query
-
 		return Mailer.sendMail from, subject, body, dryrun, query
 
 # Limit setting username once per minute
diff --git a/packages/rocketchat-markdown/markdown.coffee b/packages/rocketchat-markdown/markdown.coffee
index c578fec716055746fe5ff6193ed875c47bcf7e01..f33c817e52735bdbf0cac761c6efd0efd12cb860 100644
--- a/packages/rocketchat-markdown/markdown.coffee
+++ b/packages/rocketchat-markdown/markdown.coffee
@@ -13,6 +13,20 @@ class Markdown
 			else
 				return message
 
+		# Support `text`
+		if _.isString message
+			msg = msg.replace(/(^|&gt;|[ >_*~])\`([^`\r\n]+)\`([<_*~]|\B|\b|$)/gm, '$1<span class="copyonly">`</span><span><code class="inline">$2</code></span><span class="copyonly">`</span>$3')
+		else
+			message.tokens ?= []
+			msg = msg.replace /(^|&gt;|[ >_*~])\`([^`\r\n]+)\`([<_*~]|\B|\b|$)/gm, (match, p1, p2, p3, offset, text) ->
+				token = "$#{Random.id()}$"
+
+				message.tokens.push
+					token: token
+					text: "#{p1}<span class=\"copyonly\">`</span><span><code class=\"inline\">#{p2}</code></span><span class=\"copyonly\">`</span>#{p3}"
+
+				return token
+
 		# Support ![alt text](http://image url)
 		msg = msg.replace(/!\[([^\]]+)\]\((https?:\/\/[^\)]+)\)/gm, '<a href="$2" title="$1" class="swipebox" target="_blank"><div class="inline-image" style="background-image: url($2);"></div></a>')
 
@@ -35,9 +49,6 @@ class Markdown
 			# Support # Text for h4
 			msg = msg.replace(/^#### (([\w\d-_\/\*\.,\\] ?)+)/gm, '<h4>$1</h4>')
 
-		# Support `text`
-		msg = msg.replace(/(^|&gt;|[ >_*~])\`([^`\r\n]+)\`([<_*~]|\B|\b|$)/gm, '$1<span class="copyonly">`</span><code class="inline">$2</code><span class="copyonly">`</span>$3')
-
 		# Support *text* to make bold
 		msg = msg.replace(/(^|&gt;|[ >_~`])\*{1,2}([^\*\r\n]+)\*{1,2}([<_~`]|\B|\b|$)/gm, '$1<span class="copyonly">*</span><strong>$2</strong><span class="copyonly">*</span>$3')
 
diff --git a/packages/rocketchat-markdown/package.js b/packages/rocketchat-markdown/package.js
index aca6f0d8415c476256b110b0b8d6eadaf7f1a2ac..ef87d1cc43ca7cc8ac0dc3f28496292a220613e1 100644
--- a/packages/rocketchat-markdown/package.js
+++ b/packages/rocketchat-markdown/package.js
@@ -12,7 +12,7 @@ Package.onUse(function(api) {
 	api.use('underscore');
 	api.use('templating');
 	api.use('underscorestring:underscore.string');
-	api.use('rocketchat:lib@0.0.1');
+	api.use('rocketchat:lib');
 
 	api.addFiles('settings.coffee', 'server');
 	api.addFiles('markdown.coffee');
diff --git a/packages/rocketchat-me/package.js b/packages/rocketchat-me/package.js
index c23a5d916f9c0a5292eca31bcf4c7a7dea5913bf..a123d4e98edf8109527e6a1758c65fd43450ab66 100644
--- a/packages/rocketchat-me/package.js
+++ b/packages/rocketchat-me/package.js
@@ -10,7 +10,7 @@ Package.onUse(function(api) {
 
 	api.use([
 		'coffeescript',
-		'rocketchat:lib@0.0.1'
+		'rocketchat:lib'
 	]);
 
 	api.addFiles('me.coffee', ['server','client']);
diff --git a/packages/rocketchat-mentions-flextab/client/actionButton.coffee b/packages/rocketchat-mentions-flextab/client/actionButton.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..6d18189d7cad96342e7dcc2ac50eda254532c261
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/client/actionButton.coffee
@@ -0,0 +1,14 @@
+Meteor.startup ->
+	RocketChat.MessageAction.addButton
+		id: 'jump-to-message'
+		icon: 'icon-right-hand'
+		i18nLabel: 'Jump_to_message'
+		action: (event, instance) ->
+			message = @_arguments[1]
+			$('.message-dropdown:visible').hide()
+			RoomHistoryManager.getSurroundingMessages(message, 50)
+
+		validation: (message) ->
+			return message.mentionedList is true
+
+		order: 100
diff --git a/packages/rocketchat-mentions-flextab/client/lib/MentionedMessage.coffee b/packages/rocketchat-mentions-flextab/client/lib/MentionedMessage.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..26dc11807b8c297ccc9e93363caf2898e8edd4a8
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/client/lib/MentionedMessage.coffee
@@ -0,0 +1 @@
+@MentionedMessage = new Meteor.Collection 'rocketchat_mentioned_message'
diff --git a/packages/rocketchat-mentions-flextab/client/tabBar.coffee b/packages/rocketchat-mentions-flextab/client/tabBar.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..93da941b2ec168aca05d00ff748ac3c23a87b555
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/client/tabBar.coffee
@@ -0,0 +1,9 @@
+Meteor.startup ->
+	RocketChat.TabBar.addButton({
+		groups: ['channel', 'privategroup'],
+		id: 'mentions',
+		i18nTitle: 'Mentions',
+		icon: 'icon-at',
+		template: 'mentionsFlexTab',
+		order: 3
+	})
diff --git a/packages/rocketchat-mentions-flextab/client/views/mentionsFlexTab.coffee b/packages/rocketchat-mentions-flextab/client/views/mentionsFlexTab.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..9d693cf3e5a031cb316700e6df367e4b50d2a6dd
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/client/views/mentionsFlexTab.coffee
@@ -0,0 +1,40 @@
+Template.mentionsFlexTab.helpers
+	hasMessages: ->
+		return MentionedMessage.find({ rid: @rid }, { sort: { ts: -1 } }).count() > 0
+
+	messages: ->
+		return MentionedMessage.find { rid: @rid }, { sort: { ts: -1 } }
+
+	notReadySubscription: ->
+		return 'notready' unless Template.instance().subscriptionsReady()
+
+	hasMore: ->
+		return Template.instance().hasMore.get()
+
+Template.mentionsFlexTab.onCreated ->
+	@hasMore = new ReactiveVar true
+	@limit = new ReactiveVar 50
+	@autorun =>
+		sub = @subscribe 'mentionedMessages', @data.rid, @limit.get()
+		if sub.ready()
+			if MentionedMessage.find({ rid: @data.rid }).count() < @limit.get()
+				@hasMore.set false
+
+Template.mentionsFlexTab.events
+	'click .message-cog': (e) ->
+		e.stopPropagation()
+		e.preventDefault()
+		message_id = $(e.currentTarget).closest('.message').attr('id')
+		$('.message-dropdown:visible').hide()
+		$(".mentioned-messages-list \##{message_id} .message-dropdown").remove()
+		message = MentionedMessage.findOne message_id
+		actions = RocketChat.MessageAction.getButtons message
+		el = Blaze.toHTMLWithData Template.messageDropdown, { actions: actions }
+		$(".mentioned-messages-list \##{message_id} .message-cog-container").append el
+		dropDown = $(".mentioned-messages-list \##{message_id} .message-dropdown")
+		dropDown.show()
+
+	'scroll .content': _.throttle (e, instance) ->
+		if e.target.scrollTop >= e.target.scrollHeight - e.target.clientHeight
+			instance.limit.set(instance.limit.get() + 50)
+	, 200
diff --git a/packages/rocketchat-mentions-flextab/client/views/mentionsFlexTab.html b/packages/rocketchat-mentions-flextab/client/views/mentionsFlexTab.html
new file mode 100644
index 0000000000000000000000000000000000000000..8675f5c251b5cd0ff590e10e0142217b830de9f5
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/client/views/mentionsFlexTab.html
@@ -0,0 +1,28 @@
+<template name="mentionsFlexTab">
+	<div class="content">
+		<div class="list-view mentioned-messages-list">
+			<div class="status">
+				<h2>{{_ "Mentions"}}</h2>
+			</div>
+			<ul class="mentioned-messages-list list clearfix">
+				{{#each messages}}
+					{{#nrr nrrargs 'message' .}}{{/nrr}}
+				{{/each}}
+				{{#if hasMore}}
+					<li class="load-more">
+						{{#if Template.subscriptionsReady}}
+							<a href="">{{_ "Has_more"}}...</a>
+						{{else}}
+							<div class="load-more-loading">{{_ "Loading..."}}</div>
+						{{/if}}
+					</li>
+				{{/if}}
+			</ul>
+			{{#if Template.subscriptionsReady}}
+				{{#unless hasMessages}}
+					<h2>{{_ "No_mentions_found"}}</h2>
+				{{/unless}}
+			{{/if}}
+		</div>
+	</div>
+</template>
diff --git a/packages/rocketchat-mentions-flextab/client/views/stylesheets/mentionsFlexTab.less b/packages/rocketchat-mentions-flextab/client/views/stylesheets/mentionsFlexTab.less
new file mode 100644
index 0000000000000000000000000000000000000000..a8956d799c8e2d5580d59a4fb00180be1cd13fd9
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/client/views/stylesheets/mentionsFlexTab.less
@@ -0,0 +1,46 @@
+.mentioned-messages-list {
+	&.notready {
+		background-image: url(/images/logo/loading.gif);
+		background-repeat: no-repeat;
+		background-position: 50% 50%;
+		height: 100px;
+
+		.message {
+			display: none;
+		}
+	}
+
+	li.empty {
+		color: #7f7f7f;
+		text-align: center;
+		margin-top: 60px;
+	}
+
+	.mention-link.mention-link-me {
+		background-color: transparent;
+		color: inherit;
+		&:hover {
+			color: inherit;
+		}
+	}
+
+	.message-cog-container {
+		.message-action {
+			display: none !important;
+			&.jump-to-message {
+				display: block !important;
+			}
+		}
+	}
+
+	.load-more {
+		text-transform: lowercase;
+		text-align: center;
+		line-height: 40px;
+		font-style: italic;
+
+		.load-more-loading {
+			color: #aaa;
+		}
+	}
+}
diff --git a/packages/rocketchat-mentions-flextab/i18n/ar.i18n.json b/packages/rocketchat-mentions-flextab/i18n/ar.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/ar.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/cs.i18n.json b/packages/rocketchat-mentions-flextab/i18n/cs.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/cs.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/de.i18n.json b/packages/rocketchat-mentions-flextab/i18n/de.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..cdf69c577fd629171525083f1a6c595be5d2bb02
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/de.i18n.json
@@ -0,0 +1,4 @@
+{
+  "Mentions" : "Erwähnungen",
+  "No_mentions_found" : "Sie wurden bisher nirgendwo erwähnt."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/el.i18n.json b/packages/rocketchat-mentions-flextab/i18n/el.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/el.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/en.i18n.json b/packages/rocketchat-mentions-flextab/i18n/en.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..e876e44ba9822df6a7de1447412f2cbba25b4e7b
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/en.i18n.json
@@ -0,0 +1,4 @@
+{
+  "Mentions" : "Mentions",
+  "No_mentions_found" : "No mentions found"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/es.i18n.json b/packages/rocketchat-mentions-flextab/i18n/es.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/es.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/fa.i18n.json b/packages/rocketchat-mentions-flextab/i18n/fa.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/fa.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/fi.i18n.json b/packages/rocketchat-mentions-flextab/i18n/fi.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..003f29ff22aaa5402520262a089b9ff75154ee7b
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/fi.i18n.json
@@ -0,0 +1,4 @@
+{
+  "Mentions" : "Maininnat",
+  "No_mentions_found" : "Mainintoja ei löytynyt"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/fr.i18n.json b/packages/rocketchat-mentions-flextab/i18n/fr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..78d945fe3d72f1457cb6c42acb799e9310798945
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/fr.i18n.json
@@ -0,0 +1,4 @@
+{
+  "Mentions" : "Mentions",
+  "No_mentions_found" : "Aucune mention trouvée"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/he.i18n.json b/packages/rocketchat-mentions-flextab/i18n/he.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..f76342a759c4a82f711dcb5772fe25d08c23bed2
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/he.i18n.json
@@ -0,0 +1,4 @@
+{
+  "Mentions" : "אזכורים",
+  "No_mentions_found" : "לא נמצאו אזכורים"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/hr.i18n.json b/packages/rocketchat-mentions-flextab/i18n/hr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/hr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/hu.i18n.json b/packages/rocketchat-mentions-flextab/i18n/hu.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/hu.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/it.i18n.json b/packages/rocketchat-mentions-flextab/i18n/it.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/it.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/ja.i18n.json b/packages/rocketchat-mentions-flextab/i18n/ja.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/ja.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/km.i18n.json b/packages/rocketchat-mentions-flextab/i18n/km.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/km.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/ko.i18n.json b/packages/rocketchat-mentions-flextab/i18n/ko.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/ko.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/ku.i18n.json b/packages/rocketchat-mentions-flextab/i18n/ku.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/ku.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/lo.i18n.json b/packages/rocketchat-mentions-flextab/i18n/lo.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/lo.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/ms-MY.i18n.json b/packages/rocketchat-mentions-flextab/i18n/ms-MY.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/ms-MY.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/nl.i18n.json b/packages/rocketchat-mentions-flextab/i18n/nl.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..52e805767b306df055b5d7b5df3b2acbcc97b943
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/nl.i18n.json
@@ -0,0 +1,4 @@
+{
+  "Mentions" : "Vermeldingen",
+  "No_mentions_found" : "Geen vermeldingen gevonden"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/pl.i18n.json b/packages/rocketchat-mentions-flextab/i18n/pl.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..4668ec4afa75b1d65c342cd02502007702fdf15f
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/pl.i18n.json
@@ -0,0 +1,4 @@
+{
+  "Mentions" : "Wzmianki o tobie",
+  "No_mentions_found" : "Nie znaleziono wzmianek o tobie"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/pt.i18n.json b/packages/rocketchat-mentions-flextab/i18n/pt.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/pt.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/ro.i18n.json b/packages/rocketchat-mentions-flextab/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..1e3a994651563e044cc9c58a897ac05a8049eb39
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/ro.i18n.json
@@ -0,0 +1,4 @@
+{
+  "Mentions" : "Mențiuni",
+  "No_mentions_found" : "Nicio mențiune găsită"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/ru.i18n.json b/packages/rocketchat-mentions-flextab/i18n/ru.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..1a95e01b2d59ed40e06820f12e731ae1e697647e
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/ru.i18n.json
@@ -0,0 +1,4 @@
+{
+  "Mentions" : "Упоминания",
+  "No_mentions_found" : "Упоминания не найдены"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/sq.i18n.json b/packages/rocketchat-mentions-flextab/i18n/sq.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/sq.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/sr.i18n.json b/packages/rocketchat-mentions-flextab/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/sr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/sv.i18n.json b/packages/rocketchat-mentions-flextab/i18n/sv.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/sv.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/ta-IN.i18n.json b/packages/rocketchat-mentions-flextab/i18n/ta-IN.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/ta-IN.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/tr.i18n.json b/packages/rocketchat-mentions-flextab/i18n/tr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/tr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/ug.i18n.json b/packages/rocketchat-mentions-flextab/i18n/ug.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/ug.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/uk.i18n.json b/packages/rocketchat-mentions-flextab/i18n/uk.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/uk.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-mentions-flextab/i18n/zh.i18n.json b/packages/rocketchat-mentions-flextab/i18n/zh.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/i18n/zh.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-authorization/server/publications/integrations.coffee b/packages/rocketchat-mentions-flextab/package-tap.i18n
similarity index 100%
rename from packages/rocketchat-authorization/server/publications/integrations.coffee
rename to packages/rocketchat-mentions-flextab/package-tap.i18n
diff --git a/packages/rocketchat-mentions-flextab/package.js b/packages/rocketchat-mentions-flextab/package.js
new file mode 100644
index 0000000000000000000000000000000000000000..320ff8098d1b48ace45bab0a45363802097c3384
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/package.js
@@ -0,0 +1,46 @@
+Package.describe({
+	name: 'rocketchat:mentions-flextab',
+	version: '0.0.1',
+	summary: 'Mentions Flextab',
+	git: ''
+});
+
+Package.onUse(function(api) {
+	api.versionsFrom('1.0');
+
+	api.use([
+		'coffeescript',
+		'underscore',
+		'less@2.5.0',
+		'rocketchat:lib'
+	]);
+
+	api.addFiles([
+		'client/lib/MentionedMessage.coffee',
+		'client/views/stylesheets/mentionsFlexTab.less',
+		'client/views/mentionsFlexTab.html',
+		'client/views/mentionsFlexTab.coffee',
+		'client/actionButton.coffee',
+		'client/tabBar.coffee'
+	], 'client');
+
+	api.addFiles([
+		'server/publications/mentionedMessages.coffee'
+	], 'server');
+
+	// TAPi18n
+	api.use('templating', 'client');
+	var _ = Npm.require('underscore');
+	var fs = Npm.require('fs');
+	tapi18nFiles = _.compact(_.map(fs.readdirSync('packages/rocketchat-mentions-flextab/i18n'), function(filename) {
+		if (fs.statSync('packages/rocketchat-mentions-flextab/i18n/' + filename).size > 16) {
+			return 'i18n/' + filename;
+		}
+	}));
+	api.use('tap:i18n');
+	api.addFiles(tapi18nFiles);
+});
+
+Package.onTest(function(api) {
+
+});
diff --git a/packages/rocketchat-mentions-flextab/server/publications/mentionedMessages.coffee b/packages/rocketchat-mentions-flextab/server/publications/mentionedMessages.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..72a557e2df8547cc83ad88e5db2f1d8ed441f68e
--- /dev/null
+++ b/packages/rocketchat-mentions-flextab/server/publications/mentionedMessages.coffee
@@ -0,0 +1,25 @@
+Meteor.publish 'mentionedMessages', (rid, limit=50) ->
+	unless this.userId
+		return this.ready()
+
+	publication = @
+
+	user = RocketChat.models.Users.findOneById this.userId
+	unless user
+		return this.ready()
+
+	cursorHandle = RocketChat.models.Messages.findVisibleByMentionAndRoomId(user.username, rid, { sort: { ts: -1 }, limit: limit }).observeChanges
+		added: (_id, record) ->
+			record.mentionedList = true
+			publication.added('rocketchat_mentioned_message', _id, record)
+
+		changed: (_id, record) ->
+			record.mentionedList = true
+			publication.changed('rocketchat_mentioned_message', _id, record)
+
+		removed: (_id) ->
+			publication.removed('rocketchat_mentioned_message', _id)
+
+	@ready()
+	@onStop ->
+		cursorHandle.stop()
diff --git a/packages/rocketchat-mentions/package.js b/packages/rocketchat-mentions/package.js
index 51266c3fd9c04c0647801a77022f767c677a4e69..bc10d0e3e7cfb291e130b43714f5655b8b72d4ca 100644
--- a/packages/rocketchat-mentions/package.js
+++ b/packages/rocketchat-mentions/package.js
@@ -10,7 +10,7 @@ Package.onUse(function(api) {
 
 	api.use([
 		'coffeescript',
-		'rocketchat:lib@0.0.1'
+		'rocketchat:lib'
 	]);
 
 	api.addFiles('server.coffee', 'server');
diff --git a/packages/rocketchat-message-attachments/client/messageAttachment.coffee b/packages/rocketchat-message-attachments/client/messageAttachment.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..4bfee816da8991bdb5e53a9309833c739ed1bd16
--- /dev/null
+++ b/packages/rocketchat-message-attachments/client/messageAttachment.coffee
@@ -0,0 +1,30 @@
+Template.messageAttachment.helpers
+	fixCordova: (url) ->
+		if Meteor.isCordova and url?[0] is '/'
+			url = Meteor.absoluteUrl().replace(/\/$/, '') + url
+			query = "rc_uid=#{Meteor.userId()}&rc_token=#{Meteor._localStorage.getItem('Meteor.loginToken')}"
+			if url.indexOf('?') is -1
+				url = url + '?' + query
+			else
+				url = url + '&' + query
+
+		return url
+
+	showImage: ->
+		if Meteor.user()?.settings?.preferences?.autoImageLoad is false and this.downloadImages? is not true
+			return false
+
+		if Meteor.Device.isPhone() and Meteor.user()?.settings?.preferences?.saveMobileBandwidth and this.downloadImages? is not true
+			return false
+
+		return true
+
+	getImageHeight: (height) ->
+		return height or 200
+
+	color: ->
+		switch @color
+			when 'good' then return '#35AC19'
+			when 'warning' then return '#FCB316'
+			when 'danger' then return '#D30230'
+			else return @color
diff --git a/packages/rocketchat-message-attachments/client/messageAttachment.html b/packages/rocketchat-message-attachments/client/messageAttachment.html
index 7429edaedb10a11373d7c7c7189eb70364a8c409..06fc30ea37ce3f34a7c5ee23c92d8579a9d87e51 100644
--- a/packages/rocketchat-message-attachments/client/messageAttachment.html
+++ b/packages/rocketchat-message-attachments/client/messageAttachment.html
@@ -9,14 +9,14 @@
 				{{#if author_link}}
 					<div class="attachment-author">
 						{{#if author_icon}}
-							<img src="{{author_icon}}">
+							<img src="{{fixCordova author_icon}}">
 						{{/if}}
-						<a href="{{author_link}}" target="_blank">{{author_name}}</a>
+						<a href="{{fixCordova author_link}}" target="_blank">{{author_name}}</a>
 					</div>
 				{{else}}
 					<div class="attachment-author">
 						{{#if author_icon}}
-							<img src="{{author_icon}}">
+							<img src="{{fixCordova author_icon}}">
 						{{/if}}
 						{{author_name}}
 					</div>
@@ -25,7 +25,7 @@
 
 			{{#if title}}
 				{{#if title_link}}
-					<div class="attachment-title"><a href="{{title_link}}" target="_blank">{{title}}</a></div>
+					<div class="attachment-title"><a href="{{fixCordova title_link}}" target="_blank">{{title}}</a></div>
 				{{else}}
 					<div class="attachment-title">{{title}}</div>
 				{{/if}}
@@ -34,7 +34,7 @@
 			<div class="attachment-flex">
 				{{#if thumb_url}}
 					<div class="attachment-thumb">
-						<img src="{{thumb_url}}">
+						<img src="{{fixCordova thumb_url}}">
 					</div>
 				{{/if}}
 
@@ -47,11 +47,36 @@
 
 			{{#if image_url}}
 				<div class="attachment-image">
-					<a href="{{image_url}}" class="swipebox" target="_blank">
-						<div class="inline-image" style="background-image: url({{image_url}});">
-							<img src="{{image_url}}">
+					{{#if showImage}}
+						<a href="{{fixCordova image_url}}" class="swipebox" target="_blank">
+							<div class="inline-image" style="background-image: url('{{fixCordova image_url}}');">
+								<img src="{{fixCordova image_url}}" height="{{getImageHeight image_dimensions.height}}">
+							</div>
+						</a>
+					{{else}}
+						<div class="image-to-download" data-url="{{image_url}}">
+							<i class="icon-picture"></i>
+							<div>click to load</div>
 						</div>
-					</a>
+					{{/if}}
+				</div>
+			{{/if}}
+
+			{{#if audio_url}}
+				<div class="attachment-audio">
+					<audio controls>
+						<source src="{{fixCordova audio_url}}" type="{{audio_type}}">
+						Your browser does not support the audio element.
+					</audio>
+				</div>
+			{{/if}}
+
+			{{#if video_url}}
+				<div class="attachment-video">
+					<video controls class="inline-video">
+						<source src="{{fixCordova video_url}}" type="{{video_type}}">
+						Your browser does not support the video element.
+					</video>
 				</div>
 			{{/if}}
 
diff --git a/packages/rocketchat-message-attachments/package.js b/packages/rocketchat-message-attachments/package.js
index 928f83ea8dcb924f2c566a8319a1fceca813f858..9c9945e868af9a42f5f8cbd70cde281fee4a0b4f 100644
--- a/packages/rocketchat-message-attachments/package.js
+++ b/packages/rocketchat-message-attachments/package.js
@@ -12,10 +12,11 @@ Package.onUse(function(api) {
 		'templating',
 		'coffeescript',
 		'underscore',
-		'rocketchat:lib@0.0.1'
+		'rocketchat:lib'
 	]);
 
 	api.addFiles('client/messageAttachment.html', 'client');
+	api.addFiles('client/messageAttachment.coffee', 'client');
 
 	// stylesheets
 	api.addAssets('client/stylesheets/messageAttachments.less', 'server');
diff --git a/packages/rocketchat-message-pin/client/actionButton.coffee b/packages/rocketchat-message-pin/client/actionButton.coffee
index 78527e098fdc338816d1bede7debb54ab9221a44..14f0129ceb8067cafbdd0c9aa5646f961deb29e0 100644
--- a/packages/rocketchat-message-pin/client/actionButton.coffee
+++ b/packages/rocketchat-message-pin/client/actionButton.coffee
@@ -21,7 +21,7 @@ Meteor.startup ->
 
 	RocketChat.MessageAction.addButton
 		id: 'unpin-message'
-		icon: 'icon-pin'
+		icon: 'icon-pin rotate-45'
 		i18nLabel: 'Unpin_Message'
 		action: (event, instance) ->
 			message = @_arguments[1]
@@ -38,3 +38,14 @@ Meteor.startup ->
 
 			return ChatRoom.findOne(message.rid).u?._id is Meteor.userId()
 		order: 21
+
+	RocketChat.MessageAction.addButton
+		id: 'jump-to-pin-message'
+		icon: 'icon-right-hand'
+		i18nLabel: 'Jump_to_message'
+		action: (event, instance) ->
+			message = @_arguments[1]
+			$('.message-dropdown:visible').hide()
+			RoomHistoryManager.getSurroundingMessages(message, 50)
+		order: 100
+
diff --git a/packages/rocketchat-message-pin/client/pinMessage.coffee b/packages/rocketchat-message-pin/client/pinMessage.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..7b934880ac43f8fbe8213f7bd48a9c86ad8a745c
--- /dev/null
+++ b/packages/rocketchat-message-pin/client/pinMessage.coffee
@@ -0,0 +1,26 @@
+Meteor.methods
+	pinMessage: (message) ->
+		if not Meteor.userId()
+			throw new Meteor.Error('invalid-user', "[methods] pinMessage -> Invalid user")
+
+		if not RocketChat.settings.get 'Message_AllowPinning'
+			throw new Meteor.Error 'message-pinning-not-allowed', '[methods] pinMessage -> Message pinning not allowed'
+
+
+		ChatMessage.update
+			_id: message._id
+		,
+			$set: { pinned: true }
+
+	unpinMessage: (message) ->
+		if not Meteor.userId()
+			throw new Meteor.Error('invalid-user', "[methods] pinMessage -> Invalid user")
+
+		if not RocketChat.settings.get 'Message_AllowPinning'
+			throw new Meteor.Error 'message-pinning-not-allowed', '[methods] pinMessage -> Message pinning not allowed'
+
+
+		ChatMessage.update
+			_id: message._id
+		,
+			$set: { pinned: false }
diff --git a/packages/rocketchat-message-pin/client/tabBar.coffee b/packages/rocketchat-message-pin/client/tabBar.coffee
index f4b8d24a66b68211b85dc870ecaca04247dfef90..f434a26bf6edea1d32f92939130342fc2c1ee7e5 100644
--- a/packages/rocketchat-message-pin/client/tabBar.coffee
+++ b/packages/rocketchat-message-pin/client/tabBar.coffee
@@ -1,5 +1,13 @@
 Meteor.startup ->
-	RocketChat.callbacks.add 'enter-room', ->
+	Tracker.autorun ->
 		if RocketChat.settings.get 'Message_AllowPinning'
-			RocketChat.TabBar.addButton({ id: 'pinned-messages', i18nTitle: 'Pinned_Messages', icon: 'icon-pin', template: 'pinnedMessages', order: 10 })
-	, RocketChat.callbacks.priority.MEDIUM, 'enter-room-tabbar-pin'
+			RocketChat.TabBar.addButton({
+				groups: ['channel', 'privategroup', 'directmessage'],
+				id: 'pinned-messages',
+				i18nTitle: 'Pinned_Messages',
+				icon: 'icon-pin',
+				template: 'pinnedMessages',
+				order: 10
+			})
+		else
+			RocketChat.TabBar.removeButton 'pinned-messages'
diff --git a/packages/rocketchat-message-pin/client/views/pinnedMessages.coffee b/packages/rocketchat-message-pin/client/views/pinnedMessages.coffee
index c60783c49ef7a7985d2bf5e0f0502e66a2b0544c..ba6df0cada88cff05c31a0f7286761df523761f2 100644
--- a/packages/rocketchat-message-pin/client/views/pinnedMessages.coffee
+++ b/packages/rocketchat-message-pin/client/views/pinnedMessages.coffee
@@ -1,16 +1,24 @@
 Template.pinnedMessages.helpers
 	hasMessages: ->
-		return PinnedMessage.find({ rid: this.rid }, { sort: { ts: -1 } }).count() > 0
+		return PinnedMessage.find({ rid: @rid }, { sort: { ts: -1 } }).count() > 0
 
 	messages: ->
-		return PinnedMessage.find { rid: this.rid }, { sort: { ts: -1 } }
+		return PinnedMessage.find { rid: @rid }, { sort: { ts: -1 } }
 
-	notReadySubscription: ->
-		return 'notready' unless Template.instance().subscriptionsReady()
+	hasMore: ->
+		return Template.instance().hasMore.get()
 
 Template.pinnedMessages.onCreated ->
-	this.autorun =>
-		this.subscribe 'pinnedMessages', Template.currentData().rid
+	@hasMore = new ReactiveVar true
+	@limit = new ReactiveVar 50
+	@autorun =>
+		sub = @subscribe 'pinnedMessages', @data.rid, @limit.get()
+		if sub.ready()
+			if PinnedMessage.find({ rid: @data.rid }).count() < @limit.get()
+				@hasMore.set false
+
+	@autorun =>
+		@subscribe 'pinnedMessages', Template.currentData().rid
 
 Template.pinnedMessages.events
 	'click .message-cog': (e) ->
@@ -18,4 +26,15 @@ Template.pinnedMessages.events
 		e.preventDefault()
 		message_id = $(e.currentTarget).closest('.message').attr('id')
 		$('.message-dropdown:visible').hide()
-		$(".pinned-messages-list \##{message_id} .message-dropdown").show()
+		$(".pinned-messages-list \##{message_id} .message-dropdown").remove()
+		message = PinnedMessage.findOne message_id
+		actions = RocketChat.MessageAction.getButtons message
+		el = Blaze.toHTMLWithData Template.messageDropdown, { actions: actions }
+		$(".pinned-messages-list \##{message_id} .message-cog-container").append el
+		dropDown = $(".pinned-messages-list \##{message_id} .message-dropdown")
+		dropDown.show()
+
+	'scroll .content': _.throttle (e, instance) ->
+		if e.target.scrollTop >= e.target.scrollHeight - e.target.clientHeight
+			instance.limit.set(instance.limit.get() + 50)
+	, 200
diff --git a/packages/rocketchat-message-pin/client/views/pinnedMessages.html b/packages/rocketchat-message-pin/client/views/pinnedMessages.html
index d1c470c7f41cfe8820a6e9e3a8df161a2dae65a7..8122f0c580b011a32a2df021e4ba7932673e5d4f 100644
--- a/packages/rocketchat-message-pin/client/views/pinnedMessages.html
+++ b/packages/rocketchat-message-pin/client/views/pinnedMessages.html
@@ -1,22 +1,28 @@
 <template name="pinnedMessages">
-	<div class="control">
-		<div class="header">
-			<h2>{{_ "Pinned_Messages"}}</h2>
+	<div class="content">
+		<div class="list-view pinned-messages-list">
+			<div class="status">
+				<h2>{{_ "Pinned_Messages"}}</h2>
+			</div>
+			<ul class="list clearfix">
+				{{#each messages}}
+					{{#nrr nrrargs 'message' .}}{{/nrr}}
+				{{/each}}
+				{{#if hasMore}}
+					<li class="load-more">
+						{{#if Template.subscriptionsReady}}
+							<a href="">{{_ "Has_more"}}...</a>
+						{{else}}
+							<div class="load-more-loading">{{_ "Loading..."}}</div>
+						{{/if}}
+					</li>
+				{{/if}}
+			</ul>
+			{{#if Template.subscriptionsReady}}
+				{{#unless hasMessages}}
+					<h2>{{_ "No_pinned_messages"}}</h2>
+				{{/unless}}
+			{{/if}}
 		</div>
 	</div>
-	<ul class="pinned-messages-list scrollable">
-	{{#if Template.subscriptionsReady}}
-		{{#if hasMessages}}
-			{{#each messages}}
-				{{#nrr nrrargs 'message' .}}{{/nrr}}
-			{{/each}}
-		{{else}}
-			<li class="empty">
-				{{_ "No_pinned_messages"}}
-			</li>
-		{{/if}}
-	{{else}}
-		{{> loading}}
-	{{/if}}
-	</ul>
 </template>
diff --git a/packages/rocketchat-message-pin/client/views/stylesheets/messagepin.less b/packages/rocketchat-message-pin/client/views/stylesheets/messagepin.less
index de3c15683ba13efdebdd51c390e7cb22505cdb50..94248d67b99a3248b177fa71e7f5f4328e7e1a9f 100644
--- a/packages/rocketchat-message-pin/client/views/stylesheets/messagepin.less
+++ b/packages/rocketchat-message-pin/client/views/stylesheets/messagepin.less
@@ -1,17 +1,20 @@
-.pinned-messages-list {
-	padding: 30px 0;
-
-	&.notready {
-		background-image: url(/images/logo/loading.gif);
-		background-repeat: no-repeat;
-		background-position: 50% 50%;
-		height: 100px;
+.icon-pin.rotate-45:before {
+	-ms-transform: rotate(45deg);
+	-webkit-transform: rotate(45deg);
+	transform: rotate(45deg);
+}
 
-		.message {
-			display: none;
+.messages-box {
+	.message-cog-container {
+		.message-action {
+			&.jump-to-pin-message {
+				display: none !important;
+			}
 		}
 	}
+}
 
+.pinned-messages-list {
 	li.empty {
 		color: #7f7f7f;
 		text-align: center;
@@ -19,8 +22,22 @@
 	}
 
 	.message-cog-container {
-		.edit-message, .delete-message, .star-message, .unstar-message {
+		.message-action {
 			display: none !important;
+			&.pin-message, &.unpin-message, &.jump-to-pin-message {
+				display: block !important;
+			}
+		}
+	}
+
+	.load-more {
+		text-transform: lowercase;
+		text-align: center;
+		line-height: 40px;
+		font-style: italic;
+
+		.load-more-loading {
+			color: #aaa;
 		}
 	}
 }
diff --git a/packages/rocketchat-message-pin/i18n/ar.i18n.json b/packages/rocketchat-message-pin/i18n/ar.i18n.json
index ab3b6e37c0846ca70eaad727b45556fc7bba1bba..3a3ddcfed5462aed1b7f66405c458ecb108155d6 100644
--- a/packages/rocketchat-message-pin/i18n/ar.i18n.json
+++ b/packages/rocketchat-message-pin/i18n/ar.i18n.json
@@ -1,4 +1,7 @@
 {
+  "Message_AllowPinning" : "السماح بتثبيث الرسائل",
+  "Pin_Message" : "تثبيث الرسالة",
+  "Unpin_Message" : "إلغاء تثبيث الرسالة",
   "Pinned_Messages" : "رسائل مثبتة",
   "No_pinned_messages" : "لا توجد رسائل مثبتة"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-message-pin/i18n/de.i18n.json b/packages/rocketchat-message-pin/i18n/de.i18n.json
index b8e3131562d0148aa479c3693495c909a673af0e..1f6aa825c53be2e6897a984cdeb055ef9760ea71 100644
--- a/packages/rocketchat-message-pin/i18n/de.i18n.json
+++ b/packages/rocketchat-message-pin/i18n/de.i18n.json
@@ -1,3 +1,10 @@
 {
-  "Message_AllowPinning" : "Erlaube es Nachrichten anzuheften"
+  "Message_AllowPinning" : "Das Fixieren von Nachrichten erlauben",
+  "Message_AllowPinning_Description" : "Benutzern das Fixieren von Nachrichten in Kanälen erlauben",
+  "Message_AllowPinningByAnyone" : "Jedem Nutzer erlauben, Nachrichten zu fixieren",
+  "Message_AllowPinningByAnyone_Description" : "Allen Benutzern das Fixieren von Nachrichten in Kanälen erlauben",
+  "Pin_Message" : "Nachricht fixieren",
+  "Unpin_Message" : "Nachicht nicht mehr fixieren",
+  "Pinned_Messages" : "Fixierte Nachrichten",
+  "No_pinned_messages" : "Es wurden bisher keine Nachrichten fixiert."
 }
\ No newline at end of file
diff --git a/packages/rocketchat-message-pin/i18n/fr.i18n.json b/packages/rocketchat-message-pin/i18n/fr.i18n.json
index 19f10ea3b8aed970de214ba28f85219e3a133293..1b4a150a1f2b0c2994a63ae6ae1822b34429d53d 100644
--- a/packages/rocketchat-message-pin/i18n/fr.i18n.json
+++ b/packages/rocketchat-message-pin/i18n/fr.i18n.json
@@ -1,3 +1,10 @@
 {
-  "Message_AllowPinning" : "Autoriser l'épinglement de messages"
+  "Message_AllowPinning" : "Autoriser l'épinglement de messages",
+  "Message_AllowPinning_Description" : "Autoriser les messages à être épinglés à tous des canaux.",
+  "Message_AllowPinningByAnyone" : "Permettre à quiconque d'épingler des messages",
+  "Message_AllowPinningByAnyone_Description" : "Permettre à quiconque d'épingler des messages, pas seulement les administrateurs.",
+  "Pin_Message" : "Épingler ce message",
+  "Unpin_Message" : "Détacher ce message",
+  "Pinned_Messages" : "Messages épinglés",
+  "No_pinned_messages" : "Aucun message épinglé"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-message-pin/i18n/he.i18n.json b/packages/rocketchat-message-pin/i18n/he.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..8523fea7c8df9324431fe6778f314acf5fde46e9 100644
--- a/packages/rocketchat-message-pin/i18n/he.i18n.json
+++ b/packages/rocketchat-message-pin/i18n/he.i18n.json
@@ -1 +1,6 @@
-{ }
\ No newline at end of file
+{
+  "Pin_Message" : "הצמדת הודעה",
+  "Unpin_Message" : "שחרור הודעה",
+  "Pinned_Messages" : "הודעות מוצמדות",
+  "No_pinned_messages" : "אין הודעות מוצמדות"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-message-pin/i18n/km.i18n.json b/packages/rocketchat-message-pin/i18n/km.i18n.json
index 4b0abbe97422cfbe12fc6da0329fce4ba5e09a11..a61185894bc25b7438d261109666520c2a55b51a 100644
--- a/packages/rocketchat-message-pin/i18n/km.i18n.json
+++ b/packages/rocketchat-message-pin/i18n/km.i18n.json
@@ -1,3 +1,9 @@
 {
-  "Message_AllowPinning" : "អនុញ្ញតិ​ខ្ទស់សារ​"
+  "Message_AllowPinning" : "អនុញ្ញតិ​ខ្ទស់សារ​",
+  "Message_AllowPinning_Description" : "អនុញ្ញាតឱ្យសារត្រូវបានខ្ទាស់ទៅច្រើនប៉ុស្តិ៍។",
+  "Message_AllowPinningByAnyone" : "អនុញ្ញាតឱ្យគ្រាប់គ្នាខ្ទាស់សារ",
+  "Message_AllowPinningByAnyone_Description" : "អនុញ្ញាតិឲ្យគ្រប់គ្នាអាចខ្ទាស់សារទៅកាន់ប៉ុស្តិ៍ណាមួយ ដោយមិនចាំបាច់សិទ្ធជាអ្នកគ្រប់គ្រង។",
+  "Pin_Message" : "ខ្ទាស់សារ",
+  "Pinned_Messages" : "មិនខ្ទាស់សារ",
+  "No_pinned_messages" : "មិនមានសារបានខ្ទាស់"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-message-pin/i18n/ko.i18n.json b/packages/rocketchat-message-pin/i18n/ko.i18n.json
index 4feeebeb4f06b5295d1b0bae16e8c5c7c4c239c0..fbd8a50499a8cbff4f9400fc4bc825bb1aef53b9 100644
--- a/packages/rocketchat-message-pin/i18n/ko.i18n.json
+++ b/packages/rocketchat-message-pin/i18n/ko.i18n.json
@@ -1,5 +1,6 @@
 {
   "Message_AllowPinning" : "허용 메시지 고정",
+  "Message_AllowPinningByAnyone" : "누구나 메시지를 보관할 수 있도록 허용",
   "Pin_Message" : "메시지 보관하기",
   "Unpin_Message" : "메시지 보관하지 않기",
   "Pinned_Messages" : "보관된 메시지",
diff --git a/packages/rocketchat-message-pin/i18n/nl.i18n.json b/packages/rocketchat-message-pin/i18n/nl.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..721e551b3217d9f658b247958726cab59b1091bb 100644
--- a/packages/rocketchat-message-pin/i18n/nl.i18n.json
+++ b/packages/rocketchat-message-pin/i18n/nl.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Message_AllowPinning" : "Bericht vastzetten toestaan"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-message-pin/i18n/ro.i18n.json b/packages/rocketchat-message-pin/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..20534d184df0fd50afd6437ecb494fc3a39a9eb2
--- /dev/null
+++ b/packages/rocketchat-message-pin/i18n/ro.i18n.json
@@ -0,0 +1,10 @@
+{
+  "Message_AllowPinning" : "Permiteți fixarea mesajului",
+  "Message_AllowPinning_Description" : "Permite fixarea mesajelor în oricare canal.",
+  "Message_AllowPinningByAnyone" : "Permite oricui să fixeze mesaje.",
+  "Message_AllowPinningByAnyone_Description" : "Permite oricui să fixeze mesaje pe un canal, nu doar administratorilor.",
+  "Pin_Message" : "Fixează mesaj",
+  "Unpin_Message" : "Anulați fixarea mesajului",
+  "Pinned_Messages" : "Mesaje fixate",
+  "No_pinned_messages" : "Nu sunt mesaje fixate"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-message-pin/i18n/ru.i18n.json b/packages/rocketchat-message-pin/i18n/ru.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..a83261331d94ebaa9049dac4c7df7cfcbccf331a 100644
--- a/packages/rocketchat-message-pin/i18n/ru.i18n.json
+++ b/packages/rocketchat-message-pin/i18n/ru.i18n.json
@@ -1 +1,6 @@
-{ }
\ No newline at end of file
+{
+  "Message_AllowPinning" : "Разрешить прикреплять сообщения",
+  "Message_AllowPinning_Description" : "Разрешить прикреплять сообщения к любому из каналов",
+  "Pinned_Messages" : "Прикрепленные сообщения",
+  "No_pinned_messages" : "Нет прикрепленных сообщений"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-message-pin/i18n/sr.i18n.json b/packages/rocketchat-message-pin/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-message-pin/i18n/sr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-message-pin/package.js b/packages/rocketchat-message-pin/package.js
index 69f0358da29e6d86fb1bca4e98226ac0fc2f5c7b..b70908ef0bdce2e313147918eb6795e6d8de53d0 100644
--- a/packages/rocketchat-message-pin/package.js
+++ b/packages/rocketchat-message-pin/package.js
@@ -9,13 +9,15 @@ Package.onUse(function(api) {
 
 	api.use([
 		'coffeescript',
+		'underscore',
 		'less@2.5.0',
-		'rocketchat:lib@0.0.1'
+		'rocketchat:lib'
 	]);
 
 	api.addFiles([
 		'client/lib/PinnedMessage.coffee',
 		'client/actionButton.coffee',
+		'client/pinMessage.coffee',
 		'client/tabBar.coffee',
 		'client/views/pinnedMessages.html',
 		'client/views/pinnedMessages.coffee',
@@ -38,9 +40,8 @@ Package.onUse(function(api) {
 			return 'i18n/' + filename;
 		}
 	}));
-	api.use(["tap:i18n@1.5.1"], ["client", "server"]);
-	api.imply('tap:i18n');
-	api.addFiles(tapi18nFiles, ["client", "server"]);
+	api.use('tap:i18n');
+	api.addFiles(tapi18nFiles);
 });
 
 Package.onTest(function(api) {
diff --git a/packages/rocketchat-message-pin/server/pinMessage.coffee b/packages/rocketchat-message-pin/server/pinMessage.coffee
index 7a62e55f3da45d6934df4dea17ee3c4e21a8c574..01e651611439a7bfb3a8ff389089a0981c2600de 100644
--- a/packages/rocketchat-message-pin/server/pinMessage.coffee
+++ b/packages/rocketchat-message-pin/server/pinMessage.coffee
@@ -6,8 +6,6 @@ Meteor.methods
 		if not RocketChat.settings.get 'Message_AllowPinning'
 			throw new Meteor.Error 'message-pinning-not-allowed', '[methods] pinMessage -> Message pinning not allowed'
 
-		console.log '[methods] pinMessage -> '.green, 'userId:', Meteor.userId()
-
 		# If we keep history of edits, insert a new message to store history information
 		if RocketChat.settings.get 'Message_KeepHistory'
 			RocketChat.models.Messages.cloneAndSaveAsHistoryById message._id
@@ -31,8 +29,6 @@ Meteor.methods
 		if not RocketChat.settings.get 'Message_AllowPinning'
 			throw new Meteor.Error 'message-pinning-not-allowed', '[methods] pinMessage -> Message pinning not allowed'
 
-		console.log '[methods] unpinMessage -> '.green, 'userId:', Meteor.userId()
-
 		# If we keep history of edits, insert a new message to store history information
 		if RocketChat.settings.get 'Message_KeepHistory'
 			RocketChat.models.Messages.cloneAndSaveAsHistoryById message._id
diff --git a/packages/rocketchat-message-pin/server/publications/pinnedMessages.coffee b/packages/rocketchat-message-pin/server/publications/pinnedMessages.coffee
index 7daf7a32bd576bc82e502cff3987260fe1876617..efa77f81456c4f9e9bab4511f9ca6497ef5e414f 100644
--- a/packages/rocketchat-message-pin/server/publications/pinnedMessages.coffee
+++ b/packages/rocketchat-message-pin/server/publications/pinnedMessages.coffee
@@ -1,12 +1,14 @@
-Meteor.publish 'pinnedMessages', (rid, options = {}) ->
+Meteor.publish 'pinnedMessages', (rid, limit=50) ->
 	unless this.userId
 		return this.ready()
 
-	console.log '[publish] pinnedMessages -> '.green, 'rid:', rid, 'options:', options
-
 	publication = @
 
-	cursorHandle = RocketChat.models.Messages.findPinnedByRoom(rid, { sort: { ts: -1 }, limit: 50 }).observeChanges
+	user = RocketChat.models.Users.findOneById this.userId
+	unless user
+		return this.ready()
+
+	cursorHandle = RocketChat.models.Messages.findPinnedByRoom(rid, { sort: { ts: -1 }, limit: limit }).observeChanges
 		added: (_id, record) ->
 			publication.added('rocketchat_pinned_message', _id, record)
 
diff --git a/packages/rocketchat-message-star/client/actionButton.coffee b/packages/rocketchat-message-star/client/actionButton.coffee
index 02d25daf7e74d8b5678fa55f834e41b6262f2a38..42d0f7a017256a14f9f97d03b50db68b7df496c4 100644
--- a/packages/rocketchat-message-star/client/actionButton.coffee
+++ b/packages/rocketchat-message-star/client/actionButton.coffee
@@ -26,3 +26,13 @@ Meteor.startup ->
 		validation: (message) ->
 			return RocketChat.settings.get('Message_AllowStarring') and message.starred
 		order: 10
+
+	RocketChat.MessageAction.addButton
+		id: 'jump-to-star-message'
+		icon: 'icon-right-hand'
+		i18nLabel: 'Jump_to_message'
+		action: (event, instance) ->
+			message = @_arguments[1]
+			$('.message-dropdown:visible').hide()
+			RoomHistoryManager.getSurroundingMessages(message, 50)
+		order: 100
diff --git a/packages/rocketchat-message-star/client/tabBar.coffee b/packages/rocketchat-message-star/client/tabBar.coffee
index b2b2d969d1ad552e440b87acae9f4412cfa3facd..9e34add34ab923157eddb1f29d64762de8dea380 100644
--- a/packages/rocketchat-message-star/client/tabBar.coffee
+++ b/packages/rocketchat-message-star/client/tabBar.coffee
@@ -1,4 +1,9 @@
 Meteor.startup ->
-	RocketChat.callbacks.add 'enter-room', ->
-		RocketChat.TabBar.addButton({ id: 'starred-messages', i18nTitle: 'Starred_Messages', icon: 'icon-star', template: 'starredMessages', order: 3 })
-	, RocketChat.callbacks.priority.MEDIUM, 'enter-room-tabbar-star'
+	RocketChat.TabBar.addButton({
+		groups: ['channel', 'privategroup', 'directmessage'],
+		id: 'starred-messages',
+		i18nTitle: 'Starred_Messages',
+		icon: 'icon-star',
+		template: 'starredMessages',
+		order: 3
+	})
diff --git a/packages/rocketchat-message-star/client/views/starredMessages.coffee b/packages/rocketchat-message-star/client/views/starredMessages.coffee
index 24124e12f4f640d68a5b0950b87af3f1e0ea5ed0..f51eb088a1524a77398c36cca90f48c2745ca756 100644
--- a/packages/rocketchat-message-star/client/views/starredMessages.coffee
+++ b/packages/rocketchat-message-star/client/views/starredMessages.coffee
@@ -1,16 +1,21 @@
 Template.starredMessages.helpers
 	hasMessages: ->
-		return StarredMessage.find({ rid: this.rid }, { sort: { ts: -1 } }).count() > 0
+		return StarredMessage.find({ rid: @rid }, { sort: { ts: -1 } }).count() > 0
 
 	messages: ->
-		return StarredMessage.find { rid: this.rid }, { sort: { ts: -1 } }
+		return StarredMessage.find { rid: @rid }, { sort: { ts: -1 } }
 
-	notReadySubscription: ->
-		return 'notready' unless Template.instance().subscriptionsReady()
+	hasMore: ->
+		return Template.instance().hasMore.get()
 
 Template.starredMessages.onCreated ->
-	this.autorun =>
-		this.subscribe 'starredMessages', Template.currentData().rid
+	@hasMore = new ReactiveVar true
+	@limit = new ReactiveVar 50
+	@autorun =>
+		sub = @subscribe 'starredMessages', @data.rid, @limit.get()
+		if sub.ready()
+			if StarredMessage.find({ rid: @data.rid }).count() < @limit.get()
+				@hasMore.set false
 
 Template.starredMessages.events
 	'click .message-cog': (e) ->
@@ -18,4 +23,15 @@ Template.starredMessages.events
 		e.preventDefault()
 		message_id = $(e.currentTarget).closest('.message').attr('id')
 		$('.message-dropdown:visible').hide()
-		$(".starred-messages-list \##{message_id} .message-dropdown").show()
+		$(".starred-messages-list \##{message_id} .message-dropdown").remove()
+		message = StarredMessage.findOne message_id
+		actions = RocketChat.MessageAction.getButtons message
+		el = Blaze.toHTMLWithData Template.messageDropdown, { actions: actions }
+		$(".starred-messages-list \##{message_id} .message-cog-container").append el
+		dropDown = $(".starred-messages-list \##{message_id} .message-dropdown")
+		dropDown.show()
+
+	'scroll .content': _.throttle (e, instance) ->
+		if e.target.scrollTop >= e.target.scrollHeight - e.target.clientHeight
+			instance.limit.set(instance.limit.get() + 50)
+	, 200
diff --git a/packages/rocketchat-message-star/client/views/starredMessages.html b/packages/rocketchat-message-star/client/views/starredMessages.html
index 38724f43a20e534bdafec0adc9c9cc350bc977e2..b1bdc184762adaa40e72b54478a95cc45ec39f5b 100644
--- a/packages/rocketchat-message-star/client/views/starredMessages.html
+++ b/packages/rocketchat-message-star/client/views/starredMessages.html
@@ -1,22 +1,28 @@
 <template name="starredMessages">
-	<div class="control">
-		<div class="header">
-			<h2>{{_ "Starred_Messages"}}</h2>
+	<div class="content">
+		<div class="list-view starred-messages-list">
+			<div class="status">
+				<h2>{{_ "Starred_Messages"}}</h2>
+			</div>
+			<ul class="list clearfix">
+				{{#each messages}}
+					{{#nrr nrrargs 'message' .}}{{/nrr}}
+				{{/each}}
+				{{#if hasMore}}
+					<li class="load-more">
+						{{#if Template.subscriptionsReady}}
+							<a href="">{{_ "Has_more"}}...</a>
+						{{else}}
+							<div class="load-more-loading">{{_ "Loading..."}}</div>
+						{{/if}}
+					</li>
+				{{/if}}
+			</ul>
+			{{#if Template.subscriptionsReady}}
+				{{#unless hasMessages}}
+					<h2>{{_ "No_starred_messages"}}</h2>
+				{{/unless}}
+			{{/if}}
 		</div>
 	</div>
-	<ul class="starred-messages-list scrollable">
-	{{#if Template.subscriptionsReady}}
-		{{#if hasMessages}}
-			{{#each messages}}
-				{{#nrr nrrargs 'message' .}}{{/nrr}}
-			{{/each}}
-		{{else}}
-			<li class="empty">
-				{{_ "No_starred_messages"}}
-			</li>
-		{{/if}}
-	{{else}}
-		{{> loading}}
-	{{/if}}
-	</ul>
 </template>
diff --git a/packages/rocketchat-message-star/client/views/stylesheets/messagestar.less b/packages/rocketchat-message-star/client/views/stylesheets/messagestar.less
index b31cb69553af5fbcaafa34da94d6d0d9dbd47820..83e74cbb29b467e4b3b4e5c753cf1bef777973e4 100644
--- a/packages/rocketchat-message-star/client/views/stylesheets/messagestar.less
+++ b/packages/rocketchat-message-star/client/views/stylesheets/messagestar.less
@@ -1,17 +1,14 @@
-.starred-messages-list {
-	padding: 30px 0;
-
-	&.notready {
-		background-image: url(/images/logo/loading.gif);
-		background-repeat: no-repeat;
-		background-position: 50% 50%;
-		height: 100px;
-
-		.message {
-			display: none;
+.messages-box {
+	.message-cog-container {
+		.message-action {
+			&.jump-to-star-message {
+				display: none !important;
+			}
 		}
 	}
+}
 
+.starred-messages-list {
 	li.empty {
 		color: #7f7f7f;
 		text-align: center;
@@ -19,8 +16,22 @@
 	}
 
 	.message-cog-container {
-		.edit-message, .delete-message, .pin-message, .unpin-message {
+		.message-action {
 			display: none !important;
+			&.star-message, &.unstar-message, &.jump-to-star-message {
+				display: block !important;
+			}
+		}
+	}
+
+	.load-more {
+		text-transform: lowercase;
+		text-align: center;
+		line-height: 40px;
+		font-style: italic;
+
+		.load-more-loading {
+			color: #aaa;
 		}
 	}
 }
diff --git a/packages/rocketchat-message-star/i18n/de.i18n.json b/packages/rocketchat-message-star/i18n/de.i18n.json
index bb056d4d81b846e4ba8a2c637e2a81bb7523231a..e7a604c007692baa15e70375cab22f6b805344d3 100644
--- a/packages/rocketchat-message-star/i18n/de.i18n.json
+++ b/packages/rocketchat-message-star/i18n/de.i18n.json
@@ -1,7 +1,7 @@
 {
-  "Message_AllowStarring" : "Erlaube Nachricht mit einem Stern zu makieren",
-  "Star_Message" : "Stern-Nachrichten",
-  "Unstar_Message" : "Stern entfernen",
-  "Starred_Messages" : "Nachrichten mit Stern",
-  "No_starred_messages" : "Keine Nachrichten mit einem Stern"
+  "Message_AllowStarring" : "Erlaube es, Nachrichten zu markieren",
+  "Star_Message" : "Nachricht markieren",
+  "Unstar_Message" : "Markierung entfernen",
+  "Starred_Messages" : "Markierte Nachrichten",
+  "No_starred_messages" : "Es wurden bisher keine Nachrichten markiert."
 }
\ No newline at end of file
diff --git a/packages/rocketchat-message-star/i18n/hr.i18n.json b/packages/rocketchat-message-star/i18n/hr.i18n.json
index f57e88dc1e86b7b8cae22bb35abecc47ee0579b6..3a488fb06895cca9df3b6221dab4ce80736b2c41 100644
--- a/packages/rocketchat-message-star/i18n/hr.i18n.json
+++ b/packages/rocketchat-message-star/i18n/hr.i18n.json
@@ -1,4 +1,5 @@
 {
   "Unstar_Message" : "Ukloni zvjezdicu",
-  "Starred_Messages" : "Poruke sa zvjezdicom"
+  "Starred_Messages" : "Poruke sa zvjezdicom",
+  "No_starred_messages" : "Nema poruka sa zvjezdicom"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-message-star/i18n/ko.i18n.json b/packages/rocketchat-message-star/i18n/ko.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..ab22552dc73bf8ab93033ec72c7c1509b8bda6f2 100644
--- a/packages/rocketchat-message-star/i18n/ko.i18n.json
+++ b/packages/rocketchat-message-star/i18n/ko.i18n.json
@@ -1 +1,7 @@
-{ }
\ No newline at end of file
+{
+  "Message_AllowStarring" : "메시지 별표 허용",
+  "Star_Message" : "별표 메시지",
+  "Unstar_Message" : "별표 삭제",
+  "Starred_Messages" : "별표된 메시지",
+  "No_starred_messages" : "별표된 메시지가 없습니다"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-message-star/i18n/ro.i18n.json b/packages/rocketchat-message-star/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..a4e057d9f1da6e13751e5fdd8f5c5970ca457434
--- /dev/null
+++ b/packages/rocketchat-message-star/i18n/ro.i18n.json
@@ -0,0 +1,7 @@
+{
+  "Message_AllowStarring" : "Permiteți însemnarea cu steluță a mesajelor",
+  "Star_Message" : "Marchează cu stea mesajul",
+  "Unstar_Message" : "Eliminați marcajul cu stea",
+  "Starred_Messages" : "Mesaje cu stea",
+  "No_starred_messages" : "Niciun mesaj cu stea"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-message-star/i18n/ru.i18n.json b/packages/rocketchat-message-star/i18n/ru.i18n.json
index 24843cb079a2e507a458e6560294c7723539d789..a34c4a5791a81c4f805fa38c4bd70b27ab5b51d2 100644
--- a/packages/rocketchat-message-star/i18n/ru.i18n.json
+++ b/packages/rocketchat-message-star/i18n/ru.i18n.json
@@ -1,4 +1,5 @@
 {
+  "Message_AllowStarring" : "Разрешить отмечать сообщения",
   "Star_Message" : "Оценить сообщение",
   "Unstar_Message" : "Убрать оценку",
   "Starred_Messages" : "Сообщения с оценкой",
diff --git a/packages/rocketchat-message-star/i18n/sr.i18n.json b/packages/rocketchat-message-star/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-message-star/i18n/sr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-message-star/package.js b/packages/rocketchat-message-star/package.js
index 6073d2bad8199a610b5c4ba23d52a4de38022e8b..a05a6a1767a6dac0257315839720ebaa7efcfa74 100644
--- a/packages/rocketchat-message-star/package.js
+++ b/packages/rocketchat-message-star/package.js
@@ -10,8 +10,9 @@ Package.onUse(function(api) {
 
 	api.use([
 		'coffeescript',
+		'underscore',
 		'less@2.5.0',
-		'rocketchat:lib@0.0.1'
+		'rocketchat:lib'
 	]);
 
 	api.addFiles([
@@ -40,9 +41,8 @@ Package.onUse(function(api) {
 			return 'i18n/' + filename;
 		}
 	}));
-	api.use(["tap:i18n@1.5.1"], ["client", "server"]);
-	api.imply('tap:i18n');
-	api.addFiles(tapi18nFiles, ["client", "server"]);
+	api.use('tap:i18n');
+	api.addFiles(tapi18nFiles);
 });
 
 Package.onTest(function(api) {
diff --git a/packages/rocketchat-message-star/server/publications/starredMessages.coffee b/packages/rocketchat-message-star/server/publications/starredMessages.coffee
index badaa2b3bddb105cbc90bf1f8fe6e5ef94e9eb48..51d664d7653035ed39bf3d9dcee23267e501e0a5 100644
--- a/packages/rocketchat-message-star/server/publications/starredMessages.coffee
+++ b/packages/rocketchat-message-star/server/publications/starredMessages.coffee
@@ -1,12 +1,14 @@
-Meteor.publish 'starredMessages', (rid, options = {}) ->
+Meteor.publish 'starredMessages', (rid, limit=50) ->
 	unless this.userId
 		return this.ready()
 
-	console.log '[publish] starredMessages -> '.green, 'rid:', rid, 'options:', options
-
 	publication = @
 
-	cursorHandle = RocketChat.models.Messages.findStarredByUserAtRoom(this.userId, rid, { sort: { ts: -1 }, limit: 50 }).observeChanges
+	user = RocketChat.models.Users.findOneById this.userId
+	unless user
+		return this.ready()
+
+	cursorHandle = RocketChat.models.Messages.findStarredByUserAtRoom(this.userId, rid, { sort: { ts: -1 }, limit: limit }).observeChanges
 		added: (_id, record) ->
 			publication.added('rocketchat_starred_message', _id, record)
 
diff --git a/packages/rocketchat-message-star/server/starMessage.coffee b/packages/rocketchat-message-star/server/starMessage.coffee
index 625f0539f910b0eda1deaab5dc90d93605126f86..6df1a37865afece40a3323aa0c9a906034d33e80 100644
--- a/packages/rocketchat-message-star/server/starMessage.coffee
+++ b/packages/rocketchat-message-star/server/starMessage.coffee
@@ -6,6 +6,4 @@ Meteor.methods
 		if not RocketChat.settings.get 'Message_AllowStarring'
 			throw new Meteor.Error 'message-starring-not-allowed', "[methods] starMessage -> Message starring not allowed"
 
-		console.log '[methods] starMessage -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
-
 		RocketChat.models.Messages.updateUserStarById(message._id, Meteor.userId(), message.starred)
diff --git a/packages/rocketchat-oauth2-server-config/.gitignore b/packages/rocketchat-oauth2-server-config/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..677a6fc26373dfaddcf7d4b8a52711f7257e1be5
--- /dev/null
+++ b/packages/rocketchat-oauth2-server-config/.gitignore
@@ -0,0 +1 @@
+.build*
diff --git a/packages/rocketchat-oauth2-server-config/admin/client/collection.coffee b/packages/rocketchat-oauth2-server-config/admin/client/collection.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..4004f7cde99f74da229510eb9a0efb941ed29713
--- /dev/null
+++ b/packages/rocketchat-oauth2-server-config/admin/client/collection.coffee
@@ -0,0 +1 @@
+@ChatOAuthApps = new Meteor.Collection 'rocketchat_oauth_apps'
diff --git a/packages/rocketchat-oauth2-server-config/admin/client/route.coffee b/packages/rocketchat-oauth2-server-config/admin/client/route.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..f2fcc3b836596dea446f0a2906346fada821c5df
--- /dev/null
+++ b/packages/rocketchat-oauth2-server-config/admin/client/route.coffee
@@ -0,0 +1,17 @@
+FlowRouter.route '/admin/oauth-apps',
+	name: 'admin-oauth-apps'
+	action: (params) ->
+		BlazeLayout.render 'main',
+			center: 'pageSettingsContainer'
+			pageTitle: t('OAuth_Applications')
+			pageTemplate: 'oauthApps'
+
+
+FlowRouter.route '/admin/oauth-app/:id?',
+	name: 'admin-oauth-app'
+	action: (params) ->
+		BlazeLayout.render 'main',
+			center: 'pageSettingsContainer'
+			pageTitle: t('OAuth_Application')
+			pageTemplate: 'oauthApp'
+			params: params
diff --git a/packages/rocketchat-oauth2-server-config/admin/client/startup.coffee b/packages/rocketchat-oauth2-server-config/admin/client/startup.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..1619a366a3dd4c85c3c7417e3c8f7e4bb9e947c1
--- /dev/null
+++ b/packages/rocketchat-oauth2-server-config/admin/client/startup.coffee
@@ -0,0 +1,7 @@
+Meteor.subscribe 'oauthApps'
+
+RocketChat.AdminBox.addOption
+	href: 'admin-oauth-apps'
+	i18nLabel: 'OAuth Apps'
+	permissionGranted: ->
+		return RocketChat.authz.hasAllPermission('manage-oauth-apps')
diff --git a/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApp.coffee b/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApp.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..4ced37677bb6857a9cc90107dde8be905b78d1fc
--- /dev/null
+++ b/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApp.coffee
@@ -0,0 +1,79 @@
+Template.oauthApp.onCreated ->
+	@record = new ReactiveVar
+		active: true
+
+
+Template.oauthApp.helpers
+	hasPermission: ->
+		return RocketChat.authz.hasAllPermission 'manage-oauth-apps'
+
+	data: ->
+		params = Template.instance().data.params?()
+
+		if params?.id?
+			data = ChatOAuthApps.findOne({_id: params.id})
+			if data?
+				data.authorization_url = Meteor.absoluteUrl("oauth/authorize")
+				data.access_token_url = Meteor.absoluteUrl("oauth/token")
+
+				Template.instance().record.set data
+				return data
+
+		return Template.instance().record.curValue
+
+
+Template.oauthApp.events
+	"click .submit > .delete": ->
+		params = Template.instance().data.params()
+
+		swal
+			title: t('Are_you_sure')
+			text: t('You_will_not_be_able_to_recover')
+			type: 'warning'
+			showCancelButton: true
+			confirmButtonColor: '#DD6B55'
+			confirmButtonText: t('Yes_delete_it')
+			cancelButtonText: t('Cancel')
+			closeOnConfirm: false
+			html: false
+		, ->
+			Meteor.call "deleteOAuthApp", params.id, (err, data) ->
+				swal
+					title: t('Deleted')
+					text: t('Your_entry_has_been_deleted')
+					type: 'success'
+					timer: 1000
+					showConfirmButton: false
+
+				FlowRouter.go "admin-oauth-apps"
+
+	"click .submit > .save": ->
+		name = $('[name=name]').val().trim()
+		active = $('[name=active]:checked').val().trim() is "1"
+		redirectUri = $('[name=redirectUri]').val().trim()
+
+		if name is ''
+			return toastr.error TAPi18n.__("The_application_name_is_required")
+
+		if redirectUri is ''
+			return toastr.error TAPi18n.__("The_redirectUri_is_required")
+
+		app =
+			name: name
+			active: active
+			redirectUri: redirectUri
+
+		params = Template.instance().data.params?()
+		if params?.id?
+			Meteor.call "updateOAuthApp", params.id, app, (err, data) ->
+				if err?
+					return toastr.error TAPi18n.__(err.error)
+
+				toastr.success TAPi18n.__("Application_updated")
+		else
+			Meteor.call "addOAuthApp", app, (err, data) ->
+				if err?
+					return toastr.error TAPi18n.__(err.error)
+
+				toastr.success TAPi18n.__("Application_added")
+				FlowRouter.go "admin-oauth-app", {id: data._id}
diff --git a/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApp.html b/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApp.html
new file mode 100644
index 0000000000000000000000000000000000000000..d9d722ddd4917d53feaf9ca48f42330c82c2174b
--- /dev/null
+++ b/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApp.html
@@ -0,0 +1,72 @@
+<template name="oauthApp">
+	<div class="permissions-manager">
+		{{#if hasPermission}}
+			<a href="{{pathFor "admin-oauth-apps"}}"><i class="icon-angle-left"></i> {{_ "Back_to_applications"}}</a><br><br>
+			<div class="rocket-form">
+				<div class="section">
+					<div class="section-content">
+						<div class="input-line double-col">
+							<label>{{_ "Active"}}</label>
+							<div>
+								<label><input class="input-monitor" type="radio" name="active" value="1" checked="{{$eq data.active true}}" /> {{_ "True"}}</label>
+								<label><input class="input-monitor" type="radio" name="active" value="0" checked="{{$eq data.active false}}" /> {{_ "False"}}</label>
+							</div>
+						</div>
+						<div class="input-line double-col">
+							<label>{{_ "Application_Name"}}</label>
+							<div>
+								<input type="text" name="name" value="{{data.name}}" />
+								<div class="settings-description">{{_ "Give_the_application_a_name_This_will_be_seen_by_your_users"}}</div>
+							</div>
+						</div>
+						<div class="input-line double-col">
+							<label>{{_ "Redirect_URI"}}</label>
+							<div>
+								<input type="text" name="redirectUri" value="{{data.redirectUri}}" />
+								<div class="settings-description">{{_ "After_OAuth2_authentication_users_will_be_redirected_to_this_URL"}}</div>
+							</div>
+						</div>
+						{{#if data.clientId}}
+							<div class="input-line double-col">
+								<label>{{_ "Client_ID"}}</label>
+								<div>
+									<input type="text" name="clientId" value="{{data.clientId}}" disabled="disabled" />
+									<div class="settings-description"><a href="#" class="clipboard" data-clipboard-target="[name=clientId]">{{_ "COPY_TO_CLIPBOARD"}}</a></div>
+								</div>
+							</div>
+							<div class="input-line double-col">
+								<label>{{_ "Client_Secret"}}</label>
+								<div>
+									<input type="text" name="clientSecret" value="{{data.clientSecret}}" disabled="disabled" />
+									<div class="settings-description"><a href="#" class="clipboard" data-clipboard-target="[name=clientSecret]">{{_ "COPY_TO_CLIPBOARD"}}</a></div>
+								</div>
+							</div>
+							<div class="input-line double-col">
+								<label>{{_ "Authorization_URL"}}</label>
+								<div>
+									<input type="text" name="authorization_url" value="{{data.authorization_url}}" disabled="disabled" />
+									<div class="settings-description"><a href="#" class="clipboard" data-clipboard-target="[name=authorization_url]">{{_ "COPY_TO_CLIPBOARD"}}</a></div>
+								</div>
+							</div>
+							<div class="input-line double-col">
+								<label>{{_ "Access_Token_URL"}}</label>
+								<div>
+									<input type="text" name="access_token_url" value="{{data.access_token_url}}" disabled="disabled" />
+									<div class="settings-description"><a href="#" class="clipboard" data-clipboard-target="[name=access_token_url]">{{_ "COPY_TO_CLIPBOARD"}}</a></div>
+								</div>
+							</div>
+						{{/if}}
+					</div>
+				</div>
+				<div class="submit">
+					{{#if data.clientId}}
+						<button class="button red delete"><i class="icon-trash"></i><span>{{_ "Delete"}}</span></button>
+					{{/if}}
+					<button class="button save"><i class="icon-send"></i><span>{{_ "Save_changes"}}</span></button>
+				</div>
+			</div>
+		{{else}}
+			{{_ "Not_authorized"}}
+		{{/if}}
+	</div>
+</template>
diff --git a/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApps.coffee b/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApps.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..0dca6796b28d1a74743a4a7c2ee863278698dcbf
--- /dev/null
+++ b/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApps.coffee
@@ -0,0 +1,9 @@
+Template.oauthApps.helpers
+	hasPermission: ->
+		return RocketChat.authz.hasAllPermission 'manage-oauth-apps'
+
+	applications: ->
+		return ChatOAuthApps.find()
+
+	dateFormated: (date) ->
+		return moment(date).format('L LT')
diff --git a/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApps.html b/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApps.html
new file mode 100644
index 0000000000000000000000000000000000000000..f0dc3df3364aa0a9291c95d78239ad40c1d08d25
--- /dev/null
+++ b/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApps.html
@@ -0,0 +1,33 @@
+<template name="oauthApps">
+	<div class="permissions-manager">
+		{{#if hasPermission}}
+			<a href="{{pathFor "admin-oauth-app"}}" class="button primary new-role">{{_ "New_Application"}}</a>
+
+			<div class="rocket-form">
+				<div class="section">
+					<div class="admin-integrations-new-panel">
+						{{#each applications}}
+							<a href="{{pathFor "admin-oauth-app" id=_id}}">
+								<div class="admin-integrations-new-item">
+									<div class="admin-integrations-new-item-body">
+										<div class="admin-integrations-new-item-title">
+											{{name}}
+										</div>
+										<div class="admin-integrations-new-item-description">
+											{{{_ "Created_at_s_by_s" (dateFormated _createdAt) _createdBy.username}}}
+										</div>
+									</div>
+									<i class="icon-angle-right"></i>
+								</div>
+							</a>
+						{{else}}
+							<h1>{{_ "There_are_no_applications"}}</h1>
+						{{/each}}
+					</div>
+				</div>
+			</div>
+		{{else}}
+			{{_ "Not_authorized"}}
+		{{/if}}
+	</div>
+</template>
diff --git a/packages/rocketchat-oauth2-server-config/admin/server/methods/addOAuthApp.coffee b/packages/rocketchat-oauth2-server-config/admin/server/methods/addOAuthApp.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..21e189664dc64073a013c4ba2f34a0bffe6a9c72
--- /dev/null
+++ b/packages/rocketchat-oauth2-server-config/admin/server/methods/addOAuthApp.coffee
@@ -0,0 +1,28 @@
+Meteor.methods
+	addOAuthApp: (application) ->
+		if not RocketChat.authz.hasPermission @userId, 'manage-oauth-apps'
+			throw new Meteor.Error 'not_authorized'
+
+		if not _.isString(application.name)
+			throw new Meteor.Error 'invalid_name', '[methods] addOAuthApp -> name must be string'
+
+		if application.name.trim() is ''
+			throw new Meteor.Error 'invalid_name', '[methods] addOAuthApp -> name can\'t be empty'
+
+		if not _.isString(application.redirectUri)
+			throw new Meteor.Error 'invalid_redirectUri', '[methods] addOAuthApp -> redirectUri must be string'
+
+		if application.redirectUri.trim() is ''
+			throw new Meteor.Error 'invalid_redirectUri', '[methods] addOAuthApp -> redirectUri can\'t be empty'
+
+		if not _.isBoolean(application.active)
+			throw new Meteor.Error 'invalid_active', '[methods] addOAuthApp -> active must be boolean'
+
+		application.clientId = Random.id()
+		application.clientSecret = Random.secret()
+		application._createdAt = new Date
+		application._createdBy = RocketChat.models.Users.findOne @userId, {fields: {username: 1}}
+
+		application._id = RocketChat.models.OAuthApps.insert application
+
+		return application
diff --git a/packages/rocketchat-oauth2-server-config/admin/server/methods/deleteOAuthApp.coffee b/packages/rocketchat-oauth2-server-config/admin/server/methods/deleteOAuthApp.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..704dfed09c5ffd4a77df7febdc4db62c2bffabdd
--- /dev/null
+++ b/packages/rocketchat-oauth2-server-config/admin/server/methods/deleteOAuthApp.coffee
@@ -0,0 +1,13 @@
+Meteor.methods
+	deleteOAuthApp: (applicationId) ->
+		if not RocketChat.authz.hasPermission @userId, 'manage-oauth-apps'
+			throw new Meteor.Error 'not_authorized'
+
+		application = RocketChat.models.OAuthApps.findOne(applicationId)
+
+		if not application?
+			throw new Meteor.Error 'invalid_application', '[methods] deleteOAuthApp -> application not found'
+
+		RocketChat.models.OAuthApps.remove _id: applicationId
+
+		return true
diff --git a/packages/rocketchat-oauth2-server-config/admin/server/methods/updateOAuthApp.coffee b/packages/rocketchat-oauth2-server-config/admin/server/methods/updateOAuthApp.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..e50cbf1161104b80fefb23db0ed376b62c32e649
--- /dev/null
+++ b/packages/rocketchat-oauth2-server-config/admin/server/methods/updateOAuthApp.coffee
@@ -0,0 +1,33 @@
+Meteor.methods
+	updateOAuthApp: (applicationId, application) ->
+		if not RocketChat.authz.hasPermission @userId, 'manage-oauth-apps'
+			throw new Meteor.Error 'not_authorized'
+
+		if not _.isString(application.name)
+			throw new Meteor.Error 'invalid_name', '[methods] updateOAuthApp -> name must be string'
+
+		if application.name.trim() is ''
+			throw new Meteor.Error 'invalid_name', '[methods] updateOAuthApp -> name can\'t be empty'
+
+		if not _.isString(application.redirectUri)
+			throw new Meteor.Error 'invalid_redirectUri', '[methods] updateOAuthApp -> redirectUri must be string'
+
+		if application.redirectUri.trim() is ''
+			throw new Meteor.Error 'invalid_redirectUri', '[methods] updateOAuthApp -> redirectUri can\'t be empty'
+
+		if not _.isBoolean(application.active)
+			throw new Meteor.Error 'invalid_active', '[methods] updateOAuthApp -> active must be boolean'
+
+		currentApplication = RocketChat.models.OAuthApps.findOne(applicationId)
+		if not currentApplication?
+			throw new Meteor.Error 'invalid_application', '[methods] updateOAuthApp -> application not found'
+
+		RocketChat.models.OAuthApps.update applicationId,
+			$set:
+				name: application.name
+				active: application.active
+				redirectUri: application.redirectUri
+				_updatedAt: new Date
+				_updatedBy: RocketChat.models.Users.findOne @userId, {fields: {username: 1}}
+
+		return RocketChat.models.OAuthApps.findOne(applicationId)
diff --git a/packages/rocketchat-oauth2-server-config/admin/server/publications/oauthApps.coffee b/packages/rocketchat-oauth2-server-config/admin/server/publications/oauthApps.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..d29a5cbdcdbe69884614bd6e177926525c9cceac
--- /dev/null
+++ b/packages/rocketchat-oauth2-server-config/admin/server/publications/oauthApps.coffee
@@ -0,0 +1,8 @@
+Meteor.publish 'oauthApps', ->
+	unless @userId
+		return @ready()
+
+	if not RocketChat.authz.hasPermission @userId, 'manage-oauth-apps'
+		throw new Meteor.Error "not-authorized"
+
+	return RocketChat.models.OAuthApps.find()
diff --git a/packages/rocketchat-oauth2-server-config/oauth/client/oauth2-client.coffee b/packages/rocketchat-oauth2-server-config/oauth/client/oauth2-client.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..c2acdd899d11a13db46046ecadea9d11e61d588b
--- /dev/null
+++ b/packages/rocketchat-oauth2-server-config/oauth/client/oauth2-client.coffee
@@ -0,0 +1,47 @@
+# @ChatOAuthApps = new Meteor.Collection 'rocketchat_oauth_apps'
+
+FlowRouter.route '/oauth/authorize',
+	action: (params, queryParams) ->
+		BlazeLayout.render 'main',
+			center: 'authorize'
+			modal: true
+			client_id: queryParams.client_id
+			redirect_uri: queryParams.redirect_uri
+			response_type: queryParams.response_type
+			state: queryParams.state
+
+
+FlowRouter.route '/oauth/error/:error',
+	action: (params, queryParams) ->
+		BlazeLayout.render 'main',
+			center: 'oauth404'
+			modal: true
+			error: params.error
+
+
+Template.authorize.onCreated ->
+	@subscribe 'authorizedOAuth'
+	@subscribe 'oauthClient', @data.client_id()
+
+
+Template.authorize.helpers
+	getToken: ->
+		return localStorage.getItem('Meteor.loginToken')
+
+	getClient: ->
+		return ChatOAuthApps.findOne()
+
+
+Template.authorize.events
+	'click #logout-oauth': ->
+		return Meteor.logout()
+
+	'click #cancel-oauth': ->
+		return window.close()
+
+
+Template.authorize.onRendered ->
+	@autorun (c) =>
+		if Meteor.user()?.oauth?.athorizedClients?.indexOf(@data.client_id()) > -1
+			c.stop()
+			$('button').click()
diff --git a/packages/rocketchat-oauth2-server-config/oauth/client/oauth2-client.html b/packages/rocketchat-oauth2-server-config/oauth/client/oauth2-client.html
new file mode 100644
index 0000000000000000000000000000000000000000..ce886eca1ff9fd581d58375814076ac0bbd4fea7
--- /dev/null
+++ b/packages/rocketchat-oauth2-server-config/oauth/client/oauth2-client.html
@@ -0,0 +1,59 @@
+<template name="authorize">
+	{{#if currentUser}}
+		<div class="oauth-panel">
+			<form method="post" action="" role="form" class="{{#unless Template.subscriptionsReady}}hidden{{/unless}}">
+				{{#if currentUser}}
+					<div class="user-info">
+						<div class="thumb">
+							{{> avatar username=currentUser.username}}
+						</div>
+						<div class="username">
+							{{_ "You_are_logged_in_as"}}
+							<h1>{{currentUser.username}}</h1>
+						</div>
+					</div>
+				{{/if}}
+
+				<div class="integration-info">
+					<div>
+						<span><b>{{getClient.name}}</b> {{_ "will_be_able_to"}}</span>
+						<ul class="integration-permissions">
+							<li>Post Messages</li>
+							<li>Create Channels</li>
+							<li>Change Chennel Topic</li>
+						</ul>
+					</div>
+				</div>
+				<input type="hidden" name="allow" value="yes">
+				<input type="hidden" name="token" value="{{getToken}}">
+				<input type="hidden" name="client_id" value="{{client_id}}">
+				<input type="hidden" name="redirect_uri" value="{{redirect_uri}}">
+				<input type="hidden" name="response_type" value="code">
+				<div class="buttons">
+					<a id="logout-oauth" href="" class="button secondary">{{_ "Logout"}}</a>
+					<div class="horizontal-space"></div>
+					<button id="cancel-oauth" type="button" class="button secondary">{{_ "Cancel"}}</button>
+					<button type="submit" class="button">{{_ "Authorize"}}</button>
+				</div>
+			</form>
+			{{#unless Template.subscriptionsReady}}
+				{{_ "loading"}}...
+			{{/unless}}
+		</div>
+	{{else}}
+		{{> loginButtons}}
+	{{/if}}
+</template>
+
+<template name="oauth404">
+		<div class="oauth-panel">
+			<form>
+				{{#if $eq error '404'}}
+					<h2>Invalid OAuth client</h2>
+				{{/if}}
+				{{#if $eq error 'invalid_redirect_uri'}}
+					<h2>Redirect URL does not match</h2>
+				{{/if}}
+			</form>
+		</div>
+</template>
diff --git a/packages/rocketchat-oauth2-server-config/oauth/client/stylesheets/load.coffee b/packages/rocketchat-oauth2-server-config/oauth/client/stylesheets/load.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..631ef382a4e69a8a6ebda08537da49d86e9d3f1e
--- /dev/null
+++ b/packages/rocketchat-oauth2-server-config/oauth/client/stylesheets/load.coffee
@@ -0,0 +1,2 @@
+RocketChat.theme.addPackageAsset ->
+	return Assets.getText 'oauth/client/stylesheets/oauth2.less'
diff --git a/packages/rocketchat-oauth2-server-config/oauth/client/stylesheets/oauth2.less b/packages/rocketchat-oauth2-server-config/oauth/client/stylesheets/oauth2.less
new file mode 100644
index 0000000000000000000000000000000000000000..e83fecf16ffdd0e13633cfebcc82631ffe68222a
--- /dev/null
+++ b/packages/rocketchat-oauth2-server-config/oauth/client/stylesheets/oauth2.less
@@ -0,0 +1,72 @@
+.oauth-panel {
+	position: absolute;
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	justify-content: center;
+	left: 0px;
+	right: 0px;
+	top: 0px;
+	bottom: 0px;
+
+	ul, li, ol {
+		list-style: initial;
+	}
+
+	ul {
+		padding-left: 10px;
+		margin-left: 6px;
+	}
+
+	form {
+		min-width: 400px;
+		padding: 40px;
+	}
+
+	.user-info {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		padding-bottom: 20px;
+		margin-bottom: 20px;
+		border-bottom: 1px solid #eee;
+
+		.thumb {
+			height: 40px;
+			width: 40px;
+			margin-right: 10px;
+		}
+
+		.username {
+			text-align: left;
+			h1 {
+				font-size: 18px;
+			}
+		}
+	}
+
+	.integration-info {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+
+		.integration-permissions {
+			margin-left: 16px;
+			padding-top: 10px;
+			padding-bottom: 40px;
+		}
+	}
+
+	.buttons {
+		display: flex;
+		align-items: center;
+		justify-content: center;
+
+		.horizontal-space {
+			border-right: 1px solid #ddd;
+			height: 14px;
+			margin: 0 15px;
+		}
+	}
+}
diff --git a/packages/rocketchat-oauth2-server-config/oauth/server/default-services.coffee b/packages/rocketchat-oauth2-server-config/oauth/server/default-services.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..41fee6a9a863d9a6a10a50f5f030d7ec8a011ecc
--- /dev/null
+++ b/packages/rocketchat-oauth2-server-config/oauth/server/default-services.coffee
@@ -0,0 +1,12 @@
+if not RocketChat.models.OAuthApps.findOne('zapier')
+	RocketChat.models.OAuthApps.insert
+		_id: 'zapier'
+		name: 'Zapier'
+		active: false
+		clientId: 'zapier'
+		clientSecret: 'RTK6TlndaCIolhQhZ7_KHIGOKj41RnlaOq_o-7JKwLr'
+		redirectUri: 'https://zapier.com/dashboard/auth/oauth/return/AppIDAPI/'
+		_createdAt: new Date
+		_createdBy:
+			_id: 'system'
+			username: 'system'
diff --git a/packages/rocketchat-oauth2-server-config/oauth/server/oauth2-server.coffee b/packages/rocketchat-oauth2-server-config/oauth/server/oauth2-server.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..7fb13851d207d457ac81e855367766151d698c18
--- /dev/null
+++ b/packages/rocketchat-oauth2-server-config/oauth/server/oauth2-server.coffee
@@ -0,0 +1,58 @@
+oauth2server = new OAuth2Server
+	accessTokensCollectionName: 'rocketchat_oauth_access_tokens'
+	refreshTokensCollectionName: 'rocketchat_oauth_refresh_tokens'
+	authCodesCollectionName: 'rocketchat_oauth_auth_codes'
+	clientsCollection: RocketChat.models.OAuthApps.model
+	debug: true
+
+
+WebApp.connectHandlers.use oauth2server.app
+
+
+Meteor.publish 'oauthClient', (clientId) ->
+	unless @userId
+		return @ready()
+
+	return RocketChat.models.OAuthApps.find {clientId: clientId, active: true},
+		fields:
+			name: 1
+
+
+RocketChat.API.v1.addAuthMethod ->
+	console.log @request.method, @request.url
+
+	headerToken = @request.headers['authorization']
+	getToken = @request.query.access_token
+
+	if headerToken?
+		if matches = headerToken.match(/Bearer\s(\S+)/)
+			headerToken = matches[1]
+		else
+			headerToken = undefined
+
+	bearerToken = headerToken or getToken
+
+	if not bearerToken?
+		# console.log 'token not found'.red
+		return
+
+	# console.log 'bearerToken', bearerToken
+
+	getAccessToken = Meteor.wrapAsync oauth2server.oauth.model.getAccessToken, oauth2server.oauth.model
+	accessToken = getAccessToken bearerToken
+
+	if not accessToken?
+		# console.log 'accessToken not found'.red
+		return
+
+	if accessToken.expires? and accessToken.expires isnt 0 and accessToken.expires < new Date()
+		# console.log 'accessToken expired'.red
+		return
+
+	user = RocketChat.models.Users.findOne(accessToken.userId)
+	if not user?
+		# console.log 'user not found'.red
+		return
+
+	return user: user
+
diff --git a/packages/rocketchat-oauth2-server-config/package.js b/packages/rocketchat-oauth2-server-config/package.js
new file mode 100644
index 0000000000000000000000000000000000000000..3d7b2f10c2a0dc41918547c3a5b3dbee4a473422
--- /dev/null
+++ b/packages/rocketchat-oauth2-server-config/package.js
@@ -0,0 +1,52 @@
+Package.describe({
+	name: 'rocketchat:oauth2-server-config',
+	summary: "Configure the OAuth2 Server",
+	version: "1.0.0"
+});
+
+Package.onUse(function(api) {
+	api.versionsFrom('1.0');
+
+	api.use('webapp');
+	api.use('coffeescript');
+	api.use('rocketchat:lib');
+	api.use('rocketchat:api');
+	api.use('rocketchat:theme');
+	api.use('rocketchat:oauth2-server');
+
+	api.use('templating', 'client');
+	api.use('kadira:flow-router', 'client');
+
+	//// General //
+	// Server
+	api.addFiles('server/models/OAuthApps.coffee', 'server');
+
+	//// OAuth //
+	// Server
+	api.addFiles('oauth/server/oauth2-server.coffee', 'server');
+	api.addFiles('oauth/server/default-services.coffee', 'server');
+
+	api.addAssets('oauth/client/stylesheets/oauth2.less', 'server');
+	api.addFiles('oauth/client/stylesheets/load.coffee', 'server');
+
+	// Client
+	api.addFiles('oauth/client/oauth2-client.html', 'client');
+	api.addFiles('oauth/client/oauth2-client.coffee', 'client');
+
+
+	//// Admin //
+	// Client
+	api.addFiles('admin/client/startup.coffee', 'client');
+	api.addFiles('admin/client/collection.coffee', 'client');
+	api.addFiles('admin/client/route.coffee', 'client');
+	api.addFiles('admin/client/views/oauthApp.html', 'client');
+	api.addFiles('admin/client/views/oauthApp.coffee', 'client');
+	api.addFiles('admin/client/views/oauthApps.html', 'client');
+	api.addFiles('admin/client/views/oauthApps.coffee', 'client');
+
+	// Server
+	api.addFiles('admin/server/publications/oauthApps.coffee', 'server');
+	api.addFiles('admin/server/methods/addOAuthApp.coffee', 'server');
+	api.addFiles('admin/server/methods/updateOAuthApp.coffee', 'server');
+	api.addFiles('admin/server/methods/deleteOAuthApp.coffee', 'server');
+});
diff --git a/packages/rocketchat-oauth2-server-config/server/models/OAuthApps.coffee b/packages/rocketchat-oauth2-server-config/server/models/OAuthApps.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..5f95a6c2d32e08ac297fffb2c4ffec08b0f724e3
--- /dev/null
+++ b/packages/rocketchat-oauth2-server-config/server/models/OAuthApps.coffee
@@ -0,0 +1,13 @@
+RocketChat.models.OAuthApps = new class extends RocketChat.models._Base
+	constructor: ->
+		@_initModel 'oauth_apps'
+
+
+	# FIND
+	# findByRole: (role, options) ->
+	# 	query =
+	# 		roles: role
+
+	# 	return @find query, options
+
+	# CREATE
diff --git a/packages/rocketchat-oembed/client/oembedImageWidget.html b/packages/rocketchat-oembed/client/oembedImageWidget.html
index 8d277d965021b748772a69de89b8a9728eb3b1c1..144dd7665215be92aefe9b16c2d9d8c8584e22a8 100644
--- a/packages/rocketchat-oembed/client/oembedImageWidget.html
+++ b/packages/rocketchat-oembed/client/oembedImageWidget.html
@@ -3,8 +3,8 @@
 		{{#if parsedUrl}}
 			<div>
 				<a href="{{url}}" class="swipebox" target="_blank">
-					<div class="inline-image" style="background-image: url({{url}});">
-						<img src="{{url}}">
+					<div class="inline-image" style="background-image: url('{{url}}');">
+						<img src="{{url}}" height="200">
 					</div>
 				</a>
 			</div>
diff --git a/packages/rocketchat-oembed/client/oembedUrlWidget.coffee b/packages/rocketchat-oembed/client/oembedUrlWidget.coffee
index 3193a2df5a940d87961ef2427cb0680eb39b7744..79e6127073a67dd71a58a5f09e3d1d584d2cde58 100644
--- a/packages/rocketchat-oembed/client/oembedUrlWidget.coffee
+++ b/packages/rocketchat-oembed/client/oembedUrlWidget.coffee
@@ -26,7 +26,7 @@ Template.oembedUrlWidget.helpers
 		if not this.meta?
 			return
 
-		decodedOgImage = @meta.ogImage.replace(/&amp;/g, '&')
+		decodedOgImage = @meta.ogImage?.replace?(/&amp;/g, '&')
 
 		return decodedOgImage or this.meta.twitterImage
 
diff --git a/packages/rocketchat-oembed/client/oembedUrlWidget.html b/packages/rocketchat-oembed/client/oembedUrlWidget.html
index 56115decb6de4433bf5da104cd478cf152e3ceaf..9d749d7f6c8ef71b4ab661b4a3ed146d44d53dcb 100644
--- a/packages/rocketchat-oembed/client/oembedUrlWidget.html
+++ b/packages/rocketchat-oembed/client/oembedUrlWidget.html
@@ -1,7 +1,7 @@
 <template name="oembedUrlWidget">
 	{{#if show}}
 		<blockquote>
-			<div style="{{#if image}}min-height: 60px;{{/if}} padding: 10px 3px;">
+			<div style="{{#if image}}min-height: 80px;{{/if}} padding: 10px 3px;">
 				{{#if image}}
 					{{#if meta.ogImageUserGenerated}}
 						<div>
@@ -25,4 +25,4 @@
 			</div>
 		</blockquote>
 	{{/if}}
-</template>
\ No newline at end of file
+</template>
diff --git a/packages/rocketchat-oembed/package.js b/packages/rocketchat-oembed/package.js
index ace7d0496be20df1c7ef2e5d2f55f0321ede8563..3bb4babd591ad8f0e05629ff44d33d64e9df5e64 100644
--- a/packages/rocketchat-oembed/package.js
+++ b/packages/rocketchat-oembed/package.js
@@ -13,7 +13,7 @@ Package.onUse(function(api) {
 		'coffeescript',
 		'underscore',
 		'konecty:change-case',
-		'rocketchat:lib@0.0.1'
+		'rocketchat:lib'
 	]);
 
 	api.addFiles('client/baseWidget.html', 'client');
diff --git a/packages/rocketchat-oembed/server/server.coffee b/packages/rocketchat-oembed/server/server.coffee
index 7696e42b7705aca64c89934999f8710ce13e573c..95266e478ab99cfea1bf8b1f514d73e4a918f72c 100644
--- a/packages/rocketchat-oembed/server/server.coffee
+++ b/packages/rocketchat-oembed/server/server.coffee
@@ -103,7 +103,7 @@ OEmbed.getUrlMeta = (url, withFragment) ->
 
 	if content?.body?
 		metas = {}
-		content.body.replace /<title>(.+)<\/title>/gmi, (meta, title) ->
+		content.body.replace /<title>((.|\n)+?)<\/title>/gmi, (meta, title) ->
 			metas.pageTitle = title
 
 		content.body.replace /<meta[^>]*(?:name|property)=[']([^']*)['][^>]*content=[']([^']*)['][^>]*>/gmi, (meta, name, value) ->
diff --git a/packages/rocketchat-sharedsecret/package.js b/packages/rocketchat-sharedsecret/package.js
index 4371ff0846a000412e12de5f5a74756f7ead1159..d0547036c7adf12f6339c755d59ece2acedf5cef 100644
--- a/packages/rocketchat-sharedsecret/package.js
+++ b/packages/rocketchat-sharedsecret/package.js
@@ -10,7 +10,7 @@ Package.onUse(function(api) {
 
 	api.use([
 		'coffeescript',
-		'rocketchat:lib@0.0.1'
+		'rocketchat:lib'
 	]);
 
 	api.use(['jparker:crypto-aes'], ['server','client']);
diff --git a/packages/rocketchat-slashcommands-invite/i18n/ar.i18n.json b/packages/rocketchat-slashcommands-invite/i18n/ar.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..6912464b1a1168f158a9b4e5d05619bf27ae679d 100644
--- a/packages/rocketchat-slashcommands-invite/i18n/ar.i18n.json
+++ b/packages/rocketchat-slashcommands-invite/i18n/ar.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "User_doesnt_exist" : "لا يوجد مستخدم بالاسم `@%s`"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-invite/i18n/de.i18n.json b/packages/rocketchat-slashcommands-invite/i18n/de.i18n.json
index 7ed315a21cd419d186de385f01172f6c80285b0d..03bf1dcfbe890b85cb18a8af8290a84047bc032b 100644
--- a/packages/rocketchat-slashcommands-invite/i18n/de.i18n.json
+++ b/packages/rocketchat-slashcommands-invite/i18n/de.i18n.json
@@ -1,5 +1,5 @@
 {
-  "Invite_user_to_join_channel" : "Lade einen Benutzer in diesen Kanal ein",
-  "User_doesnt_exist" : "Kein Benutzer vorhanden mit dem Namen `@% s`.",
-  "Username_is_already_in_here" : "`@% s` ist bereits da"
+  "Invite_user_to_join_channel" : "Benutzer in diesen Kanal einladen",
+  "User_doesnt_exist" : "Kein Benutzer mit dem Namen `@% s` vorhanden.",
+  "Username_is_already_in_here" : "`@%s` wurde bereits hinzugefügt."
 }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-invite/i18n/hr.i18n.json b/packages/rocketchat-slashcommands-invite/i18n/hr.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..6e8a0bf75bcb1c7d5236d51be12807440b283712 100644
--- a/packages/rocketchat-slashcommands-invite/i18n/hr.i18n.json
+++ b/packages/rocketchat-slashcommands-invite/i18n/hr.i18n.json
@@ -1 +1,5 @@
-{ }
\ No newline at end of file
+{
+  "Invite_user_to_join_channel" : "Pozovi jednog korisnika da se pridruži ovom kanalu",
+  "User_doesnt_exist" : "Ne postoji korisnik pod imenom `@% s`.",
+  "Username_is_already_in_here" : "`@% s` je već ovdje."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-invite/i18n/ko.i18n.json b/packages/rocketchat-slashcommands-invite/i18n/ko.i18n.json
index 79dc107036c67bb7bd7b13201f3abd4dcd25f112..784fb685f16bf4e151e1bd4c1c387e93010e21fd 100644
--- a/packages/rocketchat-slashcommands-invite/i18n/ko.i18n.json
+++ b/packages/rocketchat-slashcommands-invite/i18n/ko.i18n.json
@@ -1,4 +1,5 @@
 {
+  "Invite_user_to_join_channel" : "이 채널로 초대한 사용자 참여",
   "User_doesnt_exist" : "`@%s` 사용자가 존재하지 않습니다.",
   "Username_is_already_in_here" : "`@%s` 사용자가 이미 있습니다."
 }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-invite/i18n/nl.i18n.json b/packages/rocketchat-slashcommands-invite/i18n/nl.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..35a6d518000af37fb6f8a8da1c78e7b0e970c01b 100644
--- a/packages/rocketchat-slashcommands-invite/i18n/nl.i18n.json
+++ b/packages/rocketchat-slashcommands-invite/i18n/nl.i18n.json
@@ -1 +1,5 @@
-{ }
\ No newline at end of file
+{
+  "Invite_user_to_join_channel" : "Nodig een gebruiker uit voor om dit kanaal",
+  "User_doesnt_exist" : "Geen gebruiker bestaat met de naam `@%s`.",
+  "Username_is_already_in_here" : "`@%s` is al hier."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-invite/i18n/ro.i18n.json b/packages/rocketchat-slashcommands-invite/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..ce218ea20e43320fc7885615bc8a90f810efe839
--- /dev/null
+++ b/packages/rocketchat-slashcommands-invite/i18n/ro.i18n.json
@@ -0,0 +1,5 @@
+{
+  "Invite_user_to_join_channel" : "Invitați un utilizator să se alăture acestui canal",
+  "User_doesnt_exist" : "Nu există nici un utilizator cu numele de `@%s`.",
+  "Username_is_already_in_here" : "`@% s` este deja aici."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-invite/i18n/ru.i18n.json b/packages/rocketchat-slashcommands-invite/i18n/ru.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..dba0f28979984872e132710c157b46902d0466ba 100644
--- a/packages/rocketchat-slashcommands-invite/i18n/ru.i18n.json
+++ b/packages/rocketchat-slashcommands-invite/i18n/ru.i18n.json
@@ -1 +1,5 @@
-{ }
\ No newline at end of file
+{
+  "Invite_user_to_join_channel" : "Пригласить пользователя присоединиться к этому публичному чату",
+  "User_doesnt_exist" : "Пользователя с логином `@%s` не существует.",
+  "Username_is_already_in_here" : "`@%s` уже здесь."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-invite/i18n/sr.i18n.json b/packages/rocketchat-slashcommands-invite/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-invite/i18n/sr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-invite/package.js b/packages/rocketchat-slashcommands-invite/package.js
index a73b9e87f4ea07a78a1390bc96b405f843b3f944..1f78c040243a8c13a302add086dd770da5479743 100644
--- a/packages/rocketchat-slashcommands-invite/package.js
+++ b/packages/rocketchat-slashcommands-invite/package.js
@@ -12,7 +12,7 @@ Package.onUse(function(api) {
 	api.use([
 		'coffeescript',
 		'check',
-		'rocketchat:lib@0.0.1'
+		'rocketchat:lib'
 	]);
 
 	api.addFiles('client.coffee', 'client');
@@ -27,9 +27,8 @@ Package.onUse(function(api) {
 			return 'i18n/' + filename;
 		}
 	}));
-	api.use('tap:i18n@1.6.1', ['client', 'server']);
-	api.imply('tap:i18n');
-	api.addFiles(tapi18nFiles, ['client', 'server']);
+	api.use('tap:i18n');
+	api.addFiles(tapi18nFiles);
 });
 
 Package.onTest(function(api) {
diff --git a/packages/rocketchat-slashcommands-invite/server.coffee b/packages/rocketchat-slashcommands-invite/server.coffee
index 36ae07981e531db2820d57d26ab6ce1386dfbf03..4b619023139d4bff982f2de3e8cf20d23a9e6ffe 100644
--- a/packages/rocketchat-slashcommands-invite/server.coffee
+++ b/packages/rocketchat-slashcommands-invite/server.coffee
@@ -37,8 +37,9 @@ class Invite
 			}
 			return
 
-		Meteor.runAsUser user._id, ->
-			Meteor.call 'joinRoom', item.rid
+		Meteor.call 'addUserToRoom',
+			rid: item.rid
+			username: user.username
 
 
 RocketChat.slashCommands.add 'invite', Invite
diff --git a/packages/rocketchat-slashcommands-join/i18n/ar.i18n.json b/packages/rocketchat-slashcommands-join/i18n/ar.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..6f532cbd1fb22059e1d7da40fe400ae4a16addff 100644
--- a/packages/rocketchat-slashcommands-join/i18n/ar.i18n.json
+++ b/packages/rocketchat-slashcommands-join/i18n/ar.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Channel_doesnt_exist" : "القناة '#%s' غير موجودة."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-join/i18n/de.i18n.json b/packages/rocketchat-slashcommands-join/i18n/de.i18n.json
index ad6c15152faecf30e80538da4e5fd05b2562740c..af31e778a80815908adb9365ec32bdc3b06d4ecf 100644
--- a/packages/rocketchat-slashcommands-join/i18n/de.i18n.json
+++ b/packages/rocketchat-slashcommands-join/i18n/de.i18n.json
@@ -1,4 +1,4 @@
 {
   "Channel_doesnt_exist" : "Der Kanal `#% s` existiert nicht.",
-  "Join_the_given_channel" : "Trete dem vorgeschlagenen Kanal bei"
+  "Join_the_given_channel" : "Angegebenen Kanal beitreten"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-join/i18n/fr.i18n.json b/packages/rocketchat-slashcommands-join/i18n/fr.i18n.json
index 9565cca54e7dec08cabd9ccb6203684ea054419a..900f6a3c2c9b51d18a84eb5d6bddca6a8b412587 100644
--- a/packages/rocketchat-slashcommands-join/i18n/fr.i18n.json
+++ b/packages/rocketchat-slashcommands-join/i18n/fr.i18n.json
@@ -1,3 +1,4 @@
 {
-  "Channel_doesnt_exist" : "Le canal `#%s` n'existe pas."
+  "Channel_doesnt_exist" : "Le canal `#%s` n'existe pas.",
+  "Join_the_given_channel" : "Rejoindre le canal donné"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-join/i18n/hr.i18n.json b/packages/rocketchat-slashcommands-join/i18n/hr.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..709ab51b4ada2fb94ca6907995a950f1d5341d37 100644
--- a/packages/rocketchat-slashcommands-join/i18n/hr.i18n.json
+++ b/packages/rocketchat-slashcommands-join/i18n/hr.i18n.json
@@ -1 +1,3 @@
-{ }
\ No newline at end of file
+{
+  "Channel_doesnt_exist" : "Kanal `#% s` ne postoji."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-join/i18n/ko.i18n.json b/packages/rocketchat-slashcommands-join/i18n/ko.i18n.json
index 061624dfd786bbb2cc72fa39cf43217d94449eaa..08976fe9f190d36731c5dac5afaa375ac495bbcf 100644
--- a/packages/rocketchat-slashcommands-join/i18n/ko.i18n.json
+++ b/packages/rocketchat-slashcommands-join/i18n/ko.i18n.json
@@ -1,3 +1,4 @@
 {
-  "Channel_doesnt_exist" : "`#%s` 채널이 존재하지 않습니다."
+  "Channel_doesnt_exist" : "`#%s` 채널이 존재하지 않습니다.",
+  "Join_the_given_channel" : "지정한 채널에 참여"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-join/i18n/nl.i18n.json b/packages/rocketchat-slashcommands-join/i18n/nl.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..0c0dd584e3cf747d9025fec91082232474d3d402 100644
--- a/packages/rocketchat-slashcommands-join/i18n/nl.i18n.json
+++ b/packages/rocketchat-slashcommands-join/i18n/nl.i18n.json
@@ -1 +1,4 @@
-{ }
\ No newline at end of file
+{
+  "Channel_doesnt_exist" : "Het kanaal `#%s` bestaat niet.",
+  "Join_the_given_channel" : "Word lid van de gegeven kanaal"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-join/i18n/ro.i18n.json b/packages/rocketchat-slashcommands-join/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..e6d2e68d62859d536e62289e38b3d4818cf39391
--- /dev/null
+++ b/packages/rocketchat-slashcommands-join/i18n/ro.i18n.json
@@ -0,0 +1,4 @@
+{
+  "Channel_doesnt_exist" : "Canalul `#%s` nu există.",
+  "Join_the_given_channel" : "Intrați pe canalul specificat"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-join/i18n/ru.i18n.json b/packages/rocketchat-slashcommands-join/i18n/ru.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..aaaaf72ef992a556ce4cc8e94b499c38ba5d5e67 100644
--- a/packages/rocketchat-slashcommands-join/i18n/ru.i18n.json
+++ b/packages/rocketchat-slashcommands-join/i18n/ru.i18n.json
@@ -1 +1,4 @@
-{ }
\ No newline at end of file
+{
+  "Channel_doesnt_exist" : "Чат `#%s` не существует.",
+  "Join_the_given_channel" : "Присоединиться к заданному публичному чату"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-join/i18n/sr.i18n.json b/packages/rocketchat-slashcommands-join/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-join/i18n/sr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-join/package.js b/packages/rocketchat-slashcommands-join/package.js
index 04690ded85c9a5189bc54e0e8c1aa53f9399fc95..08f72676382888131e64d05051850b97b64d4202 100644
--- a/packages/rocketchat-slashcommands-join/package.js
+++ b/packages/rocketchat-slashcommands-join/package.js
@@ -12,7 +12,7 @@ Package.onUse(function(api) {
 	api.use([
 		'coffeescript',
 		'check',
-		'rocketchat:lib@0.0.1'
+		'rocketchat:lib'
 	]);
 
 	api.addFiles('client.coffee', 'client');
@@ -27,9 +27,8 @@ Package.onUse(function(api) {
 			return 'i18n/' + filename;
 		}
 	}));
-	api.use('tap:i18n@1.6.1', ['client', 'server']);
-	api.imply('tap:i18n');
-	api.addFiles(tapi18nFiles, ['client', 'server']);
+	api.use('tap:i18n');
+	api.addFiles(tapi18nFiles);
 });
 
 Package.onTest(function(api) {
diff --git a/packages/rocketchat-slashcommands-kick/client.coffee b/packages/rocketchat-slashcommands-kick/client.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..acc40d33db03fc7e81cac9cf9e55487c96e3159b
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/client.coffee
@@ -0,0 +1,11 @@
+RocketChat.slashCommands.add 'kick', (command, params, item) ->
+	username = params.trim()
+	if username is ''
+		return
+	username = username.replace('@', '')
+
+	if Session.get('showUserInfo') is username
+		Session.set('showUserInfo', null)
+,
+	description: TAPi18n.__ 'Remove_someone_from_room'
+	params: '@username'
diff --git a/packages/rocketchat-slashcommands-kick/i18n/ar.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/ar.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..8a0f48baf891f8baeefda509380d5659256aff1c
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/ar.i18n.json
@@ -0,0 +1,4 @@
+{
+  "Username_is_not_in_this_room" : "المستخدم `#%s` غير موجود في الغرفة",
+  "Remove_someone_from_room" : "إزالة شخص من الغرفة"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/cs.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/cs.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/cs.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/de.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/de.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..033f4cec499f12780fe0c13c54a8a3800dc8f934
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/de.i18n.json
@@ -0,0 +1,5 @@
+{
+  "Username_doesnt_exist" : "Der Benutzername `#%s` existiert nicht.",
+  "Username_is_not_in_this_room" : "Der Benutzer `#%s` ist nicht in diesem Raum.",
+  "Remove_someone_from_room" : "Jemanden aus dem Raum entfernen"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/el.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/el.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/el.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/en.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/en.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..4074198404aaa037f05d6262bd7af9027c5672ae
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/en.i18n.json
@@ -0,0 +1,5 @@
+{
+  "Username_doesnt_exist" : "The username `#%s` doesn't exist.",
+  "Username_is_not_in_this_room" : "The user `#%s` is not in this room.",
+  "Remove_someone_from_room" : "Remove someone from the room"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/es.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/es.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/es.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/fa.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/fa.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/fa.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/fi.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/fi.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..63a5726744edfb8423f4bab35db21c1a43f4196b
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/fi.i18n.json
@@ -0,0 +1,5 @@
+{
+  "Username_doesnt_exist" : "Käyttäjätunnusta  `#% s` ei ole olemassa.",
+  "Username_is_not_in_this_room" : "Käyttäjä `#% s` ei ole tässä huoneessa.",
+  "Remove_someone_from_room" : "Poista joku huoneesta"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/fr.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/fr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..f005e4a0b51327f9ff573512d663c9f6124d780b
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/fr.i18n.json
@@ -0,0 +1,5 @@
+{
+  "Username_doesnt_exist" : "L'utilisateur `#%s` n'existe pas.",
+  "Username_is_not_in_this_room" : "L'utilisateur `#%s` est pas dans ce salon.",
+  "Remove_someone_from_room" : "Retirer quelqu'un du salon."
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/he.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/he.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/he.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/hr.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/hr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..f4880e1c7ea2ad0db394cf4411903eacaf30a31b
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/hr.i18n.json
@@ -0,0 +1,5 @@
+{
+  "Username_doesnt_exist" : "Korisničko ime '#% s` ne postoji.",
+  "Username_is_not_in_this_room" : "Korisnik `#% s` nije u ovoj sobi.",
+  "Remove_someone_from_room" : "Uklonite nekoga iz sobe"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/hu.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/hu.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/hu.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/it.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/it.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/it.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/ja.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/ja.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/ja.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/km.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/km.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/km.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/ko.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/ko.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/ko.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/ku.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/ku.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/ku.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/lo.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/lo.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/lo.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/ms-MY.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/ms-MY.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/ms-MY.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/nl.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/nl.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..a7e2c8e2068d08ea68d42562811550924903852d
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/nl.i18n.json
@@ -0,0 +1,5 @@
+{
+  "Username_doesnt_exist" : "De gebruikersnaam `#%s` bestaat niet.",
+  "Username_is_not_in_this_room" : "De gebruiker `#%s` is niet in deze kamer.",
+  "Remove_someone_from_room" : "Verwijder iemand uit de kamer"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/pl.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/pl.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/pl.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/pt.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/pt.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/pt.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/ro.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..967a28c53f65d8f8f9e122d40a09e28dc7a9a951
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/ro.i18n.json
@@ -0,0 +1,5 @@
+{
+  "Username_doesnt_exist" : "Numele de utilizator `#% s` nu există.",
+  "Username_is_not_in_this_room" : "Utilizatorul `#% s` nu este în această cameră.",
+  "Remove_someone_from_room" : "Scoateți pe cineva din camera"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/ru.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/ru.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..56c56d4f03ea306d7a900c6cacf27fc32bfaa996
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/ru.i18n.json
@@ -0,0 +1,4 @@
+{
+  "Username_is_not_in_this_room" : "Пользователь `#%s` не в этом чате.",
+  "Remove_someone_from_room" : "Удалить кого-то из чата"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/sq.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/sq.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/sq.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/sr.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/sr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/sv.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/sv.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/sv.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/ta-IN.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/ta-IN.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/ta-IN.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/tr.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/tr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/tr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/ug.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/ug.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/ug.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/uk.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/uk.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/uk.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/i18n/zh.i18n.json b/packages/rocketchat-slashcommands-kick/i18n/zh.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/i18n/zh.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-kick/package.js b/packages/rocketchat-slashcommands-kick/package.js
new file mode 100644
index 0000000000000000000000000000000000000000..a2878a1f7d4206188684fdf24ec3ebe2e5a92335
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/package.js
@@ -0,0 +1,36 @@
+Package.describe({
+	name: 'rocketchat:slashcommands-kick',
+	version: '0.0.1',
+	summary: 'Command handler for the /kick command',
+	git: ''
+});
+
+Package.onUse(function(api) {
+
+	api.versionsFrom('1.0');
+
+	api.use([
+		'coffeescript',
+		'check',
+		'rocketchat:lib'
+	]);
+
+	api.addFiles('client.coffee', 'client');
+	api.addFiles('server.coffee', 'server');
+
+	// TAPi18n
+	api.use('templating', 'client');
+	var _ = Npm.require('underscore');
+	var fs = Npm.require('fs');
+	tapi18nFiles = _.compact(_.map(fs.readdirSync('packages/rocketchat-slashcommands-kick/i18n'), function(filename) {
+		if (fs.statSync('packages/rocketchat-slashcommands-kick/i18n/' + filename).size > 16) {
+			return 'i18n/' + filename;
+		}
+	}));
+	api.use('tap:i18n');
+	api.addFiles(tapi18nFiles);
+});
+
+Package.onTest(function(api) {
+
+});
diff --git a/packages/rocketchat-slashcommands-kick/server.coffee b/packages/rocketchat-slashcommands-kick/server.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..112313be987440b5aef170589f1faf42842a1dcd
--- /dev/null
+++ b/packages/rocketchat-slashcommands-kick/server.coffee
@@ -0,0 +1,40 @@
+###
+# Kick is a named function that will replace /kick commands
+###
+
+class Kick
+	constructor: (command, params, item) ->
+		if command isnt 'kick' or not Match.test params, String
+			return
+
+		username = params.trim()
+		if username is ''
+			return
+
+		username = username.replace('@', '')
+
+		user = Meteor.users.findOne Meteor.userId()
+		kickedUser = RocketChat.models.Users.findOneByUsername username
+		room = RocketChat.models.Rooms.findOneById item.rid
+
+		if not kickedUser?
+			RocketChat.Notifications.notifyUser Meteor.userId(), 'message', {
+				_id: Random.id()
+				rid: item.rid
+				ts: new Date
+				msg: TAPi18n.__('Username_doesnt_exist', { postProcess: 'sprintf', sprintf: [ username ] }, user.language);
+			}
+			return
+
+		if username not in (room.usernames or [])
+			RocketChat.Notifications.notifyUser Meteor.userId(), 'message', {
+				_id: Random.id()
+				rid: item.rid
+				ts: new Date
+				msg: TAPi18n.__('Username_is_not_in_this_room', { postProcess: 'sprintf', sprintf: [ username ] }, user.language);
+			}
+			return
+
+		Meteor.call 'removeUserFromRoom', { rid: item.rid, username: username }
+
+RocketChat.slashCommands.add 'kick', Kick
diff --git a/packages/rocketchat-slashcommands-leave/package.js b/packages/rocketchat-slashcommands-leave/package.js
index 678f15b5593681774e84969aa3b03a07a8fad381..ac66b78c4648af2e9d62b8e1ba3178e9c1ed8d3b 100644
--- a/packages/rocketchat-slashcommands-leave/package.js
+++ b/packages/rocketchat-slashcommands-leave/package.js
@@ -10,7 +10,7 @@ Package.onUse(function(api) {
 
 	api.use([
 		'coffeescript',
-		'rocketchat:lib@0.0.1'
+		'rocketchat:lib'
 	]);
 	api.addFiles('leave.coffee');
 });
diff --git a/packages/rocketchat-slashcommands-mute/client/mute.coffee b/packages/rocketchat-slashcommands-mute/client/mute.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..d812e0cc179eff97753683ee5795c77549b84640
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/client/mute.coffee
@@ -0,0 +1,3 @@
+RocketChat.slashCommands.add 'mute', null,
+	description: TAPi18n.__ 'Mute_someone_in_room'
+	params: '@username'
diff --git a/packages/rocketchat-slashcommands-mute/client/unmute.coffee b/packages/rocketchat-slashcommands-mute/client/unmute.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..4d59ccb7de4bd97b7407520628aacd4aebb77bec
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/client/unmute.coffee
@@ -0,0 +1,3 @@
+RocketChat.slashCommands.add 'unmute', null,
+	description: TAPi18n.__ 'Unmute_someone_in_room'
+	params: '@username'
diff --git a/packages/rocketchat-slashcommands-mute/i18n/ar.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/ar.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..093fc95cd564f0791dc57cc18eeb6dfe3faaa793
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/ar.i18n.json
@@ -0,0 +1,4 @@
+{
+  "Mute_someone_in_room" : "إسكات شخص في الغرفة",
+  "Unmute_someone_in_room" : "إلغاء إسكات شخص في هذه الغرفة"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/cs.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/cs.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/cs.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/de.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/de.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..d1a8bdcde1f6a9341c1c6f498f26c12feffaff7e
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/de.i18n.json
@@ -0,0 +1,4 @@
+{
+  "Mute_someone_in_room" : "Jemanden das Chatten in einem Raum verbieten",
+  "Unmute_someone_in_room" : "Jemanden das Chatten in einem Raum wieder erlauben"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/el.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/el.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/el.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/en.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/en.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..a4c14cecd20881e5ef2199153c0b08b8a5cf2df2
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/en.i18n.json
@@ -0,0 +1,4 @@
+{
+  "Mute_someone_in_room" : "Mute someone in the room",
+  "Unmute_someone_in_room" : "Unmute someone in the room"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/es.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/es.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/es.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/fa.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/fa.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/fa.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/fi.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/fi.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..9058f3251335a95904e820c5b9b8152e090f8300
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/fi.i18n.json
@@ -0,0 +1,4 @@
+{
+  "Mute_someone_in_room" : "Mykistä joku huoneessa",
+  "Unmute_someone_in_room" : "Poista jonkun mykistys huoneessa"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/fr.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/fr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..f11bb2e01a39ee820c732a2d2d0df4ce5007df44
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/fr.i18n.json
@@ -0,0 +1,4 @@
+{
+  "Mute_someone_in_room" : "Rendre quelqu'un muet dans ce salon",
+  "Unmute_someone_in_room" : "Réactiver le chat de quelqu'un"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/he.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/he.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/he.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/hr.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/hr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/hr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/hu.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/hu.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/hu.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/it.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/it.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/it.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/ja.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/ja.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/ja.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/km.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/km.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/km.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/ko.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/ko.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/ko.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/ku.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/ku.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/ku.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/lo.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/lo.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/lo.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/ms-MY.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/ms-MY.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/ms-MY.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/nl.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/nl.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..0493e2a91aadb4cfdc8a6ee22de6c2f8bd1d01ae
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/nl.i18n.json
@@ -0,0 +1,4 @@
+{
+  "Mute_someone_in_room" : "Maak iemand in de kamer stil",
+  "Unmute_someone_in_room" : "Laat iemand weer in de kamer praten"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/pl.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/pl.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/pl.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/pt.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/pt.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/pt.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/ro.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..72303597425f503f3ca99eddc82380d03ab13008
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/ro.i18n.json
@@ -0,0 +1,4 @@
+{
+  "Mute_someone_in_room" : "Blocați noi mesaje ale cuiva în cameră",
+  "Unmute_someone_in_room" : "Deblocați mesajele noi ale unui utilizator în cameră"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/ru.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/ru.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..55e8952a1a75995ca14a58ca657e5197dfc7f867
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/ru.i18n.json
@@ -0,0 +1,3 @@
+{
+  "Mute_someone_in_room" : "Заглу"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/sq.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/sq.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/sq.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/sr.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/sr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/sv.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/sv.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/sv.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/ta-IN.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/ta-IN.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/ta-IN.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/tr.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/tr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/tr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/ug.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/ug.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/ug.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/uk.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/uk.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/uk.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/i18n/zh.i18n.json b/packages/rocketchat-slashcommands-mute/i18n/zh.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/i18n/zh.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-slashcommands-mute/package.js b/packages/rocketchat-slashcommands-mute/package.js
new file mode 100644
index 0000000000000000000000000000000000000000..3d776dd74e1787f97c047df4ed087b224ae1443a
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/package.js
@@ -0,0 +1,38 @@
+Package.describe({
+	name: 'rocketchat:slashcommands-mute',
+	version: '0.0.1',
+	summary: 'Command handler for the /mute command',
+	git: ''
+});
+
+Package.onUse(function(api) {
+
+	api.versionsFrom('1.0');
+
+	api.use([
+		'coffeescript',
+		'check',
+		'rocketchat:lib'
+	]);
+
+	api.addFiles('client/mute.coffee', 'client');
+	api.addFiles('client/unmute.coffee', 'client');
+	api.addFiles('server/mute.coffee', 'server');
+	api.addFiles('server/unmute.coffee', 'server');
+
+	// TAPi18n
+	api.use('templating', 'client');
+	var _ = Npm.require('underscore');
+	var fs = Npm.require('fs');
+	tapi18nFiles = _.compact(_.map(fs.readdirSync('packages/rocketchat-slashcommands-mute/i18n'), function(filename) {
+		if (fs.statSync('packages/rocketchat-slashcommands-mute/i18n/' + filename).size > 16) {
+			return 'i18n/' + filename;
+		}
+	}));
+	api.use('tap:i18n');
+	api.addFiles(tapi18nFiles);
+});
+
+Package.onTest(function(api) {
+
+});
diff --git a/packages/rocketchat-slashcommands-mute/server/mute.coffee b/packages/rocketchat-slashcommands-mute/server/mute.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..d8bc3d3bc513d90e75e237da4fc23c63fedbd19a
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/server/mute.coffee
@@ -0,0 +1,40 @@
+###
+# Mute is a named function that will replace /mute commands
+###
+
+class Mute
+	constructor: (command, params, item) ->
+		if command isnt 'mute' or not Match.test params, String
+			return
+
+		username = params.trim()
+		if username is ''
+			return
+
+		username = username.replace('@', '')
+
+		user = Meteor.users.findOne Meteor.userId()
+		mutedUser = RocketChat.models.Users.findOneByUsername username
+		room = RocketChat.models.Rooms.findOneById item.rid
+
+		if not mutedUser?
+			RocketChat.Notifications.notifyUser Meteor.userId(), 'message', {
+				_id: Random.id()
+				rid: item.rid
+				ts: new Date
+				msg: TAPi18n.__('Username_doesnt_exist', { postProcess: 'sprintf', sprintf: [ username ] }, user.language);
+			}
+			return
+
+		if username not in (room.usernames or [])
+			RocketChat.Notifications.notifyUser Meteor.userId(), 'message', {
+				_id: Random.id()
+				rid: item.rid
+				ts: new Date
+				msg: TAPi18n.__('Username_is_not_in_this_room', { postProcess: 'sprintf', sprintf: [ username ] }, user.language);
+			}
+			return
+
+		Meteor.call 'muteUserInRoom', { rid: item.rid, username: username }
+
+RocketChat.slashCommands.add 'mute', Mute
diff --git a/packages/rocketchat-slashcommands-mute/server/unmute.coffee b/packages/rocketchat-slashcommands-mute/server/unmute.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..e3b6ee25d82dba48c51f2c98d43557652520e3b5
--- /dev/null
+++ b/packages/rocketchat-slashcommands-mute/server/unmute.coffee
@@ -0,0 +1,40 @@
+###
+# Unmute is a named function that will replace /unmute commands
+###
+
+class Unmute
+	constructor: (command, params, item) ->
+		if command isnt 'unmute' or not Match.test params, String
+			return
+
+		username = params.trim()
+		if username is ''
+			return
+
+		username = username.replace('@', '')
+
+		user = Meteor.users.findOne Meteor.userId()
+		unmutedUser = RocketChat.models.Users.findOneByUsername username
+		room = RocketChat.models.Rooms.findOneById item.rid
+
+		if not unmutedUser?
+			RocketChat.Notifications.notifyUser Meteor.userId(), 'message', {
+				_id: Random.id()
+				rid: item.rid
+				ts: new Date
+				msg: TAPi18n.__('Username_doesnt_exist', { postProcess: 'sprintf', sprintf: [ username ] }, user.language);
+			}
+			return
+
+		if username not in (room.usernames or [])
+			RocketChat.Notifications.notifyUser Meteor.userId(), 'message', {
+				_id: Random.id()
+				rid: item.rid
+				ts: new Date
+				msg: TAPi18n.__('Username_is_not_in_this_room', { postProcess: 'sprintf', sprintf: [ username ] }, user.language);
+			}
+			return
+
+		Meteor.call 'unmuteUserInRoom', { rid: item.rid, username: username }
+
+RocketChat.slashCommands.add 'unmute', Unmute
diff --git a/packages/rocketchat-spotify/package.js b/packages/rocketchat-spotify/package.js
index 4940ac69ed8a07ab7d59b461c0a84a3b9354b8b4..c4829d6eb67ba807dc2e9ae385b87705911b62a3 100644
--- a/packages/rocketchat-spotify/package.js
+++ b/packages/rocketchat-spotify/package.js
@@ -13,7 +13,7 @@ Package.onUse(function(api) {
 		'templating',
 		'underscore',
 		'rocketchat:oembed@0.0.1',
-		'rocketchat:lib@0.0.1'
+		'rocketchat:lib'
 	]);
 
 	api.addFiles('lib/client/widget.coffee', 'client');
diff --git a/packages/rocketchat-statistics/package.js b/packages/rocketchat-statistics/package.js
index 47133065781539a8e2e208e101e369d72865374a..31216ca161258852ee760ca43acf39d045c6c875 100644
--- a/packages/rocketchat-statistics/package.js
+++ b/packages/rocketchat-statistics/package.js
@@ -10,7 +10,7 @@ Package.onUse(function(api) {
 
 	api.use([
 		'coffeescript',
-		'rocketchat:lib@0.0.1'
+		'rocketchat:lib'
 	]);
 
 	// Statistics
@@ -32,9 +32,8 @@ Package.onUse(function(api) {
 			return 'i18n/' + filename;
 		}
 	}));
-	api.use('tap:i18n@1.6.1', ['client', 'server']);
-	api.imply('tap:i18n');
-	api.addFiles(tapi18nFiles, ['client', 'server']);
+	api.use('tap:i18n');
+	api.addFiles(tapi18nFiles);
 
 });
 
diff --git a/packages/rocketchat-statistics/server/methods/getStatistics.coffee b/packages/rocketchat-statistics/server/methods/getStatistics.coffee
index 8bf3e8cb1d915b244f6eab3f68d2be6f6361b66a..dfe10d205e7015211627c2e13af5cd3f9295bde7 100644
--- a/packages/rocketchat-statistics/server/methods/getStatistics.coffee
+++ b/packages/rocketchat-statistics/server/methods/getStatistics.coffee
@@ -3,9 +3,7 @@ Meteor.methods
 		if not Meteor.userId()
 			throw new Meteor.Error('invalid-user', "[methods] getStatistics -> Invalid user")
 
-		console.log '[methods] getStatistics -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
-
 		unless RocketChat.authz.hasPermission(Meteor.userId(), 'view-statistics') is true
 			throw new Meteor.Error 'not-authorized', '[methods] getStatistics -> Not authorized'
 
-		return RocketChat.statistics.get()
\ No newline at end of file
+		return RocketChat.statistics.get()
diff --git a/packages/rocketchat-theme/assets/stylesheets/base.less b/packages/rocketchat-theme/assets/stylesheets/base.less
index 55ecffa41af830b6779f5968c163d328d02a3719..cd4541029362520318ff2aae15cfa5474bde1e90 100644
--- a/packages/rocketchat-theme/assets/stylesheets/base.less
+++ b/packages/rocketchat-theme/assets/stylesheets/base.less
@@ -475,7 +475,8 @@ form.inline {
 	}
 }
 
-input[disabled] {
+input[disabled],
+textarea[disabled] {
 	background-color: #f4f4f4 !important;
 }
 
@@ -867,6 +868,10 @@ a.github-fork {
 	overflow: hidden;
 	position: relative;
 	border-radius: 4px;
+	.emojione {
+		height: 100%;
+		margin: 0px;
+	}
 	.avatar-image {
 		height: 100%;
 		width: 100%;
@@ -1579,7 +1584,7 @@ a.github-fork {
 		}
 	}
 	h2 {
-		max-width: 90%;
+		width: 100%;
 		overflow: hidden;
 		white-space: nowrap;
 		text-overflow: ellipsis;
@@ -1722,6 +1727,10 @@ a.github-fork {
 			.transform(translateX(0));
 		}
 	}
+	&.main-modal {
+		left: 0px;
+		margin-right: 0px;
+	}
 	.container-fluid {
 		padding-top: 0;
 	}
@@ -1793,6 +1802,18 @@ a.github-fork {
 					padding-top: 0;
 				}
 
+				&.setting-changed {
+					> label {
+						color: #627CFF
+					}
+				}
+
+				&[disabled] {
+					label {
+						color: #888;
+					}
+				}
+
 				input {
 					color: #444;
 				}
@@ -1809,6 +1830,14 @@ a.github-fork {
 					color: #888;
 					padding: 5px;
 				}
+
+				.settings-alert {
+					background-color: rgb(255, 255, 230);
+					border: 1px solid rgb(255, 242, 196);
+					color: orange;
+					font-weight: bold;
+					padding: 5px;
+				}
 			}
 		}
 	}
@@ -2112,13 +2141,21 @@ a.github-fork {
 		text-transform: uppercase;
 		text-align: center;
 
-		> a {
+		> a.mark-read {
 			float: right;
 
 			&:hover {
 				cursor: pointer;
 			}
 		}
+
+		> a.jump-to {
+			float: left;
+
+			&:hover {
+				cursor: pointer;
+			}
+		}
 	}
 }
 
@@ -2129,7 +2166,11 @@ a.github-fork {
 	height: 100%;
 	top: 0;
 	left: 0;
-
+	.room-topic {
+		font-size: 14px;
+		opacity: 0.4;
+		margin-left: 10px;
+	}
 	.edit-room-title {
 		margin-left: 4px;
 		font-size: 16px;
@@ -2385,6 +2426,9 @@ a.github-fork {
 	width: 100%;
 	.calc(height,
 	~'100% - 120px');
+	.wrapper.has-more-next {
+		padding-bottom: 24px;
+	}
 	ul {
 		padding: 21px 0 10px;
 	}
@@ -2421,11 +2465,41 @@ a.github-fork {
 			.transform(translateY(150%));
 		}
 	}
+	.jump-recent {
+		z-index: 15;
+		background-color: #E7E7E7;
+		position: absolute;
+		text-align: right;
+		height: 24px;
+		line-height: 24px;
+		font-size: 0.8em;
+		padding-right: 20px;
+		bottom: 0;
+		left: 20px;
+		right: 20px;
+		border-top-left-radius: 4px;
+		border-top-right-radius: 4px;
+
+		span {
+			cursor: pointer;
+		}
+		.transition(transform 0.3s ease-out);
+		.transform(translateY(0));
+		&.not {
+			.transform(translateY(150%));
+		}
+	}
 	.editing {
 		.body {
 			border-radius: 4px;
 		}
 	}
+	&.selectable .message {
+		cursor: pointer;
+		&.selected {
+			background-color: #FFD;
+		}
+	}
 }
 
 .ticks-bar {
@@ -2444,11 +2518,18 @@ a.github-fork {
 }
 
 .message {
-	padding: 18px 20px 4px 70px;
+	padding: 8px 20px 4px 70px;
 	position: relative;
 	line-height: 20px;
 	min-height: 40px;
 
+	&.highlight {
+		-webkit-animation: highlight 3s;
+		-moz-animation: highlight 3s;
+		-o-animation: highlight 3s;
+		animation: highlight 3s;
+	}
+
 	.body, .user.user-card-message, .time {
 		-webkit-user-select: text;
 		-moz-user-select: text;
@@ -2465,6 +2546,9 @@ a.github-fork {
 	&:nth-child(1) {
 		margin-top: 0;
 	}
+	&:hover {
+		background-color: @message-hover-background-color;
+	}
 	&.new-day {
 		margin-top: 60px;
 	}
@@ -2583,7 +2667,6 @@ a.github-fork {
 	.thumb {
 		position: absolute;
 		left: 20px;
-		top: 20px;
 		display: block;
 		width: 40px;
 		height: 40px;
@@ -2619,6 +2702,7 @@ a.github-fork {
 		min-height: 20px;
 		padding-top: 4px;
 		padding-bottom: 4px;
+		margin-top: 0px;
 		.user {
 			display: none;
 		}
@@ -2647,6 +2731,9 @@ a.github-fork {
 				margin-left: 1px;
 			}
 		}
+		.body {
+			margin-top: 0px;
+		}
 
 		// .message-dropdown {
 		// 	top: 100%;
@@ -2683,6 +2770,7 @@ a.github-fork {
 	.body {
 		opacity: 1;
 		.transition(opacity 1s linear);
+		margin-top: 2px;
 
 		.inline-image {
 			background-size: contain;
@@ -2713,9 +2801,9 @@ a.github-fork {
 
 .compact {
 	.message {
-		padding: 5px 20px 5px 70px;
-		.thumb:not(.thumb-small) .avatar {
-			margin-top: -15px;
+		padding: 4px 20px 4px 70px;
+		.body {
+			margin-top: 0px;
 		}
 	}
 }
@@ -2999,7 +3087,12 @@ a.github-fork {
 		margin-left: 120px;
 		white-space: normal;
 		.calc(width, ~'100% - 120px');
+
 		h3 {
+			-webkit-user-select: text;
+			-moz-user-select: text;
+			-ms-user-select: text;
+			user-select: text;
 			font-size: 24px;
 			margin-bottom: 8px;
 			line-height: 27px;
@@ -3035,6 +3128,10 @@ a.github-fork {
 			}
 		}
 		p {
+			-webkit-user-select: text;
+			-moz-user-select: text;
+			-ms-user-select: text;
+			user-select: text;
 			line-height: 18px;
 			font-size: 12px;
 			font-weight: 300;
@@ -4195,7 +4292,10 @@ a.github-fork {
 }
 
 .inline-video {
-	max-height: 200px;
+    height: auto;
+    width: 100%;
+    max-width: 480px;
+    max-height: 270px;
 }
 
 .attention-message {
@@ -4209,3 +4309,52 @@ a.github-fork {
 		font-size: 40px;
 	}
 }
+
+.search-messages-list {
+	.message-cog-container {
+		.message-action {
+			display: none !important;
+			&.jump-to-star-message {
+				display: block !important;
+			}
+		}
+	}
+
+	.load-more {
+		text-transform: lowercase;
+		text-align: center;
+		line-height: 40px;
+		font-style: italic;
+
+		.load-more-loading {
+			color: #aaa;
+		}
+	}
+
+	.no-results {
+		text-align: center;
+	}
+}
+
+.uploaded-files-list {
+	.load-more {
+		text-transform: lowercase;
+		text-align: center;
+		line-height: 40px;
+		font-style: italic;
+
+		.load-more-loading {
+			color: #aaa;
+		}
+	}
+}
+
+.messages-box {
+	.message-cog-container {
+		.message-action {
+			&.jump-to-search-message {
+				display: none !important;
+			}
+		}
+	}
+}
diff --git a/packages/rocketchat-theme/assets/stylesheets/rtl.less b/packages/rocketchat-theme/assets/stylesheets/rtl.less
index 9f4d66fcd297e795c2343024855f88efe793687c..b67ceb3652f68580e7bb7014ced551ec3845c300 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);
@@ -195,9 +196,12 @@
 			}
 		}
 		.unread-bar {
-			> a {
+			> a.mark-read {
 				float: left;
 			}
+			> a.jump-to {
+				float: right;
+			}
 		}
 	}
 
@@ -296,7 +300,7 @@
 			}
 		}
 	}
-	
+
 	.flex-opened {
 		.flex-tab {
 			.control {
@@ -386,7 +390,7 @@
 			}
 		}
 	}
-	
+
 	@media all and(max-width: 1100px) {
 		#rocket-chat {
 			.flex-opened {
@@ -628,7 +632,7 @@
 	#swipebox-overlay{
 		direction: ltr;
 	}
-	
+
 	/* Override toastr messages to show on hte left side */
 	.toast-top-right {
 		.left(12px);
diff --git a/packages/rocketchat-theme/assets/stylesheets/utils/_colors.import.less b/packages/rocketchat-theme/assets/stylesheets/utils/_colors.import.less
old mode 100644
new mode 100755
index 7bdb7b45f75cb0552fa15a1342325e971f54c156..13141a7836e5bc0e0954dcbdac03ab2fcf6ed964
--- a/packages/rocketchat-theme/assets/stylesheets/utils/_colors.import.less
+++ b/packages/rocketchat-theme/assets/stylesheets/utils/_colors.import.less
@@ -123,7 +123,7 @@ blockquote {
 }
 
 html {
-	.custom-scroll(transparent, rgba(255, 255, 255, 0.05), 3px);
+	.custom-scroll(transparent, @custom-scrollbar-color, 3px);
 }
 
 body {
@@ -212,9 +212,8 @@ label.required:after {
 
 // new layout buttons
 .button {
-	background-color: #FFF;
 	color: rgba(255, 255, 255, 0.85);
-	background-color: lighten(desaturate(@primary-background-color, 15%), 12.5%);
+	background-color: @action-buttons-color;
 	&:before {
 		background-color: rgba(0, 0, 0, 0.1);
 	}
@@ -237,7 +236,7 @@ label.required:after {
 		background-color: #02acec;
 	}
 	&.clean {
-		background-color: rgba(0, 0, 0, 0.025);
+		background-color: @clean-buttons-color;
 	}
 	&.facebook {
 		background-color: #325c99;
@@ -328,7 +327,7 @@ a.github-fork {
 	.info {
 		background-color:@primary-background-color;
 		h4 {
-			color: rgba(255, 255, 255, 0.65);
+			color: fade( @quaternary-font-color, 65% );
 		}
 		&.status-offline {
 			.thumb:after {
@@ -384,29 +383,29 @@ a.github-fork {
 					border-color: #9f0030;
 					background-color: #D30230;
 				}
-			}
+			}	
 		}
 		span.soon {
 			color: #aaa;
 		}
 		a {
-			color: rgba(255, 255, 255, 0.5);
+			color: fade( @quaternary-font-color, 50% );
 			border-bottom-color: darken(@primary-background-color, 2%);
 			&:hover {
 				background-color: darken(@primary-background-color, 2%);
-				color: rgba(255, 255, 255, 0.75);
+				color: fade( @quaternary-font-color, 75% );
 			}
 		}
 	}
 	&.active .info,
 	.info:hover {
 		h4 {
-			color: rgba(255, 255, 255, 0.85);
+			color: fade(@quaternary-font-color, 85% );
 		}
 	}
 	.hover & {
 		.info h4 {
-			color: rgba(255, 255, 255, 0.85);
+			color: fade(@quaternary-font-color, 85% );
 		}
 	}
 }
@@ -416,7 +415,7 @@ a.github-fork {
 	//background-color: @primary-background-color;
 	background-color: transparent;
 	color: @tertiary-font-color;
-	.custom-scroll(transparent, rgba(255, 255, 255, 0.05));
+	.custom-scroll(transparent, @custom-scrollbar-color);
 	header {
 		background-color: @primary-background-color;
 	}
@@ -424,7 +423,7 @@ a.github-fork {
 		background-color: @primary-background-color;
 	}
 	.content {
-		.custom-scroll(transparent, rgba(255, 255, 255, 0.05));
+		.custom-scroll(transparent, @custom-scrollbar-color);
 		background-color: @primary-background-color;
 	}
 	.input-line {
@@ -455,7 +454,7 @@ a.github-fork {
 	}
 	.rooms-list {
 		background-color: lighten(@primary-background-color, 2%);
-		.custom-scroll(transparent, rgba(255, 255, 255, 0.05));
+		.custom-scroll(transparent, @custom-scrollbar-color);
 	}
 	.more {
 		color: @tertiary-font-color;
@@ -478,7 +477,7 @@ a.github-fork {
 		&:hover {
 			&:before,
 			&:after {
-				background-color: rgba(255, 255, 255, 0.85);
+				background-color: fade( @quaternary-font-color, 85% );
 			}
 		}
 	}
@@ -499,7 +498,7 @@ a.github-fork {
 		}
 	}
 	.unread {
-		background-color: #1dce73;
+		background-color: @unread-notification-color;
 		color: #FFF;
 	}
 	ul {
@@ -515,8 +514,8 @@ a.github-fork {
 			}
 			&.active {
 				a {
-					background-color: rgba(255, 255, 255, 0.075);
-					color: rgba(255, 255, 255, 0.75);
+					background-color: @active-channel-background-color;
+					color: @active-channel-font-color;
 				}
 				.opt {
 					background-color: transparent;
@@ -524,7 +523,7 @@ a.github-fork {
 			}
 			&.has-alert {
 				.name {
-					color: #ffffff;
+					color: @quaternary-font-color;
 				}
 			}
 			&.away {
@@ -542,14 +541,14 @@ a.github-fork {
 		.opt {
 			background-color: transparent;
 			i {
-				color: rgba(255, 255, 255, 0.5);
+				color: fade(@quaternary-font-color, 50% );
 				&:hover {
-					color: rgba(255, 255, 255, 0.75);
+					color: fade(@quaternary-font-color, 75% );
 				}
 			}
 		}
 		i {
-			color: rgba(255, 255, 255, 0.35);
+			color: fade(@quaternary-font-color, 35% );
 		}
 		input[type=text] {
 			color: #000;
diff --git a/packages/rocketchat-theme/i18n/ar.i18n.json b/packages/rocketchat-theme/i18n/ar.i18n.json
index 7275473661d29fae4f82ae144af9dc753b8b05df..bdfad243ecf26910dda5a9cde9571a6c909e9018 100644
--- a/packages/rocketchat-theme/i18n/ar.i18n.json
+++ b/packages/rocketchat-theme/i18n/ar.i18n.json
@@ -1,3 +1,4 @@
 {
-  "theme-color-status-away" : "لون حالة بعيد"
+  "theme-color-status-away" : "لون حالة بعيد",
+  "theme-color-status-busy" : "لون حالة مشغول"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-theme/i18n/de.i18n.json b/packages/rocketchat-theme/i18n/de.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..93f6faa9c45986af74f33fa7837765b927c4351c 100644
--- a/packages/rocketchat-theme/i18n/de.i18n.json
+++ b/packages/rocketchat-theme/i18n/de.i18n.json
@@ -1 +1,31 @@
-{ }
\ No newline at end of file
+{
+  "theme-color-action-buttons-color" : "Farbe des Aktionsbuttons",
+  "theme-color-active-channel-background-color" : "Hintergrundfarbe von aktiven Kanälen",
+  "theme-color-active-channel-font-color" : "Schriftfarbe von aktiven Kanälen",
+  "theme-color-blockquote-background" : "Hintergrundfarbe der Blockquotes ",
+  "theme-color-clean-buttons-color" : "Farbe des Säuberungsknopfs",
+  "theme-color-code-background" : "Hintergrundfarbe des Codes",
+  "theme-color-code-border" : "Randfarbe des Codes",
+  "theme-color-code-color" : "Farbe des Codes",
+  "theme-color-content-background-color" : "Hintergrundfarbe des Inhalts",
+  "theme-color-custom-scrollbar-color" : "Benutzerdefinierte Farbe der Scrollbar",
+  "theme-color-info-active-font-color" : "Schriftfarbe von aktiven Informationen",
+  "theme-color-info-font-color" : "Schriftfarbe von Informationen",
+  "theme-color-input-font-color" : "Schriftfarbe der Eingabe",
+  "theme-color-link-font-color" : "Schriftfarbe des Links",
+  "theme-color-message-hover-background-color" : "Hintergrundfarbe beim Mauskontakt mit einer Nachricht",
+  "theme-color-primary-background-color" : "Primäre Hintergrundfarbe ",
+  "theme-color-primary-font-color" : "Primäre Schriftfarbe",
+  "theme-color-quaternary-font-color" : "Quartäre Schriftfarbe",
+  "theme-color-secondary-background-color" : "Sekundäre Hintergrundfarbe",
+  "theme-color-secondary-font-color" : "Sekundäre Schriftfarbe",
+  "theme-color-smallprint-font-color" : "Schriftfarbe des Kleingedrucktem",
+  "theme-color-smallprint-hover-color" : "Farbe bei Mauskontakt mit Kleingedrucktem",
+  "theme-color-status-away" : "Farbe des Status \"abwesend\"",
+  "theme-color-status-busy" : "Farbe des Status \"beschäftigt\"",
+  "theme-color-status-offline" : "Farbe des Status \"offline\"\n",
+  "theme-color-status-online" : "Farbe des Status \"online\"",
+  "theme-color-tertiary-background-color" : "Tertiäre Hintergrundfarbe ",
+  "theme-color-tertiary-font-color" : "Tertiäre Schriftfarbe",
+  "theme-color-unread-notification-color" : "Farbe von ungelesenen Benachrichtigungen"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-theme/i18n/en.i18n.json b/packages/rocketchat-theme/i18n/en.i18n.json
index 1cac00320b14f0da11f7ecc9aac62f1d86b56b38..5535a7a7ecbdca1687c2a9fe9890fef589d15e85 100644
--- a/packages/rocketchat-theme/i18n/en.i18n.json
+++ b/packages/rocketchat-theme/i18n/en.i18n.json
@@ -1,15 +1,22 @@
 {
+  "theme-color-action-buttons-color" : "Actions Buttons Color",
+  "theme-color-active-channel-background-color" : "Active Channel Background Color",
+  "theme-color-active-channel-font-color" : "Active Channel Font Color",
   "theme-color-blockquote-background" : "Blockquote Background Color",
+  "theme-color-clean-buttons-color" : "Clean Buttons Color",
   "theme-color-code-background" : "Code Background Color",
   "theme-color-code-border" : "Code Border Color",
   "theme-color-code-color" : "Code Color",
   "theme-color-content-background-color" : "Content Background Color",
+  "theme-color-custom-scrollbar-color" : "Custom Scrollbar Color",
   "theme-color-info-active-font-color" : "Active Info Font Color",
   "theme-color-info-font-color" : "Info Font Color",
   "theme-color-input-font-color" : "Input Font Color",
   "theme-color-link-font-color" : "Link Font Color",
+  "theme-color-message-hover-background-color" : "Message Hover BG Color",
   "theme-color-primary-background-color" : "Primary Background Color",
   "theme-color-primary-font-color" : "Primary Font Color",
+  "theme-color-quaternary-font-color" : "Quaternary Font Color",
   "theme-color-secondary-background-color" : "Secondary Background Color",
   "theme-color-secondary-font-color" : "Secondary Font Color",
   "theme-color-smallprint-font-color" : "Small Print Font Color",
@@ -19,5 +26,6 @@
   "theme-color-status-offline" : "Offline Status Color",
   "theme-color-status-online" : "Online Status Color",
   "theme-color-tertiary-background-color" : "Tertiary Background Color",
-  "theme-color-tertiary-font-color" : "Tertiary Font Color"
+  "theme-color-tertiary-font-color" : "Tertiary Font Color",
+  "theme-color-unread-notification-color" : "Unread Notifications Color"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-theme/i18n/fi.i18n.json b/packages/rocketchat-theme/i18n/fi.i18n.json
index 83ead2db3d3b175b2bb2f21ae85350c50c3bc67f..2ed1a051ebce49a24d46756952c4c13c29b35ee1 100644
--- a/packages/rocketchat-theme/i18n/fi.i18n.json
+++ b/packages/rocketchat-theme/i18n/fi.i18n.json
@@ -1,15 +1,21 @@
 {
+  "theme-color-action-buttons-color" : "Toimintapainikkeiden väri",
+  "theme-color-active-channel-background-color" : "Aktiivisen kanavan taustaväri",
+  "theme-color-active-channel-font-color" : "Aktiivisen kanavan tekstin väri",
   "theme-color-blockquote-background" : "Lainauksen taustaväri",
   "theme-color-code-background" : "Koodin taustaväri",
   "theme-color-code-border" : "Koodin reunusväri",
   "theme-color-code-color" : "Koodin väri",
   "theme-color-content-background-color" : "Sisällön taustaväri",
+  "theme-color-custom-scrollbar-color" : "Vierityspalkin väri (custom)",
   "theme-color-info-active-font-color" : "Aktiivisen infon fontin väri",
   "theme-color-info-font-color" : "Infon fontin väri",
   "theme-color-input-font-color" : "Syötteen fontin väri",
   "theme-color-link-font-color" : "Linkin fontin väri",
+  "theme-color-message-hover-background-color" : "Message Hover BG Color",
   "theme-color-primary-background-color" : "Ensisijainen taustaväri",
   "theme-color-primary-font-color" : "Ensisijainen fontin väri",
+  "theme-color-quaternary-font-color" : "Neljäs tekstin väri",
   "theme-color-secondary-background-color" : "Toissijainen taustaväri",
   "theme-color-secondary-font-color" : "Toissijainen fontin väri",
   "theme-color-smallprint-font-color" : "Pienen tekstin fontin väri",
diff --git a/packages/rocketchat-theme/i18n/fr.i18n.json b/packages/rocketchat-theme/i18n/fr.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..e9164f9d59b2b7f538f96367d44a7df39b7cc156 100644
--- a/packages/rocketchat-theme/i18n/fr.i18n.json
+++ b/packages/rocketchat-theme/i18n/fr.i18n.json
@@ -1 +1,23 @@
-{ }
\ No newline at end of file
+{
+  "theme-color-blockquote-background" : "Couleur de fond des blocs de citation",
+  "theme-color-code-background" : "Couleur de fond des blocs de code",
+  "theme-color-code-border" : "Couleur des bordures du code",
+  "theme-color-code-color" : "Couleur du code",
+  "theme-color-content-background-color" : "Couleur de fond du contenu",
+  "theme-color-info-active-font-color" : "Couleur de la police des informations actives",
+  "theme-color-info-font-color" : "Couleur de la police des informations",
+  "theme-color-input-font-color" : "Couleur de la police du champ de message",
+  "theme-color-link-font-color" : "Couleur de la police des liens",
+  "theme-color-primary-background-color" : "Couleur de fond principale",
+  "theme-color-primary-font-color" : "Couleur de la police principale",
+  "theme-color-secondary-background-color" : "Couleur de fond secondaire",
+  "theme-color-secondary-font-color" : "Couleur de police secondaire",
+  "theme-color-smallprint-font-color" : "Couleur de la police des petits messages",
+  "theme-color-smallprint-hover-color" : "Couleur de survol des petits messages",
+  "theme-color-status-away" : "Couleur du statut \"Parti\" (AFK)",
+  "theme-color-status-busy" : "Couleur du statut \"occupé\"",
+  "theme-color-status-offline" : "Couleur du statut \"hors-ligne\"",
+  "theme-color-status-online" : "Couleur du statut \"en ligne\"",
+  "theme-color-tertiary-background-color" : "Couleur de fond tertiaire (contenu)",
+  "theme-color-tertiary-font-color" : "Couleur de police tertiaire (contenu)"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-theme/i18n/km.i18n.json b/packages/rocketchat-theme/i18n/km.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..c1235a4596e35f89514c8b91c4efe6e55bc2710f 100644
--- a/packages/rocketchat-theme/i18n/km.i18n.json
+++ b/packages/rocketchat-theme/i18n/km.i18n.json
@@ -1 +1,6 @@
-{ }
\ No newline at end of file
+{
+  "theme-color-code-background" : "កូដពណ៌ផ្ទៃខាងក្រោម",
+  "theme-color-code-border" : "កូដពណ៌ជាយ",
+  "theme-color-code-color" : "កូដពណ៌",
+  "theme-color-content-background-color" : "ពណ៌ផ្ទៃខាងក្រោយអត្ថបទ"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-theme/i18n/ko.i18n.json b/packages/rocketchat-theme/i18n/ko.i18n.json
index eae4ba0da589a295cbc5087e78af34444ed9dca7..fa6ce4e77c669ab4241b0e8cc60156c5eb9419e0 100644
--- a/packages/rocketchat-theme/i18n/ko.i18n.json
+++ b/packages/rocketchat-theme/i18n/ko.i18n.json
@@ -4,6 +4,11 @@
   "theme-color-code-border" : "코드 테두리 색상",
   "theme-color-code-color" : "코드 색상",
   "theme-color-content-background-color" : "콘텐츠 배경색",
+  "theme-color-info-font-color" : "글자 색상 정보",
+  "theme-color-primary-background-color" : "기본 배경색",
+  "theme-color-primary-font-color" : "기본 글자 색상",
+  "theme-color-secondary-background-color" : "보조 배경색",
+  "theme-color-secondary-font-color" : "보조 글자 색상",
   "theme-color-status-away" : "자리비움 상태 색상",
   "theme-color-status-busy" : "바쁨 상태 색상",
   "theme-color-status-offline" : "보지않음 상태 색상",
diff --git a/packages/rocketchat-theme/i18n/nl.i18n.json b/packages/rocketchat-theme/i18n/nl.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..70a0eeb7d0be7f969469de0ffcd36d8e8b9e54e7 100644
--- a/packages/rocketchat-theme/i18n/nl.i18n.json
+++ b/packages/rocketchat-theme/i18n/nl.i18n.json
@@ -1 +1,6 @@
-{ }
\ No newline at end of file
+{
+  "theme-color-active-channel-background-color" : "Actieve Kanaal Achtergrondkleur",
+  "theme-color-active-channel-font-color" : "Actieve Kanaal Tekstkleur",
+  "theme-color-message-hover-background-color" : "Achtergrondkleur als muis er boven is",
+  "theme-color-unread-notification-color" : "Ongelezen Notificaties Kleur"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-theme/i18n/ro.i18n.json b/packages/rocketchat-theme/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..48d9bc9c49231accbc06d01ffeb2581623bdc945
--- /dev/null
+++ b/packages/rocketchat-theme/i18n/ro.i18n.json
@@ -0,0 +1,31 @@
+{
+  "theme-color-action-buttons-color" : "Culoare butoane acțiuni",
+  "theme-color-active-channel-background-color" : "Culoare de fundal canal activ",
+  "theme-color-active-channel-font-color" : "Culoare text canal activ",
+  "theme-color-blockquote-background" : "Culoare de fundal Blockquote ",
+  "theme-color-clean-buttons-color" : "Culoare butoane curate",
+  "theme-color-code-background" : "Culoare de fundal cod",
+  "theme-color-code-border" : "Culoare chenar cod",
+  "theme-color-code-color" : "Culoare cod",
+  "theme-color-content-background-color" : "Culoare de fundal conținut",
+  "theme-color-custom-scrollbar-color" : "Culoare Scrollbar personalizat",
+  "theme-color-info-active-font-color" : "Culoare text informații activ",
+  "theme-color-info-font-color" : "Culoare text info",
+  "theme-color-input-font-color" : "Culoare text input",
+  "theme-color-link-font-color" : "Culoare text link",
+  "theme-color-message-hover-background-color" : "Culoare fundal mesaj la 'hover'",
+  "theme-color-primary-background-color" : "Culoare de fundal primară",
+  "theme-color-primary-font-color" : "Culoare text primară",
+  "theme-color-quaternary-font-color" : "Culoare font cuaternar",
+  "theme-color-secondary-background-color" : "Culoare de fundal secundară",
+  "theme-color-secondary-font-color" : "Culoare text secundară",
+  "theme-color-smallprint-font-color" : "Culoare text mic",
+  "theme-color-smallprint-hover-color" : "Culoare text mic la 'hover'",
+  "theme-color-status-away" : "Culoare status 'Away'",
+  "theme-color-status-busy" : "Culoare status 'Ocupat'",
+  "theme-color-status-offline" : "Culoare status 'Offline'",
+  "theme-color-status-online" : "Culoare status 'Activ'",
+  "theme-color-tertiary-background-color" : "Culoare de fundal terțiară",
+  "theme-color-tertiary-font-color" : "Culoare text terțiară",
+  "theme-color-unread-notification-color" : "Culoare notificări mesaje necitite"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-theme/i18n/sr.i18n.json b/packages/rocketchat-theme/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-theme/i18n/sr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-theme/package.js b/packages/rocketchat-theme/package.js
index 0cfa009d7cec513722b36fc7eeae12cc40a3fb6b..027f9d264f3f55d31f4f5ade6f4caff5cea80aa6 100644
--- a/packages/rocketchat-theme/package.js
+++ b/packages/rocketchat-theme/package.js
@@ -46,9 +46,8 @@ Package.onUse(function(api) {
 			return 'i18n/' + filename;
 		}
 	}));
-	api.use('tap:i18n@1.6.1', ['client', 'server']);
-	api.imply('tap:i18n');
-	api.addFiles(tapi18nFiles, ['client', 'server']);
+	api.use('tap:i18n');
+	api.addFiles(tapi18nFiles);
 });
 
 Npm.depends({
diff --git a/packages/rocketchat-theme/server/variables.coffee b/packages/rocketchat-theme/server/variables.coffee
old mode 100644
new mode 100755
index 9830698b0e872f2eda6fd872adff964ed2325ea1..3a0557a4e66ea266a9d58bf37d6be00e8b98c75d
--- a/packages/rocketchat-theme/server/variables.coffee
+++ b/packages/rocketchat-theme/server/variables.coffee
@@ -1,21 +1,30 @@
-RocketChat.theme.addPublicColor "content-background-color", "#FFF"
-RocketChat.theme.addPublicColor "primary-background-color", "#04436A"
-RocketChat.theme.addPublicColor "secondary-background-color", "#F4F4F4"
-RocketChat.theme.addPublicColor "tertiary-background-color", "#EAEAEA"
+RocketChat.theme.addPublicColor "primary-background-color", "#04436a"
 RocketChat.theme.addPublicColor "primary-font-color", "#444444"
-RocketChat.theme.addPublicColor "secondary-font-color", "#7F7F7F"
+RocketChat.theme.addPublicColor "secondary-background-color", "#f4f4f4"
+RocketChat.theme.addPublicColor "secondary-font-color", "#7f7f7f"
+RocketChat.theme.addPublicColor "tertiary-background-color", "#eaeaea"
 RocketChat.theme.addPublicColor "tertiary-font-color", "rgba(255, 255, 255, 0.6)"
+RocketChat.theme.addPublicColor "quaternary-font-color", "#ffffff"
+
+RocketChat.theme.addPublicColor "action-buttons-color", "#13679a"
+RocketChat.theme.addPublicColor "active-channel-background-color", "rgba(255, 255, 255, 0.075)"
+RocketChat.theme.addPublicColor "active-channel-font-color", "rgba(255, 255, 255, 0.75)"
+RocketChat.theme.addPublicColor "blockquote-background", "#cccccc"
+RocketChat.theme.addPublicColor "clean-buttons-color", "rgba(0, 0, 0, 0.25)"
+RocketChat.theme.addPublicColor "code-background", "#f8f8f8"
+RocketChat.theme.addPublicColor "code-border", "#cccccc"
+RocketChat.theme.addPublicColor "code-color", "#333333"
+RocketChat.theme.addPublicColor "content-background-color", "#ffffff"
+RocketChat.theme.addPublicColor "custom-scrollbar-color", "rgba(255, 255, 255, 0.05)"
+RocketChat.theme.addPublicColor "info-active-font-color", "#ff0000"
+RocketChat.theme.addPublicColor "info-font-color", "#aaaaaa"
 RocketChat.theme.addPublicColor "input-font-color", "rgba(255, 255, 255, 0.85)"
-RocketChat.theme.addPublicColor "link-font-color", "#008CE3"
-RocketChat.theme.addPublicColor "info-font-color", "#AAAAAA"
-RocketChat.theme.addPublicColor "info-active-font-color", "#FF0000"
-RocketChat.theme.addPublicColor "smallprint-font-color", "#C2E7FF"
-RocketChat.theme.addPublicColor "smallprint-hover-color", "#FFFFFF"
-RocketChat.theme.addPublicColor "status-online", "#35AC19"
+RocketChat.theme.addPublicColor "link-font-color", "#008ce3"
+RocketChat.theme.addPublicColor "message-hover-background-color", "#f9f9f9"
+RocketChat.theme.addPublicColor "smallprint-font-color", "#c2e7ff"
+RocketChat.theme.addPublicColor "smallprint-hover-color", "#ffffff"
+RocketChat.theme.addPublicColor "status-away", "#fcb316"
+RocketChat.theme.addPublicColor "status-busy", "#d30230"
 RocketChat.theme.addPublicColor "status-offline", "rgba(150, 150, 150, 0.50)"
-RocketChat.theme.addPublicColor "status-busy", "#D30230"
-RocketChat.theme.addPublicColor "status-away", "#FCB316"
-RocketChat.theme.addPublicColor "code-background", "#F8F8F8"
-RocketChat.theme.addPublicColor "code-border", "#CCC"
-RocketChat.theme.addPublicColor "code-color", "#333"
-RocketChat.theme.addPublicColor "blockquote-background", "#CCC"
+RocketChat.theme.addPublicColor "status-online", "#35ac19"
+RocketChat.theme.addPublicColor "unread-notification-color", "#1dce73"
diff --git a/packages/rocketchat-ui-account/account/accountProfile.coffee b/packages/rocketchat-ui-account/account/accountProfile.coffee
index 78c1828d504c84c7ada2aef2bddd4d27bd7c23b0..8895b85c3445634548329a6f189631e9ab316ecb 100644
--- a/packages/rocketchat-ui-account/account/accountProfile.coffee
+++ b/packages/rocketchat-ui-account/account/accountProfile.coffee
@@ -7,7 +7,7 @@ Template.accountProfile.helpers
 		return _.sortBy(result, 'key')
 
 	userLanguage: (key) ->
-		return (localStorage.getItem('userLanguage') or defaultUserLanguage())?.split('-').shift().toLowerCase() is key
+		return (Meteor.user().language or defaultUserLanguage())?.split('-').shift().toLowerCase() is key
 
 	realname: ->
 		return Meteor.user().name
@@ -106,3 +106,9 @@ Template.accountProfile.onRendered ->
 Template.accountProfile.events
 	'click .submit button': (e, t) ->
 		t.save()
+	'click .logoutOthers button': (event, templateInstance) ->
+		Meteor.logoutOtherClients (error) -> 
+			if error
+				toastr.error error.reason
+			else
+				toastr.success t('Logged_out_of_other_clients_successfully')
diff --git a/packages/rocketchat-ui-account/account/accountProfile.html b/packages/rocketchat-ui-account/account/accountProfile.html
index 8a6dbfab5d4c037d88e78c0c75c1953d7d553435..b407102a772b906578e90b25e278db53f7cbc0ec 100644
--- a/packages/rocketchat-ui-account/account/accountProfile.html
+++ b/packages/rocketchat-ui-account/account/accountProfile.html
@@ -59,6 +59,9 @@
 				<div class="submit">
 					<button class="button"><i class="icon-send"></i><span>{{_ "Save_changes"}}</span></button>
 				</div>
+				<div class="logoutOthers">
+					<button class="button">{{_ "Logout_Others"}}</button>	
+				</div>
 			</div>
 		</div>
 	</section>
diff --git a/packages/rocketchat-ui-account/package.js b/packages/rocketchat-ui-account/package.js
index 77b86dc6268700c6db01d19bc64cd4980fade8e7..5e818f1b6b8e320b9a2926903ec3d343474ba5fe 100644
--- a/packages/rocketchat-ui-account/package.js
+++ b/packages/rocketchat-ui-account/package.js
@@ -18,7 +18,7 @@ Package.onUse(function(api) {
 		'templating',
 		'coffeescript',
 		'underscore',
-		'rocketchat:lib@0.0.1'
+		'rocketchat:lib'
 	]);
 
 	api.addFiles('account/account.html', 'client');
@@ -36,4 +36,4 @@ Package.onUse(function(api) {
 	api.addFiles('account/avatar/prompt.coffee', 'client');
 
 	// api.addAssets('styles/side-nav.less', 'client');
-});
\ No newline at end of file
+});
diff --git a/packages/rocketchat-ui-admin/admin/admin.coffee b/packages/rocketchat-ui-admin/admin/admin.coffee
index 4e215e45f5e737885357f9887e83873c79436094..b637991cd3278ef4aa07ebb40cbb27213766e008 100644
--- a/packages/rocketchat-ui-admin/admin/admin.coffee
+++ b/packages/rocketchat-ui-admin/admin/admin.coffee
@@ -1,12 +1,42 @@
+@TempSettings = new Meteor.Collection null
+@Settings.find().observe
+	added: (data) ->
+		TempSettings.insert data
+	changed: (data) ->
+		TempSettings.update data._id, data
+	removed: (data) ->
+		TempSettings.remove data._id
+
+
 Template.admin.helpers
+	languages: ->
+		languages = TAPi18n.getLanguages()
+		result = []
+		for key, language of languages
+			result.push _.extend(language, { key: key })
+		result = _.sortBy(result, 'key')
+		result.unshift {
+			"name": "Default",
+			"en": "Default",
+			"key": ""
+		}
+		return result;
+
+	appLanguage: (key) ->
+		if !key
+			return !RocketChat.settings.get('Language')
+		selected = (RocketChat.settings.get('Language'))?.split('-').shift().toLowerCase() is key
+		return selected
+
 	group: ->
 		group = FlowRouter.getParam('group')
-		group ?= Settings.findOne({ type: 'group' })?._id
-		return Settings.findOne { _id: group, type: 'group' }
+		group ?= TempSettings.findOne({ type: 'group' })?._id
+		return TempSettings.findOne { _id: group, type: 'group' }
 	sections: ->
 		group = FlowRouter.getParam('group')
-		group ?= Settings.findOne({ type: 'group' })?._id
-		settings = Settings.find({ group: group }, {sort: {section: 1, i18nLabel: 1}}).fetch()
+		group ?= TempSettings.findOne({ type: 'group' })?._id
+		settings = TempSettings.find({ group: group }, {sort: {section: 1, sorter: 1, i18nLabel: 1}}).fetch()
+
 		sections = {}
 		for setting in settings
 			sections[setting.section or ''] ?= []
@@ -20,6 +50,49 @@ Template.admin.helpers
 
 		return sectionsArray
 
+	isDisabled: ->
+		if not @enableQuery?
+			return {}
+
+		if _.isString(@enableQuery)
+			enableQuery = JSON.parse(@enableQuery)
+		else
+			enableQuery = @enableQuery
+
+		if not _.isArray(enableQuery)
+			enableQuery = [enableQuery]
+
+		found = 0
+		for item in enableQuery
+			if TempSettings.findOne(item)?
+				found++
+
+		return if found is enableQuery.length then {} else {disabled: 'disabled'}
+
+	hasChanges: (section) ->
+		group = FlowRouter.getParam('group')
+
+		query =
+			group: group
+			changed: true
+
+		if section?
+			if section is ''
+				query.$or = [
+					{section: ''}
+					{section: {$exists: false}}
+				]
+			else
+				query.section = section
+
+		return TempSettings.find(query).count() > 0
+
+	translateSection: (section) ->
+		if section.indexOf(':') > -1
+			return section
+
+		return t(section)
+
 	flexOpened: ->
 		return 'opened' if RocketChat.TabBar.isFlexOpen()
 	arrowPosition: ->
@@ -44,28 +117,39 @@ Template.admin.helpers
 		return Random.id()
 
 Template.admin.events
+	"change .input-monitor": (e, t) ->
+		value = _.trim $(e.target).val()
+
+		switch @type
+			when 'int'
+				value = parseInt(value)
+			when 'boolean'
+				value = value is "1"
+
+		TempSettings.update {_id: @_id},
+			$set:
+				value: value
+				changed: Settings.findOne(@_id).value isnt value
+
 	"click .submit .save": (e, t) ->
 		group = FlowRouter.getParam('group')
-		settings = Settings.find({ group: group }).fetch()
-		updateSettings = []
-		for setting in settings
-			value = null
-			if setting.type is 'string'
-				value = _.trim(t.$("[name=#{setting._id}]").val())
-			else if setting.type is 'int'
-				value = parseInt(_.trim(t.$("[name=#{setting._id}]").val()))
-			else if setting.type is 'boolean' and t.$("[name=#{setting._id}]:checked").length
-				value = if t.$("[name=#{setting._id}]:checked").val() is "1" then true else false
-			else if setting.type is 'color'
-				value = _.trim(t.$("[name=#{setting._id}]").val())
-			else if setting.type is 'select'
-				value = t.$("[name=#{setting._id}]").val()
-
-			if value?
-				updateSettings.push { _id: setting._id, value: value }
-
-		if not _.isEmpty updateSettings
-			RocketChat.settings.batchSet updateSettings, (err, success) ->
+
+		query =
+			group: group
+			changed: true
+
+		if @section is ''
+			query.$or = [
+				{section: ''}
+				{section: {$exists: false}}
+			]
+		else
+			query.section = @section
+
+		settings = TempSettings.find(query, {fields: {_id: 1, value: 1}}).fetch()
+
+		if not _.isEmpty settings
+			RocketChat.settings.batchSet settings, (err, success) ->
 				return toastr.error TAPi18n.__ 'Error_updating_settings' if err
 				toastr.success TAPi18n.__ 'Settings_updated'
 
@@ -115,17 +199,17 @@ Template.admin.events
 		for blob in files
 			toastr.info TAPi18n.__ 'Uploading_file'
 
-			if @fileConstraints.contentType isnt blob.type
-				toastr.error TAPi18n.__ 'Invalid_file_type'
-				return
+			# if @fileConstraints.contentType isnt blob.type
+			# 	toastr.error blob.type, TAPi18n.__ 'Invalid_file_type'
+			# 	return
 
 			reader = new FileReader()
 			reader.readAsBinaryString(blob)
 			reader.onloadend = =>
 				Meteor.call 'setAsset', reader.result, blob.type, @asset, (err, data) ->
 					if err?
-						toastr.error TAPi18n.__ err.error
-						console.log err.error
+						toastr.error err.reason, TAPi18n.__ err.error
+						console.log err
 						return
 
 					toastr.success TAPi18n.__ 'File_uploaded'
@@ -159,10 +243,10 @@ Template.admin.onRendered ->
 
 	Meteor.setTimeout ->
 		$('input.minicolors').minicolors({theme: 'rocketchat'})
-	, 500
+	, 1000
 
 	Tracker.autorun ->
 		FlowRouter.watchPathChange()
 		Meteor.setTimeout ->
 			$('input.minicolors').minicolors({theme: 'rocketchat'})
-		, 200
+		, 400
diff --git a/packages/rocketchat-ui-admin/admin/admin.html b/packages/rocketchat-ui-admin/admin/admin.html
index 492d539321b126e8c1e50d1cc0e4c516d71362f8..195d38f296b7d9fcb2301c38f17815d49adbf818 100644
--- a/packages/rocketchat-ui-admin/admin/admin.html
+++ b/packages/rocketchat-ui-admin/admin/admin.html
@@ -24,7 +24,7 @@
 							{{#if section}}
 								<div class="section-title">
 									<div class="section-title-text">
-										{{_ section}}
+										{{translateSection section}}
 									</div>
 									<div class="section-title-right">
 										<button class="button secondary expand"><span>{{_ "Expand"}}</span></button>
@@ -42,40 +42,48 @@
 									{{/if}}
 								{{/if}}
 								{{#each settings}}
-									<div class="input-line double-col">
+									<div class="input-line double-col {{#if changed}}setting-changed{{/if}}" {{isDisabled}}>
 										<label>{{label}}</label>
 										<div>
 											{{#if $eq type 'string'}}
 												{{#if multiline}}
-													<textarea name="{{_id}}" rows="4" style="height: auto">{{value}}</textarea>
+													<textarea class="input-monitor" name="{{_id}}" rows="4" style="height: auto" {{isDisabled}}>{{value}}</textarea>
 												{{else}}
-													<input type="text" name="{{_id}}" value="{{value}}" placeholder="{{placeholder}}" />
+													<input class="input-monitor" type="text" name="{{_id}}" value="{{value}}" placeholder="{{placeholder}}" {{isDisabled}}/>
 												{{/if}}
 											{{/if}}
 
 											{{#if $eq type 'int'}}
-												<input type="number" name="{{_id}}" value="{{value}}" placeholder="{{placeholder}}" />
+												<input class="input-monitor" type="number" name="{{_id}}" value="{{value}}" placeholder="{{placeholder}}" {{isDisabled}}/>
 											{{/if}}
 
 											{{#if $eq type 'boolean'}}
-												<label><input type="radio" name="{{_id}}" value="1" checked="{{$eq value true}}" /> {{_ "True"}}</label>
-												<label><input type="radio" name="{{_id}}" value="0" checked="{{$eq value false}}" /> {{_ "False"}}</label>
+												<label><input class="input-monitor" type="radio" name="{{_id}}" value="1" checked="{{$eq value true}}" {{isDisabled}}/> {{_ "True"}}</label>
+												<label><input class="input-monitor" type="radio" name="{{_id}}" value="0" checked="{{$eq value false}}" {{isDisabled}}/> {{_ "False"}}</label>
 											{{/if}}
 
 											{{#if $eq type 'select'}}
-												<select name="{{_id}}">
+												<select class="input-monitor" name="{{_id}}" {{isDisabled}}>
 													{{#each values}}
 														<option value="{{key}}" selected="{{selectedOption ../_id key}}">{{_ i18nLabel}}</option>
 													{{/each}}
 												</select>
 											{{/if}}
 
+											{{#if $eq type 'language'}}
+												<select class="input-monitor" name="{{_id}}" {{isDisabled}}>
+													{{#each languages}}
+													<option value="{{key}}" selected="{{appLanguage key}}" dir="auto">{{name}}</option>
+													{{/each}}
+												</select>
+											{{/if}}
+
 											{{#if $eq type 'color'}}
-												<input type="text" class="minicolors" name="{{_id}}" value="{{value}}" />
+												<input class="input-monitor minicolors" type="text" name="{{_id}}" value="{{value}}" {{isDisabled}}/>
 											{{/if}}
 
 											{{#if $eq type 'action'}}
-												<button type="button" class="button primary action" data-setting="{{_id}}" data-action="{{value}}">{{_ actionText}}</button>
+												<button type="button" class="button primary action" data-setting="{{_id}}" data-action="{{value}}" {{isDisabled}}>{{_ actionText}}</button>
 											{{/if}}
 
 											{{#if $eq type 'asset'}}
@@ -101,6 +109,9 @@
 											{{#if description}}
 												<div class="settings-description">{{{description}}}</div>
 											{{/if}}
+											{{#if alert}}
+												<div class="settings-alert"><i class="icon-attention"></i>{{{_ alert}}}</div>
+											{{/if}}
 										</div>
 									</div>
 								{{/each}}
@@ -112,6 +123,12 @@
 										</div>
 									{{/if}}
 								{{/if}}
+
+								{{#if hasChanges section}}
+									<div class="submit">
+										<button class="button save"><i class="icon-send"></i><span>{{_ "Save_changes"}}</span></button>
+									</div>
+								{{/if}}
 							</div>
 						</div>
 					{{/each}}
@@ -120,7 +137,6 @@
 						{{#if $eq group._id 'Accounts'}}
 							<button class="button secondary add-custom-oauth"><span>{{_ "Add_custom_oauth"}}</span></button>
 						{{/if}}
-						<button class="button save"><i class="icon-send"></i><span>{{_ "Save_changes"}}</span></button>
 					</div>
 				</div>
 			{{/unless}}
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-admin/admin/users/adminUsers.coffee b/packages/rocketchat-ui-admin/admin/users/adminUsers.coffee
index 098901fb5b2a58ce5841cf2e03d072f40cbb8288..e09e66e2a09394293e03edf38fbbce508c348542 100644
--- a/packages/rocketchat-ui-admin/admin/users/adminUsers.coffee
+++ b/packages/rocketchat-ui-admin/admin/users/adminUsers.coffee
@@ -37,7 +37,23 @@ Template.adminUsers.onCreated ->
 	@filter = new ReactiveVar ''
 	@ready = new ReactiveVar true
 
-	RocketChat.TabBar.addButton({ id: 'invite-user', i18nTitle: t('Invite_Users'), icon: 'icon-plus', template: 'adminInviteUser', order: 1 })
+	RocketChat.TabBar.addButton({
+		groups: ['adminusers', 'adminusers-selected'],
+		id: 'invite-user',
+		i18nTitle: 'Invite_Users',
+		icon: 'icon-plus',
+		template: 'adminInviteUser',
+		order: 1
+	})
+
+	RocketChat.TabBar.addButton({
+		groups: ['adminusers-selected']
+		id: 'admin-user-info',
+		i18nTitle: 'User_Info',
+		icon: 'icon-user',
+		template: 'adminUserInfo',
+		order: 2
+	})
 
 	@autorun ->
 		filter = instance.filter.get()
@@ -49,11 +65,10 @@ Template.adminUsers.onCreated ->
 		if Session.get 'adminSelectedUser'
 			channelSubscription = instance.subscribe 'userChannels', Session.get 'adminSelectedUser'
 			RocketChat.TabBar.setData Meteor.users.findOne Session.get 'adminSelectedUser'
-			RocketChat.TabBar.addButton({ id: 'user-info', i18nTitle: t('User_Info'), icon: 'icon-user', template: 'adminUserInfo', order: 2 })
-			# RocketChat.TabBar.addButton({ id: 'user-channel', i18nTitle: t('User_Channels'), icon: 'icon-hash', template: 'adminUserChannels', order: 3 })
+
+			RocketChat.TabBar.showGroup 'adminusers-selected'
 		else
-			RocketChat.TabBar.reset()
-			RocketChat.TabBar.addButton({ id: 'invite-user', i18nTitle: t('Invite_Users'), icon: 'icon-plus', template: 'adminInviteUser', order: 1 })
+			RocketChat.TabBar.showGroup 'adminusers'
 
 	@users = ->
 		filter = _.trim instance.filter?.get()
@@ -89,8 +104,8 @@ Template.adminUsers.events
 
 	'click .user-info': (e) ->
 		e.preventDefault()
-		Session.set 'adminSelectedUser', $(e.currentTarget).data('id')
-		Session.set 'showUserInfo', Meteor.users.findOne($(e.currentTarget).data('id'))?.username or true
+		Session.set 'adminSelectedUser', @_id
+		Session.set 'showUserInfo', Meteor.users.findOne(@_id)?.username or true
 		RocketChat.TabBar.setTemplate 'adminUserInfo'
 		RocketChat.TabBar.openFlex()
 
diff --git a/packages/rocketchat-ui-admin/admin/users/adminUsers.html b/packages/rocketchat-ui-admin/admin/users/adminUsers.html
index 828ca152200bcf67a18da83f9da51fe2d8a42ee6..aa410e3c9876abec3c1e96930894b7f5398d2db3 100644
--- a/packages/rocketchat-ui-admin/admin/users/adminUsers.html
+++ b/packages/rocketchat-ui-admin/admin/users/adminUsers.html
@@ -32,7 +32,7 @@
 						</thead>
 						<tbody>
 							{{#each users}}
-							<tr class="user-info" data-id="{{_id}}">
+							<tr class="user-info">
 								<td>
 									<div class="user-image status-{{status}}">
 										{{> avatar username=username}}
diff --git a/packages/rocketchat-ui-admin/package.js b/packages/rocketchat-ui-admin/package.js
index bebed82fd631dcbe5bf009830b426ab110f8d8c9..6fc80872456d68c7c0a8cfe2dc00290c20e22c8d 100644
--- a/packages/rocketchat-ui-admin/package.js
+++ b/packages/rocketchat-ui-admin/package.js
@@ -18,7 +18,7 @@ Package.onUse(function(api) {
 		'templating',
 		'coffeescript',
 		'underscore',
-		'rocketchat:lib@0.0.1'
+		'rocketchat:lib'
 	]);
 
 	// template files
diff --git a/packages/rocketchat-ui-flextab/flex-tab/flexTabBar.coffee b/packages/rocketchat-ui-flextab/flex-tab/flexTabBar.coffee
index 0177eb907c6625b535c8debaf023b59c00065d17..f308646ffbbbcdf3563cbdfc8c0696ab979e1c8f 100644
--- a/packages/rocketchat-ui-flextab/flex-tab/flexTabBar.coffee
+++ b/packages/rocketchat-ui-flextab/flex-tab/flexTabBar.coffee
@@ -2,26 +2,41 @@ Template.flexTabBar.helpers
 	active: ->
 		return 'active' if @template is RocketChat.TabBar.getTemplate() and RocketChat.TabBar.isFlexOpen()
 	buttons: ->
-		RocketChat.TabBar.getButtons()
 		return RocketChat.TabBar.getButtons()
 	title: ->
 		return t(@i18nTitle) or @title
+	visible: ->
+		if @groups.indexOf(RocketChat.TabBar.getVisibleGroup()) is -1
+			return 'hidden'
 
 Template.flexTabBar.events
 	'click .tab-button': (e, t) ->
 		e.preventDefault()
 
-		if RocketChat.TabBar.isFlexOpen() and RocketChat.TabBar.getTemplate() is $(e.currentTarget).data('template')
+		if RocketChat.TabBar.isFlexOpen() and RocketChat.TabBar.getTemplate() is @template
 			RocketChat.TabBar.closeFlex()
 			$('.flex-tab').css('max-width', '')
 		else
-			width = $(e.currentTarget).data('width')
-
-			if width?
-				$('.flex-tab').css('max-width', "#{width}px")
+			if @width?
+				$('.flex-tab').css('max-width', "#{@width}px")
 			else
 				$('.flex-tab').css('max-width', '')
 
-			RocketChat.TabBar.setTemplate $(e.currentTarget).data('template'), ->
+			RocketChat.TabBar.setTemplate @template, ->
 				$('.flex-tab')?.find("input[type='text']:first")?.focus()
 				$('.flex-tab .content')?.scrollTop(0)
+
+Template.flexTabBar.onCreated ->
+	# close flex if the visible group changed and the opened template is not in the new visible group
+	@autorun =>
+		visibleGroup = RocketChat.TabBar.getVisibleGroup()
+
+		Tracker.nonreactive =>
+			openedTemplate = RocketChat.TabBar.getTemplate()
+			exists = false
+			RocketChat.TabBar.getButtons().forEach (button) ->
+				if button.groups.indexOf(visibleGroup) isnt -1 and openedTemplate is button.template
+					exists = true
+
+			unless exists
+				RocketChat.TabBar.closeFlex()
diff --git a/packages/rocketchat-ui-flextab/flex-tab/flexTabBar.html b/packages/rocketchat-ui-flextab/flex-tab/flexTabBar.html
index 8a971f49990e49f7ce8a19fc3c12ec862a4cde7c..10baeed54dbef01f0e924bb208c791ea127766a2 100644
--- a/packages/rocketchat-ui-flextab/flex-tab/flexTabBar.html
+++ b/packages/rocketchat-ui-flextab/flex-tab/flexTabBar.html
@@ -1,6 +1,6 @@
 <template name="flexTabBar">
 	{{#each buttons}}
-		<div class="tab-button {{active}}" data-template="{{template}}" data-width="{{width}}" title="{{title}}">
+		<div class="tab-button {{active}} {{visible}}" title="{{title}}">
 			<i class="{{icon}}" aria-label="{{title}}" role="button" tabindex="0"></i>
 		</div>
 	{{/each}}
diff --git a/packages/rocketchat-ui-flextab/flex-tab/tabs/messageSearch.coffee b/packages/rocketchat-ui-flextab/flex-tab/tabs/messageSearch.coffee
index 59d128eec8e2d0bbcd1374316d1226a0cf06d34d..0d3113623d8b2de24d109b906c8cc6c0ddfedc83 100644
--- a/packages/rocketchat-ui-flextab/flex-tab/tabs/messageSearch.coffee
+++ b/packages/rocketchat-ui-flextab/flex-tab/tabs/messageSearch.coffee
@@ -1,3 +1,16 @@
+Meteor.startup ->
+	RocketChat.MessageAction.addButton
+		id: 'jump-to-search-message'
+		icon: 'icon-right-hand'
+		i18nLabel: 'Jump_to_message'
+		action: (event, instance) ->
+			message = @_arguments[1]
+			$('.message-dropdown:visible').hide()
+			RoomHistoryManager.getSurroundingMessages(message, 50)
+
+		order: 100
+
+
 Template.messageSearch.helpers
 	tSearchMessages: ->
 		return t('Search_Messages')
@@ -5,6 +18,15 @@ Template.messageSearch.helpers
 	searchResultMessages: ->
 		return Template.instance().searchResult.get()?.messages
 
+	hasMore: ->
+		return Template.instance().hasMore.get()
+
+	currentSearchTerm: ->
+		return Template.instance().currentSearchTerm.get()
+
+	ready: ->
+		return Template.instance().ready.get()
+
 Template.messageSearch.events
 	"keydown #message-search": (e) ->
 		if e.keyCode is 13
@@ -12,20 +34,56 @@ Template.messageSearch.events
 
 	"keyup #message-search": _.debounce (e, t) ->
 		value = e.target.value.trim()
-		if value is '' and t.currentSearchTerm
-			t.currentSearchTerm = ''
+		if value is '' and t.currentSearchTerm.get()
+			t.currentSearchTerm.set ''
 			t.searchResult.set undefined
+			t.hasMore.set false
 			return
-		else if value is t.currentSearchTerm
+		else if value is t.currentSearchTerm.get()
 			return
 
-		Tracker.nonreactive ->
-			Meteor.call 'messageSearch', value, Session.get('openedRoom'), (error, result) ->
-				if result? and (result.messages?.length > 0 or result.users?.length > 0 or result.channels?.length > 0)
-					t.searchResult.set result
-					t.currentSearchTerm = value
+		t.hasMore.set true
+		t.limit.set 20
+		t.search()
 	, 500
 
+	'click .message-cog': (e, t) ->
+		e.stopPropagation()
+		e.preventDefault()
+		message_id = $(e.currentTarget).closest('.message').attr('id')
+		$('.message-dropdown:visible').hide()
+		$(".search-messages-list \##{message_id} .message-dropdown").remove()
+		message = _.findWhere(t.searchResult.get()?.messages, (message) -> return message._id is message_id)
+		actions = RocketChat.MessageAction.getButtons message
+		el = Blaze.toHTMLWithData Template.messageDropdown, { actions: actions }
+		$(".search-messages-list \##{message_id} .message-cog-container").append el
+		dropDown = $(".search-messages-list \##{message_id} .message-dropdown")
+		dropDown.show()
+
+	'scroll .content': _.throttle (e, t) ->
+		if e.target.scrollTop >= e.target.scrollHeight - e.target.clientHeight
+			t.limit.set(t.limit.get() + 20)
+			t.search()
+	, 200
+
 Template.messageSearch.onCreated ->
-	this.currentSearchTerm = ''
-	this.searchResult = new ReactiveVar
+	@currentSearchTerm = new ReactiveVar ''
+	@searchResult = new ReactiveVar
+
+	@hasMore = new ReactiveVar true
+	@limit = new ReactiveVar 20
+	@ready = new ReactiveVar true
+
+	@search = =>
+		@ready.set false
+		value = @$('#message-search').val()
+		Tracker.nonreactive =>
+			Meteor.call 'messageSearch', value, Session.get('openedRoom'), @limit.get(), (error, result) =>
+				@currentSearchTerm.set value
+				@ready.set true
+				if result? and (result.messages?.length > 0 or result.users?.length > 0 or result.channels?.length > 0)
+					@searchResult.set result
+					if result.messages?.length + result.users?.length + result.channels?.length < @limit.get()
+						@hasMore.set false
+				else
+					@searchResult.set()
diff --git a/packages/rocketchat-ui-flextab/flex-tab/tabs/messageSearch.html b/packages/rocketchat-ui-flextab/flex-tab/tabs/messageSearch.html
index 25931d649876b62087e70689c6027153ed79c340..3b31486a97ab9a8cd4768b1b81fabfaad2d2b07c 100644
--- a/packages/rocketchat-ui-flextab/flex-tab/tabs/messageSearch.html
+++ b/packages/rocketchat-ui-flextab/flex-tab/tabs/messageSearch.html
@@ -1,17 +1,34 @@
 <template name="messageSearch">
 	<div class="content">
-		<div class="control">
-			<form class="search-form" role="form">
-				<div class="input-line search">
-					<input type="text" id="message-search" class="search" placeholder="{{tSearchMessages}}" autocomplete="off" />
-					<i class="icon-right-open-small"></i>
-				</div>
-			</form>
+		<div class="list-view search-messages-list">
+			<div class="control">
+				<form class="search-form" role="form">
+					<div class="input-line search">
+						<input type="text" id="message-search" class="search" placeholder="{{tSearchMessages}}" autocomplete="off" />
+						<i class="icon-right-open-small"></i>
+					</div>
+				</form>
+			</div>
+			<ul class="list clearfix">
+				{{#if currentSearchTerm}}
+					{{#if searchResultMessages}}
+						{{#each searchResultMessages}}
+							{{#nrr nrrargs 'message' .}}{{/nrr}}
+						{{/each}}
+						{{#if hasMore}}
+							<li class="load-more">
+								{{#if ready}}
+									<a href="">{{_ "Has_more"}}...</a>
+								{{else}}
+									<div class="load-more-loading">{{_ "Loading..."}}</div>
+								{{/if}}
+							</li>
+						{{/if}}
+					{{else}}
+						<h2 class="no-results">{{_ "No_results_found"}}</h2>
+					{{/if}}
+				{{/if}}
+			</ul>
 		</div>
-		<ul>
-			{{#each searchResultMessages}}
-				{{#nrr nrrargs 'message' .}}{{/nrr}}
-			{{/each}}
-		</ul>
 	</div>
 </template>
diff --git a/packages/rocketchat-ui-flextab/flex-tab/tabs/uploadedFilesList.coffee b/packages/rocketchat-ui-flextab/flex-tab/tabs/uploadedFilesList.coffee
index d46b484db5d044525abc90a2954d89a73e71b51f..1f8b59a0cbf003f6c94bbfa5ebeb2dec848752d8 100644
--- a/packages/rocketchat-ui-flextab/flex-tab/tabs/uploadedFilesList.coffee
+++ b/packages/rocketchat-ui-flextab/flex-tab/tabs/uploadedFilesList.coffee
@@ -1,32 +1,46 @@
 roomFiles = new Mongo.Collection 'room_files'
 
 Template.uploadedFilesList.helpers
-  files: ->
-    return roomFiles.find({ rid: this.rid }).fetch()
+	files: ->
+		return roomFiles.find({ rid: @rid }, { sort: {uploadedAt : -1} }).fetch()
 
-  hasFiles: ->
-    return roomFiles.find({ rid: this.rid }).count() > 0
+	hasFiles: ->
+		return roomFiles.find({ rid: @rid }).count() > 0
 
-  getFileIcon: (type) ->
-    if type.match(/^image\/.+$/)
-      return 'icon-picture'
+	hasMore: ->
+		return Template.instance().hasMore.get()
 
-    return 'icon-docs'
+	getFileIcon: (type) ->
+		if type.match(/^image\/.+$/)
+			return 'icon-picture'
 
-  customClassForFileType: ->
-    if this.type.match(/^image\/.+$/)
-      return 'room-files-swipebox'
+		return 'icon-docs'
 
-  escapedName: ->
-    return s.escapeHTML @name
+	customClassForFileType: ->
+		if @type.match(/^image\/.+$/)
+			return 'room-files-swipebox'
+
+	escapedName: ->
+		return s.escapeHTML @name
 
 Template.uploadedFilesList.events
-  'click .room-file-item': (e, t) ->
-    if $(e.currentTarget).siblings('.icon-picture').length
-      e.preventDefault()
+	'click .room-file-item': (e, t) ->
+		if $(e.currentTarget).siblings('.icon-picture').length
+			e.preventDefault()
+
+	'scroll .content': _.throttle (e, t) ->
+		if e.target.scrollTop >= e.target.scrollHeight - e.target.clientHeight
+			t.limit.set(t.limit.get() + 50)
+	, 200
 
 Template.uploadedFilesList.onCreated ->
-  this.subscribe 'roomFiles', Template.currentData().rid
+	rid = Template.currentData().rid
+	@hasMore = new ReactiveVar true
+	@limit = new ReactiveVar 50
+	@autorun =>
+		@subscribe 'roomFiles', rid, @limit.get(), =>
+			if roomFiles.find({ rid: rid }).fetch().length < @limit.get()
+				@hasMore.set false
 
 Template.uploadedFilesList.onRendered ->
-  $('.room-files-swipebox').swipebox()
+	$('.room-files-swipebox').swipebox()
diff --git a/packages/rocketchat-ui-flextab/flex-tab/tabs/uploadedFilesList.html b/packages/rocketchat-ui-flextab/flex-tab/tabs/uploadedFilesList.html
index f50af8c5ad994150fafe53cc86205d511b28188b..2ac193623080ad8255ebe1c3769357e06f3db615 100644
--- a/packages/rocketchat-ui-flextab/flex-tab/tabs/uploadedFilesList.html
+++ b/packages/rocketchat-ui-flextab/flex-tab/tabs/uploadedFilesList.html
@@ -1,27 +1,33 @@
 <template name="uploadedFilesList">
-  <div class="content">
-    <div class="list-view uploaded-files-list">
-      <div class="status">
-        <h2>{{_ "Room_uploaded_file_list"}}</h2>
-      </div>
-      {{#if Template.subscriptionsReady}}
-        {{#if hasFiles }}
-          <ul class='list clearfix lines'>
-            {{#each files}}
-              <li>
-                <a title="{{escapedName}}" href="{{url}}" target="_blank" class="room-file-item {{customClassForFileType}}">
-                  <i class="{{getFileIcon type}}"></i>
-                  <p>{{name}}</p>
-                </a>
-              </li>
-            {{/each}}
-          </ul>
-        {{else}}
-          <h2>{{_ "Room_uploaded_file_list_empty"}}</h2>
-        {{/if}}
-      {{else}}
-        <span>{{_ "Loading..."}}</span>
-      {{/if}}
-    </div>
-  </div>
+	<div class="content">
+		<div class="list-view uploaded-files-list">
+			<div class="status">
+				<h2>{{_ "Room_uploaded_file_list"}}</h2>
+			</div>
+			<ul class="list clearfix lines">
+				{{#each files}}
+					<li>
+						<a title="{{escapedName}}" href="{{url}}" target="_blank" class="room-file-item {{customClassForFileType}}">
+							<i class="{{getFileIcon type}}"></i>
+							<p>{{name}}</p>
+						</a>
+					</li>
+				{{/each}}
+				{{#if hasMore}}
+					<li class="load-more">
+						{{#if Template.subscriptionsReady}}
+							<a href="">{{_ "Has_more"}}...</a>
+						{{else}}
+							<div class="load-more-loading">{{_ "Loading..."}}</div>
+						{{/if}}
+					</li>
+				{{/if}}
+			</ul>
+			{{#if Template.subscriptionsReady}}
+				{{#unless hasFiles}}
+					<h2>{{_ "Room_uploaded_file_list_empty"}}</h2>
+				{{/unless}}
+			{{/if}}
+		</div>
+	</div>
 </template>
diff --git a/packages/rocketchat-ui-flextab/flex-tab/tabs/userInfo.coffee b/packages/rocketchat-ui-flextab/flex-tab/tabs/userInfo.coffee
index 341af443b10324f82be702fb82bd022b591c22cf..3c3dc4c6da3a3dd3ac099f8c729043d1f18de2c3 100644
--- a/packages/rocketchat-ui-flextab/flex-tab/tabs/userInfo.coffee
+++ b/packages/rocketchat-ui-flextab/flex-tab/tabs/userInfo.coffee
@@ -31,7 +31,31 @@ Template.userInfo.helpers
 
 	userTime: ->
 		if @utcOffset?
-			return Template.instance().now.get().utcOffset(@utcOffset).format('HH:mm')
+			return Template.instance().now.get().utcOffset(@utcOffset).format('LT')
+
+	canRemoveUser: ->
+		return RocketChat.authz.hasAllPermission('remove-user', Session.get('openedRoom'))
+
+	canMuteUser: ->
+		return RocketChat.authz.hasAllPermission('mute-user', Session.get('openedRoom'))
+
+	userMuted: ->
+		room = ChatRoom.findOne(Session.get('openedRoom'))
+		if _.isArray(room?.muted) and room.muted.indexOf(Session.get('showUserInfo')) isnt -1
+			return true
+		return false
+
+	canSetModerator: ->
+		return RocketChat.authz.hasAllPermission('set-moderator', Session.get('openedRoom'))
+
+	isModerator: ->
+		return !!RoomModeratorsAndOwners.findOne({ rid: Session.get('openedRoom'), "u._id": @user?._id, roles: 'moderator' })
+
+	canSetOwner: ->
+		return RocketChat.authz.hasAllPermission('set-owner', Session.get('openedRoom'))
+
+	isOwner: ->
+		return !!RoomModeratorsAndOwners.findOne({ rid: Session.get('openedRoom'), "u._id": @user?._id, roles: 'owner' })
 
 Template.userInfo.events
 	'click .pvt-msg': (e) ->
@@ -72,6 +96,120 @@ Template.userInfo.events
 	'click .back': (e) ->
 		Session.set('showUserInfo', null)
 
+	'click .remove-user': (e) ->
+		e.preventDefault()
+		rid = Session.get('openedRoom')
+		room = ChatRoom.findOne rid
+		if RocketChat.authz.hasAllPermission('remove-user', rid)
+			swal {
+				title: t('Are_you_sure')
+				text: t('The_user_will_be_removed_from_s', room.name)
+				type: 'warning'
+				showCancelButton: true
+				confirmButtonColor: '#DD6B55'
+				confirmButtonText: t('Yes_remove_user')
+				cancelButtonText: t('Cancel')
+				closeOnConfirm: false
+				html: false
+			}, =>
+				Meteor.call 'removeUserFromRoom', { rid: rid, username: @user.username }, (err, result) ->
+					if err
+						return toastr.error(err.reason or err.message)
+					swal
+						title: t('Removed')
+						text: t('User_has_been_removed_from_s', room.name)
+						type: 'success'
+						timer: 2000
+						showConfirmButton: false
+					Session.set('showUserInfo', null)
+		else
+			toastr.error(TAPi18n.__ 'Not_allowed')
+
+	'click .mute-user': (e) ->
+		e.preventDefault()
+		rid = Session.get('openedRoom')
+		room = ChatRoom.findOne rid
+		if RocketChat.authz.hasAllPermission('mute-user', rid)
+			swal {
+				title: t('Are_you_sure')
+				text: t('The_user_wont_be_able_to_type_in_s', room.name)
+				type: 'warning'
+				showCancelButton: true
+				confirmButtonColor: '#DD6B55'
+				confirmButtonText: t('Yes_mute_user')
+				cancelButtonText: t('Cancel')
+				closeOnConfirm: false
+				html: false
+			}, =>
+				Meteor.call 'muteUserInRoom', { rid: rid, username: @user.username }, (err, result) ->
+					if err
+						return toastr.error(err.reason or err.message)
+					swal
+						title: t('Muted')
+						text: t('User_has_been_muted_in_s', room.name)
+						type: 'success'
+						timer: 2000
+						showConfirmButton: false
+
+	'click .unmute-user': (e, t) ->
+		e.preventDefault()
+		rid = Session.get('openedRoom')
+		room = ChatRoom.findOne rid
+		if RocketChat.authz.hasAllPermission('mute-user', rid)
+			Meteor.call 'unmuteUserInRoom', { rid: rid, username: @user.username }, (err, result) ->
+				if err
+					return toastr.error(err.reason or err.message)
+				toastr.success TAPi18n.__ 'User_unmuted_in_room'
+		else
+			toastr.error(TAPi18n.__ 'Not_allowed')
+
+	'click .set-moderator': (e, t) ->
+		e.preventDefault()
+
+		userModerator = RoomModeratorsAndOwners.findOne({ rid: Session.get('openedRoom'), "u._id": @user._id, roles: 'moderator' }, { fields: { _id: 1 } })
+		unless userModerator?
+			Meteor.call 'addRoomModerator', Session.get('openedRoom'), @user._id, (err, results) =>
+				if err
+					return toastr.error(err.reason or err.message)
+
+				room = ChatRoom.findOne(Session.get('openedRoom'))
+				toastr.success TAPi18n.__ 'User__username__is_now_a_moderator_of__room_name_', { username: @user.username, room_name: room.name }
+
+	'click .unset-moderator': (e, t) ->
+		e.preventDefault()
+
+		userModerator = RoomModeratorsAndOwners.findOne({ rid: Session.get('openedRoom'), "u._id": @user._id, roles: 'moderator' }, { fields: { _id: 1 } })
+		if userModerator?
+			Meteor.call 'removeRoomModerator', Session.get('openedRoom'), @user._id, (err, results) =>
+				if err
+					return toastr.error(err.reason or err.message)
+
+				room = ChatRoom.findOne(Session.get('openedRoom'))
+				toastr.success TAPi18n.__ 'User__username__removed_from__room_name__moderators', { username: @user.username, room_name: room.name }
+
+	'click .set-owner': (e, t) ->
+		e.preventDefault()
+
+		userOwner = RoomModeratorsAndOwners.findOne({ rid: Session.get('openedRoom'), "u._id": @user._id, roles: 'owner' }, { fields: { _id: 1 } })
+		unless userOwner?
+			Meteor.call 'addRoomOwner', Session.get('openedRoom'), @user._id, (err, results) =>
+				if err
+					return toastr.error(err.reason or err.message)
+
+				room = ChatRoom.findOne(Session.get('openedRoom'))
+				toastr.success TAPi18n.__ 'User__username__is_now_a_owner_of__room_name_', { username: @user.username, room_name: room.name }
+
+	'click .unset-owner': (e, t) ->
+		e.preventDefault()
+
+		userOwner = RoomModeratorsAndOwners.findOne({ rid: Session.get('openedRoom'), "u._id": @user._id, roles: 'owner' }, { fields: { _id: 1 } })
+		if userOwner?
+			Meteor.call 'removeRoomOwner', Session.get('openedRoom'), @user._id, (err, results) =>
+				if err
+					return toastr.error(err.reason or err.message)
+
+				room = ChatRoom.findOne(Session.get('openedRoom'))
+				toastr.success TAPi18n.__ 'User__username__removed_from__room_name__owners', { username: @user.username, room_name: room.name }
 
 Template.userInfo.onCreated ->
 	@now = new ReactiveVar moment()
diff --git a/packages/rocketchat-ui-flextab/flex-tab/tabs/userInfo.html b/packages/rocketchat-ui-flextab/flex-tab/tabs/userInfo.html
index 844f5126c3ea39c4fa4691d7687b16cd8056ff47..bad3b31f4786ebbccbd7a98714f4ca2b2d080b01 100644
--- a/packages/rocketchat-ui-flextab/flex-tab/tabs/userInfo.html
+++ b/packages/rocketchat-ui-flextab/flex-tab/tabs/userInfo.html
@@ -30,10 +30,34 @@
 			{{> videoButtons}}
 
 			{{#if showAll}}
-				<button class='button secondary back'><span>{{_ "View_All"}} <i class='icon-angle-right'></i></span></button>
 				{{#if canDirectMessage user.username}}
-				<button class='button pvt-msg'><span><i class='icon-chat'></i> {{_ "Conversation"}}</span></button>
+					<button class='button button-block pvt-msg'><span><i class='icon-chat'></i> {{_ "Conversation"}}</span></button>
+				{{/if}}
+				{{#if canSetOwner}}
+					{{#if isOwner}}
+						<button class="button button-block unset-owner lightblue"><span>{{_ "Remove_as_owner"}}</span></button>
+					{{else}}
+						<button class="button button-block set-owner lightblue"><span>{{_ "Set_as_owner"}}</span></button>
+					{{/if}}
+				{{/if}}
+				{{#if canSetModerator}}
+					{{#if isModerator}}
+						<button class="button button-block unset-moderator lightblue"><span>{{_ "Remove_as_moderator"}}</span></button>
+					{{else}}
+						<button class="button button-block set-moderator lightblue"><span>{{_ "Set_as_moderator"}}</span></button>
+					{{/if}}
 				{{/if}}
+				{{#if canRemoveUser}}
+					<button class="button button-block remove-user red"><span>{{_ "Remove_from_room"}}</span></button>
+				{{/if}}
+				{{#if canMuteUser}}
+					{{#if userMuted}}
+						<button class="button button-block unmute-user primary"><span>{{_ "Unmute_user"}}</span></button>
+					{{else}}
+						<button class="button button-block mute-user red"><span>{{_ "Mute_user"}}</span></button>
+					{{/if}}
+				{{/if}}
+				<button class='button secondary back'><span>{{_ "View_All"}} <i class='icon-angle-right'></i></span></button>
 			{{/if}}
 		</nav>
 	{{/if}}
diff --git a/packages/rocketchat-ui-flextab/package.js b/packages/rocketchat-ui-flextab/package.js
index e508f10d508e852834862fd3156a6068a28d9e21..98a1b68a2c00b806c1169b386104c89524ab0ffa 100644
--- a/packages/rocketchat-ui-flextab/package.js
+++ b/packages/rocketchat-ui-flextab/package.js
@@ -22,6 +22,8 @@ Package.onUse(function(api) {
 		'rocketchat:lib'
 	]);
 
+	api.use('rocketchat:ui');
+
 	api.addFiles('flex-tab/flexTabBar.html', 'client');
 	api.addFiles('flex-tab/tabs/membersList.html', 'client');
 	api.addFiles('flex-tab/tabs/messageSearch.html', 'client');
diff --git a/packages/rocketchat-ui-login/login/form.coffee b/packages/rocketchat-ui-login/login/form.coffee
index 52ef48d4bcb98ecf285293196cf6e8eb6d71f4fe..5d9946acac25f9fa7376035bec2f3ba886c2f88e 100644
--- a/packages/rocketchat-ui-login/login/form.coffee
+++ b/packages/rocketchat-ui-login/login/form.coffee
@@ -5,6 +5,9 @@ Template.loginForm.helpers
 	namePlaceholder: ->
 		return if RocketChat.settings.get 'Accounts_RequireNameForSignUp' then t('Name') else t('Name_optional')
 
+	showFormLogin: ->
+		return RocketChat.settings.get 'Accounts_ShowFormLogin' 
+
 	showName: ->
 		return 'hidden' unless Template.instance().state.get() is 'register'
 
@@ -115,6 +118,8 @@ Template.loginForm.events
 						else
 							toastr.error t 'User_not_found_or_incorrect_password'
 						return
+					localStorage.setItem('userLanguage', Meteor.user()?.language)
+					setLanguage(Meteor.user()?.language)
 
 	'click .register': ->
 		Template.instance().state.set 'register'
diff --git a/packages/rocketchat-ui-login/login/form.html b/packages/rocketchat-ui-login/login/form.html
index 575459711cf5f23df907b37520143fa09b198c29..d84200d39144326a64006bc2fb88ea86f0c20254 100644
--- a/packages/rocketchat-ui-login/login/form.html
+++ b/packages/rocketchat-ui-login/login/form.html
@@ -4,7 +4,7 @@
 			You must login to Sandstorm (on the top right) in order to access this chat.
 		</div>
 	{{else}}
-	<form id="login-card" method='/'>
+	<form id="login-card" method='/' novalidate>
 		{{#if waitActivation}}
 			<header>
 				<h2>{{{_ "Registration_Succeeded"}}}</h2>
@@ -18,37 +18,41 @@
 					{{_ "You_need_confirm_email"}}
 				</div>
 			{{/if}}
-			<div class="fields">
-				<div class='input-text active {{showName}}'>
-					<input type="text" name='name' placeholder='{{namePlaceholder}}' dir="auto" />
+			{{#if showFormLogin}}
+				<div class="fields">
+					<div class='input-text active {{showName}}'>
+						<input type="text" name='name' placeholder='{{namePlaceholder}}' dir="auto" />
+					</div>
+					<div class='input-text active {{showEmailOrUsername}}'>
+						<input type="text" name='emailOrUsername' placeholder='{{_ "Email_or_username"}}' autocapitalize="off" autocorrect="off" />
+					</div>
+					<div class='input-text active {{showEmail}}'>
+						<input type="email" name='email' placeholder='{{_ "Email"}}' />
+					</div>
+					<div class='input-text active {{showPassword}}'>
+						<input type="password" name='pass' placeholder='{{_ "Password"}}' />
+					</div>
+					<div class='input-text active {{showConfirmPassword}}'>
+						<input type="password" name='confirm-pass' placeholder='{{_ "Confirm_password"}}' />
+					</div>
 				</div>
-				<div class='input-text active {{showEmailOrUsername}}'>
-					<input type="text" name='emailOrUsername' placeholder='{{_ "Email_or_username"}}' autocapitalize="off" autocorrect="off" />
+				<div class="submit">
+					<button data-loading-text="{{_ "Please_wait"}}..." class='button primary login'><span>{{btnLoginSave}}</span></button>
 				</div>
-				<div class='input-text active {{showEmail}}'>
-					<input type="email" name='email' placeholder='{{_ "Email"}}' />
+				{{#if registrationAllowed}}
+				<div class="register {{showRegisterLink}}">
+					<a href="">{{_ 'Register'}}</a>
 				</div>
-				<div class='input-text active {{showPassword}}'>
-					<input type="password" name='pass' placeholder='{{_ "Password"}}' />
+				{{else}}
+					{{#if linkReplacementText}}
+						{{{linkReplacementText}}}
+					{{/if}}
+				{{/if}}
+				{{#if passwordresetAllowed}}
+				<div class="forgot-password {{showForgotPasswordLink}}">
+					<a href="">{{_ 'Forgot_password'}}</a>
 				</div>
-				<div class='input-text active {{showConfirmPassword}}'>
-					<input type="password" name='confirm-pass' placeholder='{{_ "Confirm_password"}}' />
-				</div>
-			</div>
-			<div class="submit">
-				<button data-loading-text="{{_ "Please_wait"}}..." class='button primary login'><span>{{btnLoginSave}}</span></button>
-			</div>
-			{{#if registrationAllowed}}
-			<div class="register {{showRegisterLink}}">
-				<a href="">{{_ 'Register'}}</a>
-			</div>
-			{{else}}{{#if linkReplacementText}}
-				{{{linkReplacementText}}}
-			{{/if}}{{/if}}
-			{{#if passwordresetAllowed}}
-			<div class="forgot-password {{showForgotPasswordLink}}">
-				<a href="">{{_ 'Forgot_password'}}</a>
-			</div>
+				{{/if}}
 			{{/if}}
 		{{/if}}
 		<div class="back-to-login {{showBackToLoginLink}}">
diff --git a/packages/rocketchat-ui-login/login/layout.html b/packages/rocketchat-ui-login/login/layout.html
index 3cf9cd1bb298c9f036f1b5209e8f2835e6176a31..a097d5834bb2a9f91fd6892e1a06221dd2e17524 100644
--- a/packages/rocketchat-ui-login/login/layout.html
+++ b/packages/rocketchat-ui-login/login/layout.html
@@ -2,7 +2,7 @@
 	<section class="full-page">
 		<div class="wrapper">
 			{{ > loginHeader }}
-			{{ > loginForm }}
+			{{> Template.dynamic template=center}}
 			{{ > loginFooter }}
 		</div>
 	</section>
diff --git a/packages/rocketchat-ui-login/package.js b/packages/rocketchat-ui-login/package.js
index 5b2c11042cbc43f79ad3d0a646a1b166440571df..750c1a7736d2b553336625c7d4ac7831534fa597 100644
--- a/packages/rocketchat-ui-login/package.js
+++ b/packages/rocketchat-ui-login/package.js
@@ -17,9 +17,16 @@ Package.onUse(function(api) {
 		'templating',
 		'coffeescript',
 		'underscore',
-		'rocketchat:lib@0.0.1'
+		'rocketchat:lib'
 	]);
 
+	api.use('kadira:flow-router', 'client');
+
+	api.addFiles('routes.js', 'client');
+
+	api.addFiles('reset-password/resetPassword.html', 'client');
+	api.addFiles('reset-password/resetPassword.js', 'client');
+
 	api.addFiles('login/footer.html', 'client');
 	api.addFiles('login/form.html', 'client');
 	api.addFiles('login/header.html', 'client');
@@ -37,4 +44,4 @@ Package.onUse(function(api) {
 	api.addFiles('login/services.coffee', 'client');
 	api.addFiles('login/social.coffee', 'client');
 	api.addFiles('username/username.coffee', 'client');
-});
\ No newline at end of file
+});
diff --git a/packages/rocketchat-ui-login/reset-password/resetPassword.html b/packages/rocketchat-ui-login/reset-password/resetPassword.html
new file mode 100644
index 0000000000000000000000000000000000000000..56d2468673008c30a6f730ea9594785b596825b1
--- /dev/null
+++ b/packages/rocketchat-ui-login/reset-password/resetPassword.html
@@ -0,0 +1,15 @@
+<template name="resetPassword">
+	<form id="login-card" action="/">
+		<div class="fields">
+			<header>
+				<p>{{_ "Please_enter_your_new_password_below"}}</p>
+			</header>
+			<div class="input-text active">
+				<input type="password" name="newPassword" placeholder="{{_ "Type_your_new_password"}}" dir="auto" />
+			</div>
+			<div class="submit">
+				<button data-loading-text="{{_ "Please_wait"}}..."  class="button primary resetpass"><span>{{_ "Reset"}}</span></button>
+			</div>
+		</div>
+	</form>
+</template>
diff --git a/packages/rocketchat-ui-login/reset-password/resetPassword.js b/packages/rocketchat-ui-login/reset-password/resetPassword.js
new file mode 100644
index 0000000000000000000000000000000000000000..ae91df0718059ed8f6c97a6bba12a915b0702fd6
--- /dev/null
+++ b/packages/rocketchat-ui-login/reset-password/resetPassword.js
@@ -0,0 +1,26 @@
+Template.resetPassword.events({
+	'submit #login-card': function(event, instance) {
+		event.preventDefault();
+
+		var button = instance.$('button.resetpass');
+		RocketChat.Button.loading(button);
+
+		Accounts.resetPassword(FlowRouter.getParam('token'), instance.find('[name=newPassword]').value, function(error) {
+			RocketChat.Button.reset(button);
+			if (error) {
+				console.log(error);
+				swal({
+					title: t('Error_changing_password'),
+					type: 'error'
+				});
+			} else {
+				FlowRouter.go('home');
+				toastr.success(t('Password_changed_successfully'));
+			}
+		});
+	}
+});
+
+Template.resetPassword.onRendered(function() {
+	this.find('[name=newPassword]').focus();
+});
diff --git a/packages/rocketchat-ui-login/routes.js b/packages/rocketchat-ui-login/routes.js
new file mode 100644
index 0000000000000000000000000000000000000000..a6ac9f5b22f443156e96e13a774763b5cec4546c
--- /dev/null
+++ b/packages/rocketchat-ui-login/routes.js
@@ -0,0 +1,6 @@
+FlowRouter.route('/reset-password/:token', {
+	name: 'resetPassword',
+	action: function() {
+		BlazeLayout.render('loginLayout', {center: 'resetPassword'});
+	}
+});
diff --git a/packages/rocketchat-ui-master/master/main.coffee b/packages/rocketchat-ui-master/master/main.coffee
index 14ec9d986b25fe20dc93d0d4697fc24e092ceec1..a5896523f8a207399d5ed61a7a0632d2904a74e7 100644
--- a/packages/rocketchat-ui-master/master/main.coffee
+++ b/packages/rocketchat-ui-master/master/main.coffee
@@ -216,3 +216,5 @@ Template.main.onRendered ->
 	# RTL Support - Need config option on the UI
 	if isRtl localStorage.getItem "userLanguage"
 		$('html').addClass "rtl"
+	else
+		$('html').removeClass "rtl"
diff --git a/packages/rocketchat-ui-master/master/main.html b/packages/rocketchat-ui-master/master/main.html
index abf74f660a8810a9a84504e3287566719981adae..68d5ba17aef520fd861b3dc80e1055fde5a7856c 100644
--- a/packages/rocketchat-ui-master/master/main.html
+++ b/packages/rocketchat-ui-master/master/main.html
@@ -43,7 +43,10 @@
 <template name="main">
 	{{#if subsReady}}
 		{{#unless logged}}
-			{{> loginLayout}}
+			<div class="connection-status">
+				{{> status}}
+			</div>
+			{{> loginLayout center="loginForm"}}
 		{{else}}
 			{{#unless hasUsername}}
 				{{> username}}
@@ -56,13 +59,17 @@
 					<div class="connection-status">
 						{{> status}}
 					</div>
-					<div class="flex-tab-bar" role="toolbar">
-						{{> flexTabBar}}
-					</div>
-					<div class="main-content {{flexOpened}} {{flexOpenedRTC1}} {{flexOpenedRTC2}}">
+					{{#unless modal}}
+						<div class="flex-tab-bar" role="toolbar">
+							{{> flexTabBar}}
+						</div>
+					{{/unless}}
+					<div class="main-content {{flexOpened}} {{flexOpenedRTC1}} {{flexOpenedRTC2}} {{#if modal}}main-modal{{/if}}">
 						{{> Template.dynamic template=center}}
 					</div>
-					{{> sideNav }}
+					{{#unless modal}}
+						{{> sideNav }}
+					{{/unless}}
 				</div>
 				{{> audioNotification }}
 			{{/unless}}
diff --git a/packages/rocketchat-ui-message/message/message.coffee b/packages/rocketchat-ui-message/message/message.coffee
index c596d6e36af72a8bf0fc35847bd7c248ccfeeb73..6295dd6b95783ff0082fbbad1e12983974166910 100644
--- a/packages/rocketchat-ui-message/message/message.coffee
+++ b/packages/rocketchat-ui-message/message/message.coffee
@@ -1,12 +1,20 @@
 Template.message.helpers
 	isBot: ->
 		return 'bot' if this.bot?
+	isGroupable: ->
+		return 'false' if this.groupable is false
+	isSequential: ->
+		return 'sequential' if this.groupable isnt false
+	getEmoji: (emoji) ->
+		return emojione.toImage emoji
 	own: ->
 		return 'own' if this.u?._id is Meteor.userId()
+	timestamp: ->
+		return +this.ts
 	chatops: ->
 		return 'chatops-message' if this.u?.username is RocketChat.settings.get('Chatops_Username')
 	time: ->
-		return moment(this.ts).format('HH:mm')
+		return moment(this.ts).format('LT')
 	date: ->
 		return moment(this.ts).format('LL')
 	isTemp: ->
@@ -24,15 +32,13 @@ Template.message.helpers
 
 	editTime: ->
 		if Template.instance().wasEdited
-			return moment(@editedAt).format('LL hh:mma') #TODO profile pref for 12hr/24hr clock?
+			return moment(@editedAt).format('LL LT') #TODO profile pref for 12hr/24hr clock?
 	editedBy: ->
 		return "" unless Template.instance().wasEdited
 		# try to return the username of the editor,
 		# otherwise a special "?" character that will be
 		# rendered as a special avatar
 		return @editedBy?.username or "?"
-	pinned: ->
-		return this.pinned
 	canEdit: ->
 		hasPermission = RocketChat.authz.hasAtLeastOnePermission('edit-message', this.rid)
 		isEditAllowed = RocketChat.settings.get 'Message_AllowEditing'
@@ -53,10 +59,6 @@ Template.message.helpers
 			return true
 
 		return RocketChat.settings.get('Message_AllowDeleting') and this.u?._id is Meteor.userId()
-	canPin: ->
-		return RocketChat.settings.get 'Message_AllowPinning'
-	canStar: ->
-		return RocketChat.settings.get 'Message_AllowStarring'
 	showEditedStatus: ->
 		return RocketChat.settings.get 'Message_ShowEditedStatus'
 	label: ->
@@ -100,6 +102,11 @@ Template.message.onCreated ->
 				msg.html = _.escapeHTML msg.html
 
 			message = RocketChat.callbacks.run 'renderMessage', msg
+			if message.tokens?.length > 0
+				for token in message.tokens
+					token.text = token.text.replace(/([^\$])(\$[^\$])/gm, '$1$$$2')
+					message.html = message.html.replace token.token, token.text
+
 			# console.log JSON.stringify message
 			msg.html = message.html.replace /\n/gm, '<br/>'
 			return msg.html
@@ -107,27 +114,53 @@ Template.message.onCreated ->
 Template.message.onViewRendered = (context) ->
 	view = this
 	this._domrange.onAttached (domRange) ->
-		lastNode = domRange.lastNode()
-		if lastNode.previousElementSibling?.dataset?.date isnt lastNode.dataset.date
-			$(lastNode).addClass('new-day')
-			$(lastNode).removeClass('sequential')
-		else if lastNode.previousElementSibling?.dataset?.bot is 'bot' or lastNode.previousElementSibling?.dataset?.username isnt lastNode.dataset.username
-			$(lastNode).removeClass('sequential')
-
-		if lastNode.nextElementSibling?.dataset?.date is lastNode.dataset.date
-			$(lastNode.nextElementSibling).removeClass('new-day')
-			$(lastNode.nextElementSibling).addClass('sequential')
-		else
-			$(lastNode.nextElementSibling).addClass('new-day')
-			$(lastNode.nextElementSibling).removeClass('sequential')
+		currentNode = domRange.lastNode()
+		currentDataset = currentNode.dataset
+		previousNode = currentNode.previousElementSibling
+		nextNode = currentNode.nextElementSibling
+		$currentNode = $(currentNode)
+		$previousNode = $(previousNode)
+		$nextNode = $(nextNode)
+
+		unless previousNode?
+			$currentNode.addClass('new-day').removeClass('sequential')
+
+		else if previousNode?.dataset?
+			previousDataset = previousNode.dataset
+
+			if previousDataset.date isnt currentDataset.date
+				$currentNode.addClass('new-day').removeClass('sequential')
+			else
+				$currentNode.removeClass('new-day')
+
+			if previousDataset.groupable is 'false' or currentDataset.groupable is 'false'
+				$currentNode.removeClass('sequential')
+			else
+				if previousDataset.username isnt currentDataset.username or parseInt(currentDataset.timestamp) - parseInt(previousDataset.timestamp) > RocketChat.settings.get('Message_GroupingPeriod') * 1000
+					$currentNode.removeClass('sequential')
+				else if not $currentNode.hasClass 'new-day'
+					$currentNode.addClass('sequential')
+
+		if nextNode?.dataset?
+			nextDataset = nextNode.dataset
+
+			if nextDataset.date isnt currentDataset.date
+				$nextNode.addClass('new-day').removeClass('sequential')
+			else
+				$nextNode.removeClass('new-day')
+
+			if nextDataset.groupable isnt 'false'
+				if nextDataset.username isnt currentDataset.username or parseInt(nextDataset.timestamp) - parseInt(currentDataset.timestamp) > RocketChat.settings.get('Message_GroupingPeriod') * 1000
+					$nextNode.removeClass('sequential')
+				else if not $nextNode.hasClass 'new-day'
+					$nextNode.addClass('sequential')
 
-		if lastNode.nextElementSibling?.dataset?.bot is 'bot' or lastNode.nextElementSibling?.dataset?.username isnt lastNode.dataset.username
-			$(lastNode.nextElementSibling).removeClass('sequential')
+		if not nextNode?
+			templateInstance = view.parentView.parentView.parentView.parentView.parentView.templateInstance?()
 
-		if not lastNode.nextElementSibling?
-			if lastNode.classList.contains('own') is true
-				view.parentView.parentView.parentView.parentView.parentView.templateInstance?().atBottom = true
+			if currentNode.classList.contains('own') is true
+				templateInstance?.atBottom = true
 			else
-				if view.parentView.parentView.parentView.parentView.parentView.templateInstance?().atBottom isnt true
-					newMessage = view.parentView.parentView.parentView.parentView.parentView.templateInstance?()?.find(".new-message")
+				if templateInstance?.atBottom isnt true
+					newMessage = templateInstance?.find(".new-message")
 					newMessage?.className = "new-message"
diff --git a/packages/rocketchat-ui-message/message/message.html b/packages/rocketchat-ui-message/message/message.html
index 0ae084bfc99cbd4c7bceff388288b2193fbdab3a..a2d6fd53f55ecdfecdb2953fb85818a3423e168d 100644
--- a/packages/rocketchat-ui-message/message/message.html
+++ b/packages/rocketchat-ui-message/message/message.html
@@ -1,5 +1,5 @@
 <template name="message">
-	<li id="{{_id}}" class="message sequential {{system}} {{t}} {{own}} {{isTemp}} {{chatops}}" data-username="{{u.username}}" data-bot="{{isBot}}" data-date="{{date}}">
+	<li id="{{_id}}" class="message {{isSequential}} {{system}} {{t}} {{own}} {{isTemp}} {{chatops}}" data-username="{{u.username}}" data-groupable="{{isGroupable}}" data-date="{{date}}" data-timestamp="{{timestamp}}">
 		{{#if avatar}}
 			<a class="thumb user-card-message" href="#" data-username="{{u.username}}" tabindex="1">
 				<div class="avatar">
@@ -7,7 +7,15 @@
 				</div>
 			</a>
 		{{else}}
-			<a class="thumb user-card-message" href="#" data-username="{{u.username}}" tabindex="1">{{> avatar username=u.username}}</a>
+			{{#if emoji}}
+				<a class="thumb user-card-message" href="#" data-username="{{u.username}}" tabindex="1">
+					<div class="avatar">
+						{{{getEmoji emoji}}}
+					</div>
+				</a>
+			{{else}}
+				<a class="thumb user-card-message" href="#" data-username="{{u.username}}" tabindex="1">{{> avatar username=u.username}}</a>
+			{{/if}}
 		{{/if}}
 		{{#if alias}}
 			<a class="user user-card-message" href="#" data-username="{{u.username}}" tabindex="1">{{alias}} <span class="message-alias">@{{u.username}}</span></a>
diff --git a/packages/rocketchat-ui-message/message/messageBox.coffee b/packages/rocketchat-ui-message/message/messageBox.coffee
index dd9ae3c8d74f6d2f341ac44636436a1be1425eba..00f3cad3a06c64475d419a8dc94e6f5619f9cafe 100644
--- a/packages/rocketchat-ui-message/message/messageBox.coffee
+++ b/packages/rocketchat-ui-message/message/messageBox.coffee
@@ -116,7 +116,6 @@ Template.messageBox.events
 		fileUpload filesToUpload
 
 	'click .message-form .mic': (e, t) ->
-		console.log window.AudioRecorder
 		AudioRecorder.start ->
 			t.$('.stop-mic').removeClass('hidden')
 			t.$('.mic').addClass('hidden')
diff --git a/packages/rocketchat-ui-message/message/popup/messagePopupConfig.coffee b/packages/rocketchat-ui-message/message/popup/messagePopupConfig.coffee
index e8a085eebeab3e3929ce4d3d31eaecdc57128a58..022ff911f7894cddf5271bd6ec347e69690d34bd 100644
--- a/packages/rocketchat-ui-message/message/popup/messagePopupConfig.coffee
+++ b/packages/rocketchat-ui-message/message/popup/messagePopupConfig.coffee
@@ -88,7 +88,7 @@ Template.messagePopupConfig.helpers
 						commands.push
 							_id: command
 							params: item.params
-							description: item.description
+							description: TAPi18n.__ item.description
 
 					if commands.length > 10
 						break
diff --git a/packages/rocketchat-ui-message/message/popup/messagePopupEmoji.coffee b/packages/rocketchat-ui-message/message/popup/messagePopupEmoji.coffee
index 4f47569fd26de8ce0cffa8bc7e74163d4dec45bf..d50a31f2c236aa0a71d4bc5144f84d2101e4a68d 100644
--- a/packages/rocketchat-ui-message/message/popup/messagePopupEmoji.coffee
+++ b/packages/rocketchat-ui-message/message/popup/messagePopupEmoji.coffee
@@ -1,4 +1,4 @@
 Template.messagePopupEmoji.helpers
 	value: ->
 		length = this.data.length
-		return this.data[length - 1].toUpperCase()
+		return this.data[length - 1]
diff --git a/packages/rocketchat-ui-sidenav/package.js b/packages/rocketchat-ui-sidenav/package.js
index f0c3872b1463b0308f3235c6f1e37f2334acc312..6136ef7e0873cb7991520d842b43275f1dd4e91a 100644
--- a/packages/rocketchat-ui-sidenav/package.js
+++ b/packages/rocketchat-ui-sidenav/package.js
@@ -18,7 +18,8 @@ Package.onUse(function(api) {
 		'templating',
 		'coffeescript',
 		'underscore',
-		'rocketchat:lib@0.0.1'
+		'rocketchat:lib',
+		'rocketchat:ui'
 	]);
 
 	api.addFiles('side-nav/accountBox.html', 'client');
diff --git a/packages/rocketchat-ui-sidenav/side-nav/chatRoomItem.coffee b/packages/rocketchat-ui-sidenav/side-nav/chatRoomItem.coffee
index 6b0aa396d44eac80d5ef3d708ce64e62323d4895..4db2d7e04942c8fb2bb43d35d4165d4a33e12a80 100644
--- a/packages/rocketchat-ui-sidenav/side-nav/chatRoomItem.coffee
+++ b/packages/rocketchat-ui-sidenav/side-nav/chatRoomItem.coffee
@@ -9,8 +9,7 @@ Template.chatRoomItem.helpers
 			return this.unread
 
 	userStatus: ->
-		return 'status-' + (Session.get('user_' + this.name + '_status') or 'offline') if this.t is 'd'
-		return ''
+		return 'status-' + (Session.get('user_' + this.name + '_status') or 'offline')
 
 	name: ->
 		return this.name
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-sidenav/side-nav/sideNav.coffee b/packages/rocketchat-ui-sidenav/side-nav/sideNav.coffee
index 1f6f5958a07b356f0d0273d6c8aba0510307e606..8b1bfb25b6c90e1b91c54faeb544a6e376f85a2b 100644
--- a/packages/rocketchat-ui-sidenav/side-nav/sideNav.coffee
+++ b/packages/rocketchat-ui-sidenav/side-nav/sideNav.coffee
@@ -14,6 +14,15 @@ Template.sideNav.helpers
 
 		return true if favoritesEnabled and hasFavoriteRoomOpened
 
+	roomType: ->
+		return RocketChat.roomTypes.getTypes()
+
+	canShowRoomType: ->
+		return RocketChat.roomTypes.checkCondition(@)
+
+	templateName: ->
+		return @template
+
 Template.sideNav.events
 	'click .close-flex': ->
 		SideNav.closeFlex()
@@ -36,10 +45,3 @@ Template.sideNav.onRendered ->
 
 	Meteor.defer ->
 		menu.updateUnreadBars()
-
-	wrapper = $('.rooms-list .wrapper').get(0)
-	lastLink = $('.rooms-list h3.history-div').get(0)
-
-	RocketChat.roomTypes.getTypes().forEach (roomType) ->
-		if Template[roomType.template]?
-			Blaze.render Template[roomType.template], wrapper, lastLink
diff --git a/packages/rocketchat-ui-sidenav/side-nav/sideNav.html b/packages/rocketchat-ui-sidenav/side-nav/sideNav.html
index 80b0454af9cc1c988f451ea352c07c60783549c3..20446d87f20ec95731a23dada6a6ea36d921a636 100644
--- a/packages/rocketchat-ui-sidenav/side-nav/sideNav.html
+++ b/packages/rocketchat-ui-sidenav/side-nav/sideNav.html
@@ -11,6 +11,12 @@
 				<div class="wrapper">
 					{{ > unreadRooms }}
 
+					{{#each roomType}}
+						{{#if canShowRoomType}}
+							{{> Template.dynamic template=templateName }}
+						{{/if}}
+					{{/each}}
+
 					<h3 class="history-div">
 						<a href="{{pathFor 'privateHistory'}}">{{_ "History"}}</a>
 					</h3>
diff --git a/packages/rocketchat-ui/lib/RoomHistoryManager.coffee b/packages/rocketchat-ui/lib/RoomHistoryManager.coffee
index aac7ca39f1f61f854ea51d23ebb7ae45b77f526a..cb79f341e3c8ca7eddd8db37ea21efa9c993d683 100644
--- a/packages/rocketchat-ui/lib/RoomHistoryManager.coffee
+++ b/packages/rocketchat-ui/lib/RoomHistoryManager.coffee
@@ -7,8 +7,10 @@
 		if not histories[rid]?
 			histories[rid] =
 				hasMore: ReactiveVar true
+				hasMoreNext: ReactiveVar false
 				isLoading: ReactiveVar false
 				unreadNotLoaded: ReactiveVar 0
+				firstUnread: ReactiveVar {}
 				loaded: 0
 
 		return histories[rid]
@@ -42,6 +44,7 @@
 
 		Meteor.call 'loadHistory', rid, ts, limit, ls, (err, result) ->
 			room.unreadNotLoaded.set result?.unreadNotLoaded
+			room.firstUnread.set result?.firstUnread
 
 			wrapper = $('.messages-box .wrapper').get(0)
 			if wrapper?
@@ -62,20 +65,130 @@
 			if result?.messages?.length < limit
 				room.hasMore.set false
 
+	getMoreNext = (rid, limit=defaultLimit) ->
+		room = getRoom rid
+		if room.hasMoreNext.curValue isnt true
+			return
+
+		instance = Blaze.getView($('.messages-box .wrapper')[0]).templateInstance()
+		instance.atBottom = false
+
+		room.isLoading.set true
+
+		lastMessage = ChatMessage.findOne({rid: rid}, {sort: {ts: -1}})
+
+		typeName = undefined
+
+		subscription = ChatSubscription.findOne rid: rid
+		if subscription?
+			ls = subscription.ls
+			typeName = subscription.t + subscription.name
+		else
+			curRoomDoc = ChatRoom.findOne(_id: rid)
+			typeName = curRoomDoc?.t + curRoomDoc?.name
+
+		ts = lastMessage.ts
+
+		if ts
+			Meteor.call 'loadNextMessages', rid, ts, limit, (err, result) ->
+				for item in result?.messages or []
+					if item.t isnt 'command'
+						ChatMessage.upsert {_id: item._id}, item
+
+				Meteor.defer ->
+					RoomManager.updateMentionsMarksOfRoom typeName
+
+				room.isLoading.set false
+				room.loaded += result.messages.length
+				if result.messages.length < limit
+					room.hasMoreNext.set false
+
+	getSurroundingMessages = (message, limit=defaultLimit) ->
+		unless message?.rid
+			return
+
+		instance = Blaze.getView($('.messages-box .wrapper')[0]).templateInstance()
+
+		if ChatMessage.findOne message._id
+			wrapper = $('.messages-box .wrapper')
+			msgElement = $("##{message._id}", wrapper)
+			pos = wrapper.scrollTop() + msgElement.offset().top - wrapper.height()/2
+			wrapper.animate({
+				scrollTop: pos
+			}, 500)
+			msgElement.addClass('highlight')
+
+			setTimeout ->
+				messages = wrapper[0]
+				instance.atBottom = messages.scrollTop >= messages.scrollHeight - messages.clientHeight;
+
+			setTimeout ->
+				msgElement.removeClass('highlight')
+			, 3000
+		else
+			room = getRoom message.rid
+			room.isLoading.set true
+			ChatMessage.remove { rid: message.rid }
+
+			typeName = undefined
+
+			subscription = ChatSubscription.findOne rid: message.rid
+			if subscription?
+				ls = subscription.ls
+				typeName = subscription.t + subscription.name
+			else
+				curRoomDoc = ChatRoom.findOne(_id: message.rid)
+				typeName = curRoomDoc?.t + curRoomDoc?.name
+
+			Meteor.call 'loadSurroundingMessages', message, limit, (err, result) ->
+				for item in result?.messages or []
+					if item.t isnt 'command'
+						ChatMessage.upsert {_id: item._id}, item
+
+				Meteor.defer ->
+					readMessage.refreshUnreadMark(message.rid, true)
+					RoomManager.updateMentionsMarksOfRoom typeName
+					wrapper = $('.messages-box .wrapper')
+					msgElement = $("##{message._id}", wrapper)
+					pos = wrapper.scrollTop() + msgElement.offset().top - wrapper.height()/2
+					wrapper.animate({
+						scrollTop: pos
+					}, 500)
+
+					msgElement.addClass('highlight')
+
+					setTimeout ->
+						room.isLoading.set false
+						messages = wrapper[0]
+						instance.atBottom = !result.moreAfter && messages.scrollTop >= messages.scrollHeight - messages.clientHeight;
+					, 500
+
+					setTimeout ->
+						msgElement.removeClass('highlight')
+					, 3000
+				room.loaded += result.messages.length
+				room.hasMore.set result.moreBefore
+				room.hasMoreNext.set result.moreAfter
+
 	hasMore = (rid) ->
 		room = getRoom rid
 
 		return room.hasMore.get()
 
+	hasMoreNext = (rid) ->
+		room = getRoom rid
+		return room.hasMoreNext.get()
+
+
 	getMoreIfIsEmpty = (rid) ->
 		room = getRoom rid
 
 		if room.loaded is 0
 			getMore rid
 
+
 	isLoading = (rid) ->
 		room = getRoom rid
-
 		return room.isLoading.get()
 
 	clear = (rid) ->
@@ -87,7 +200,10 @@
 
 	getRoom: getRoom
 	getMore: getMore
+	getMoreNext: getMoreNext
 	getMoreIfIsEmpty: getMoreIfIsEmpty
 	hasMore: hasMore
+	hasMoreNext: hasMoreNext
 	isLoading: isLoading
 	clear: clear
+	getSurroundingMessages: getSurroundingMessages
diff --git a/packages/rocketchat-ui/lib/RoomManager.coffee b/packages/rocketchat-ui/lib/RoomManager.coffee
index 0a70060a78eba4a5a4516183bec6e6e56e565661..d5b15660788e7eb0928ac210dc4466622cf2f355 100644
--- a/packages/rocketchat-ui/lib/RoomManager.coffee
+++ b/packages/rocketchat-ui/lib/RoomManager.coffee
@@ -62,7 +62,7 @@ RocketChat.Notifications.onUser 'message', (msg) ->
 					sub.stop()
 
 			if openedRooms[typeName].rid?
-				msgStream.removeListener openedRooms[typeName].rid
+				msgStream.removeAllListeners openedRooms[typeName].rid
 				RocketChat.Notifications.unRoom openedRooms[typeName].rid, 'deleteMessage', onDeleteMessageStream
 
 			openedRooms[typeName].ready = false
@@ -85,6 +85,9 @@ RocketChat.Notifications.onUser 'message', (msg) ->
 					Meteor.subscribe 'room', typeName
 				]
 
+				if record.ready is true
+					return
+
 				ready = record.sub[0].ready() and subscription.ready()
 
 				if ready is true
@@ -108,16 +111,23 @@ RocketChat.Notifications.onUser 'message', (msg) ->
 						record.ready = RoomHistoryManager.isLoading(room._id) is false
 						Dep.changed()
 
-						msgStream.on openedRooms[typeName].rid, (msg) ->
-							if msg.t isnt 'command'
-								ChatMessage.upsert { _id: msg._id }, msg
-							else
-								Meteor.defer ->
-									RoomManager.updateMentionsMarksOfRoom typeName
+						if openedRooms[typeName].streamActive isnt true
+							openedRooms[typeName].streamActive = true
+							msgStream.on openedRooms[typeName].rid, (msg) ->
+
+								# Should not send message to room if room has not loaded all the current messages
+								if RoomHistoryManager.hasMoreNext(openedRooms[typeName].rid) is false
+
+									# Do not load command messages into channel
+									if msg.t isnt 'command'
+										ChatMessage.upsert { _id: msg._id }, msg
+
+									Meteor.defer ->
+										RoomManager.updateMentionsMarksOfRoom typeName
 
-								RocketChat.callbacks.run 'streamMessage', msg
+									RocketChat.callbacks.run 'streamMessage', msg
 
-						RocketChat.Notifications.onRoom openedRooms[typeName].rid, 'deleteMessage', onDeleteMessageStream
+							RocketChat.Notifications.onRoom openedRooms[typeName].rid, 'deleteMessage', onDeleteMessageStream
 
 				Dep.changed()
 
@@ -207,7 +217,7 @@ RocketChat.Notifications.onUser 'message', (msg) ->
 		scrollTop = $(dom).find('.messages-box > .wrapper').scrollTop() - 50
 		totalHeight = $(dom).find('.messages-box > .wrapper > ul').height() + 40
 
-		$('.mention-link-me').each (index, item) ->
+		$('.messages-box .mention-link-me').each (index, item) ->
 			topOffset = $(item).offset().top + scrollTop
 			percent = 100 / totalHeight * topOffset
 			ticksBar.append('<div class="tick" style="top: '+percent+'%;"></div>')
diff --git a/packages/rocketchat-ui/lib/accountBox.coffee b/packages/rocketchat-ui/lib/accountBox.coffee
index 49c6a3c13d288b6c1af3f4a304e37479aa4e6c34..d75d66a2a32596550b3458648a94816d460013fa 100644
--- a/packages/rocketchat-ui/lib/accountBox.coffee
+++ b/packages/rocketchat-ui/lib/accountBox.coffee
@@ -41,30 +41,39 @@
 			actual.push newItem
 			items.set actual
 
+	checkCondition = (item) ->
+		return not item.condition? or item.condition()
+
 	getItems = ->
 		return _.filter items.get(), (item) ->
-			if not item.permissions? or RocketChat.authz.hasAllPermission item.permissions
+			if checkCondition(item)
 				return true
 
-	addRoute = (newRoute) ->
+	addRoute = (newRoute, router = FlowRouter) ->
 
 		# @TODO check for mandatory fields
+		routeConfig =
+			center: 'pageContainer'
+			pageTemplate: newRoute.pageTemplate
+
+		if newRoute.i18nPageTitle?
+			routeConfig.i18nPageTitle = newRoute.i18nPageTitle
 
-		FlowRouter.route newRoute.path,
+		if newRoute.pageTitle?
+			routeConfig.pageTitle = newRoute.pageTitle
+
+		router.route newRoute.path,
 			name: newRoute.name
 			action: ->
 				Session.set 'openedRoom'
-				BlazeLayout.render 'main',
-					center: 'pageContainer'
-					pageTitle: newRoute.pageTitle
-					pageTemplate: newRoute.pageTemplate
+				RocketChat.TabBar.showGroup newRoute.name
+				BlazeLayout.render 'main', routeConfig
 			triggersEnter: [ ->
 				if newRoute.sideNav?
 					SideNav.setFlex newRoute.sideNav
 					SideNav.openFlex()
 			]
 
-
 	setStatus: setStatus
 	toggle: toggle
 	open: open
diff --git a/packages/rocketchat-ui/lib/accounts.coffee b/packages/rocketchat-ui/lib/accounts.coffee
index d81d0e7c5a4121d5d189267b1b3ddeb7d53f60e4..17f3828de2fb548355d16062f1dfdf5821ffa2fb 100644
--- a/packages/rocketchat-ui/lib/accounts.coffee
+++ b/packages/rocketchat-ui/lib/accounts.coffee
@@ -1,17 +1,6 @@
-Meteor.startup ->
-	Accounts.onEmailVerificationLink (token, done) ->
-		Accounts.verifyEmail token, (error) ->
-			if not error?
-				alert(t('Email_verified'))
+Accounts.onEmailVerificationLink (token, done) ->
+	Accounts.verifyEmail token, (error) ->
+		if not error?
+			alert(t('Email_verified'))
 
-			done()
-
-	Accounts.onResetPasswordLink (token, done) ->
-		newPassword = prompt(t('New_password'))
-		Accounts.resetPassword token, newPassword, (error) ->
-			if error?
-				console.log error
-				alert(t('Error_changing_password'))
-			else
-				alert('Password_changed')
-			done()
\ No newline at end of file
+		done()
diff --git a/packages/rocketchat-ui/lib/collections.coffee b/packages/rocketchat-ui/lib/collections.coffee
index 4c77cee3d1a9b58dff58e25c4a97866c291d0773..f02353c55014e6621cf1b3361468d328c5df55b7 100644
--- a/packages/rocketchat-ui/lib/collections.coffee
+++ b/packages/rocketchat-ui/lib/collections.coffee
@@ -1,5 +1,11 @@
 @ChatMessage = new Meteor.Collection null
 @ChatRoom = new Meteor.Collection 'rocketchat_room'
 @ChatSubscription = new Meteor.Collection 'rocketchat_subscription'
+@RoomModeratorsAndOwners = new Mongo.Collection null
 @UserAndRoom = new Meteor.Collection null
 @CachedChannelList = new Meteor.Collection null
+
+RocketChat.models.Users = _.extend {}, RocketChat.models.Users, Meteor.users
+RocketChat.models.Subscriptions = _.extend {}, RocketChat.models.Subscriptions, @ChatSubscription
+RocketChat.models.Rooms = _.extend {}, RocketChat.models.Rooms, @ChatRoom
+RocketChat.models.Messages = _.extend {}, RocketChat.models.Messages, @ChatMessage
diff --git a/packages/rocketchat-ui/lib/cordova/urls.coffee b/packages/rocketchat-ui/lib/cordova/urls.coffee
index 59bcf5d22f656359f1206d99bb80862877673395..aeed6e9604b962466353cd216164951322a4389e 100644
--- a/packages/rocketchat-ui/lib/cordova/urls.coffee
+++ b/packages/rocketchat-ui/lib/cordova/urls.coffee
@@ -10,9 +10,5 @@ Meteor.startup ->
 			url = $link.attr('href')
 
 			if /^https?:\/\/.+/.test(url) is true
-				switch platform
-					when 'ios'
-						window.open url, '_system'
-					when 'android'
-						navigator.app.loadUrl url, {openExternal: true}
-				e.preventDefault()
\ No newline at end of file
+				window.open url, '_system'
+				e.preventDefault()
diff --git a/packages/rocketchat-ui/lib/fileUpload.coffee b/packages/rocketchat-ui/lib/fileUpload.coffee
index 48db0ca7dbe23551efec61ef00fd267a93a5aba2..548cc76437fa7c461844cda20e004c31cce18436 100644
--- a/packages/rocketchat-ui/lib/fileUpload.coffee
+++ b/packages/rocketchat-ui/lib/fileUpload.coffee
@@ -31,6 +31,13 @@ readAsArrayBuffer = (file, callback) ->
 					timer: 1000
 				return
 
+			if file.file.size is 0
+				swal
+					title: t('FileUpload_File_Empty')
+					type: 'error'
+					timer: 1000
+				return
+
 			text = ''
 
 			if file.type is 'audio'
@@ -86,16 +93,38 @@ readAsArrayBuffer = (file, callback) ->
 
 						onComplete: (file) ->
 							self = this
-							Meteor.call 'sendMessage', {
+							url = file.url.replace(Meteor.absoluteUrl(), '/')
+
+							attachment =
+								title: "File Uploaded: #{file.name}"
+								title_link: url
+
+							if /^image\/.+/.test file.type
+								attachment.image_url = url
+								attachment.image_type = file.type
+								attachment.image_size = file.size
+								attachment.image_dimensions = file.identify?.size
+
+							if /^audio\/.+/.test file.type
+								attachment.audio_url = url
+								attachment.audio_type = file.type
+								attachment.audio_size = file.size
+
+							if /^video\/.+/.test file.type
+								attachment.video_url = url
+								attachment.video_type = file.type
+								attachment.video_size = file.size
+
+							msg =
 								_id: Random.id()
 								rid: roomId
-								msg: """
-									File Uploaded: *#{file.name}*
-									#{file.url}
-								"""
+								msg: ""
 								file:
 									_id: file._id
-							}, ->
+								groupable: false
+								attachments: [attachment]
+
+							Meteor.call 'sendMessage', msg, ->
 								Meteor.setTimeout ->
 									uploading = Session.get 'uploading'
 									if uploading?
diff --git a/packages/rocketchat-ui/lib/notification.coffee b/packages/rocketchat-ui/lib/notification.coffee
index c6822dd846b4ae80857e63a64ef6839848828846..0785236f5dec6445433de97f522c5e10b5d981d0 100644
--- a/packages/rocketchat-ui/lib/notification.coffee
+++ b/packages/rocketchat-ui/lib/notification.coffee
@@ -30,10 +30,6 @@
 								when 'p'
 									FlowRouter.go 'group', {name: notification.payload.name}
 
-					setTimeout ->
-						n.close()
-					, 10000
-
 	newMessage: ->
 		unless Session.equals('user_' + Meteor.userId() + '_status', 'busy') or Meteor.user()?.settings?.preferences?.disableNewMessageNotification
 			$('#chatAudioNotification')[0].play()
diff --git a/packages/rocketchat-ui/lib/recorderjs/audioRecorder.coffee b/packages/rocketchat-ui/lib/recorderjs/audioRecorder.coffee
index c2cad9187967992f5373ca8872348a5521ded8a9..013af2a24e52a488fc445c298c93d3d63b4840ec 100644
--- a/packages/rocketchat-ui/lib/recorderjs/audioRecorder.coffee
+++ b/packages/rocketchat-ui/lib/recorderjs/audioRecorder.coffee
@@ -1,4 +1,4 @@
-@AudioRecorder = new class 
+@AudioRecorder = new class
 	start: (cb) ->
 		window.AudioContext = window.AudioContext or window.webkitAudioContext
 		navigator.getUserMedia = navigator.getUserMedia or navigator.webkitGetUserMedia
@@ -28,7 +28,7 @@
 		if cb?
 			@getBlob cb
 
-		@stream.stop()
+		@stream.getAudioTracks()[0].stop()
 
 		@recorder.clear()
 
diff --git a/packages/rocketchat-ui/lib/trackRoomNameChanged.coffee b/packages/rocketchat-ui/lib/trackRoomNameChanged.coffee
deleted file mode 100644
index 8b3a0769febae4f4b9f11b9e85d6e2753536a69d..0000000000000000000000000000000000000000
--- a/packages/rocketchat-ui/lib/trackRoomNameChanged.coffee
+++ /dev/null
@@ -1,12 +0,0 @@
-Meteor.startup ->
-	roomNameChangedCallback = (msg) ->
-		Tracker.nonreactive ->
-			if msg.t is 'r'
-				if Session.get('openedRoom') is msg.rid
-					type = if FlowRouter.current().route.name is 'channel' then 'c' else 'p'
-					RoomManager.close type + FlowRouter.getParam('name')
-					FlowRouter.go FlowRouter.current().route.name, name: msg.msg
-
-		return msg
-
-	RocketChat.callbacks.add 'streamMessage', roomNameChangedCallback, RocketChat.callbacks.priority.HIGH
diff --git a/packages/rocketchat-ui/lib/updateModeratorsAndOwners.js b/packages/rocketchat-ui/lib/updateModeratorsAndOwners.js
new file mode 100644
index 0000000000000000000000000000000000000000..da6e309b9759b312308d5e6ba90a549b82096298
--- /dev/null
+++ b/packages/rocketchat-ui/lib/updateModeratorsAndOwners.js
@@ -0,0 +1,33 @@
+Meteor.startup(function() {
+	RocketChat.callbacks.add('streamMessage', function(msg) {
+		if (msg.t === 'new-moderator') {
+			user = Meteor.users.findOne({ username: msg.msg }, { fields: { username: 1 } });
+			RoomModeratorsAndOwners.upsert({ rid: msg.rid, "u._id": user._id }, { $setOnInsert: { u: user }, $addToSet: { roles: 'moderator' } });
+		} else if (msg.t === 'moderator-removed') {
+			user = Meteor.users.findOne({ username: msg.msg });
+			moderator = RoomModeratorsAndOwners.findOne({ rid: msg.rid, "u._id": user._id, roles: 'moderator' });
+			if (moderator && moderator.roles && moderator.roles.length === 1 && moderator.roles[0] === 'moderator') {
+				RoomModeratorsAndOwners.remove({ rid: msg.rid, "u._id": user._id, roles: 'moderator' });
+			} else if (moderator) {
+				RoomModeratorsAndOwners.update({ rid: msg.rid, "u._id": user._id }, { $pull: { roles: 'moderator' } });
+			}
+		}
+		return msg;
+	}, RocketChat.callbacks.priority.LOW, 'addOrRemoveModerator');
+
+	RocketChat.callbacks.add('streamMessage', function(msg) {
+		if (msg.t === 'new-owner') {
+			user = Meteor.users.findOne({ username: msg.msg }, { fields: { username: 1 } });
+			RoomModeratorsAndOwners.upsert({ rid: msg.rid, "u._id": user._id }, { $setOnInsert: { u: user }, $addToSet: { roles: 'owner' } });
+		} else if (msg.t === 'owner-removed') {
+			user = Meteor.users.findOne({ username: msg.msg });
+			owner = RoomModeratorsAndOwners.findOne({ rid: msg.rid, "u._id": user._id, roles: 'owner' });
+			if (owner && owner.roles && owner.roles.length === 1 && owner.roles[0] === 'owner') {
+				RoomModeratorsAndOwners.remove({ rid: msg.rid, "u._id": user._id, roles: 'owner' });
+			} else if (owner) {
+				RoomModeratorsAndOwners.update({ rid: msg.rid, "u._id": user._id }, { $pull: { roles: 'owner' } });
+			}
+		}
+		return msg;
+	}, RocketChat.callbacks.priority.LOW, 'addOrRemoveOwner');
+})
diff --git a/packages/rocketchat-ui/package.js b/packages/rocketchat-ui/package.js
index e7822568ede7d0bad00df719272d3faa83181f85..6badab973672c064ea512e78d490f61c06a39530 100644
--- a/packages/rocketchat-ui/package.js
+++ b/packages/rocketchat-ui/package.js
@@ -14,6 +14,7 @@ Package.onUse(function(api) {
 	api.versionsFrom('1.2.1');
 
 	api.use([
+		'accounts-base',
 		'mongo',
 		'session',
 		'jquery',
@@ -23,7 +24,7 @@ Package.onUse(function(api) {
 		'templating',
 		'coffeescript',
 		'underscore',
-		'rocketchat:lib@0.0.1',
+		'rocketchat:lib',
 		'raix:push',
 		'raix:ui-dropped-event'
 	]);
@@ -55,7 +56,7 @@ Package.onUse(function(api) {
 	api.addFiles('lib/sideNav.coffee', 'client');
 	api.addFiles('lib/tapi18n.coffee', 'client');
 	api.addFiles('lib/textarea-autogrow.js', 'client');
-	api.addFiles('lib/trackRoomNameChanged.coffee', 'client');
+	api.addFiles('lib/updateModeratorsAndOwners.js', 'client');
 
 	// LIB CORDOVA
 	api.addFiles('lib/cordova/facebook-login.coffee', 'client');
diff --git a/packages/rocketchat-ui/views/app/pageContainer.html b/packages/rocketchat-ui/views/app/pageContainer.html
index 7c8af10e1c4d5591304bed5eebb3510595f50aa0..fdd8ce1e788bd59a6ad524da9ed1799e4778d7e2 100644
--- a/packages/rocketchat-ui/views/app/pageContainer.html
+++ b/packages/rocketchat-ui/views/app/pageContainer.html
@@ -3,7 +3,13 @@
 		<head class="fixed-title">
 			{{> burger}}
 			<h2>
-				<span class="page-title">{{pageTitle}}</span>
+				<span class="page-title">
+					{{#if i18nPageTitle}}
+						{{_ i18nPageTitle}}
+					{{else}}
+						{{pageTitle}}
+					{{/if}}
+				</span>
 			</h2>
 		</head>
 		<div class="content">
diff --git a/packages/rocketchat-ui/views/app/privateHistory.coffee b/packages/rocketchat-ui/views/app/privateHistory.coffee
index b04ecd4f8037f91a75c05d9bb8c0e097e9a363a3..b59fdc7c23e6883de1c34b57261daed16c24ae83 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()
@@ -30,9 +37,6 @@ Template.privateHistory.helpers
 			when 'd'
 				return FlowRouter.path 'direct', { username: this.name }
 
-Template.privateHistory.onRendered ->
-	RocketChat.TabBar.reset()
-
 Template.privateHistory.events
 	'keydown #history-filter': (event) ->
 		if event.which is 13
diff --git a/packages/rocketchat-ui/views/app/privateHistory.html b/packages/rocketchat-ui/views/app/privateHistory.html
index 7b51de5161cd0af6e14acd06109220772742101b..0d0acc27482ba98017a449637fc64e710e345911 100644
--- a/packages/rocketchat-ui/views/app/privateHistory.html
+++ b/packages/rocketchat-ui/views/app/privateHistory.html
@@ -1,6 +1,7 @@
 <template name="privateHistory">
 	<section class="page-container page-list">
 		<header class="fixed-title">
+			{{> burger}}
 			<h2>
 				<span class="room-title">{{_ "History"}}</span>
 			</h2>
@@ -35,6 +36,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 d77154139d66e5886a1df1808f82b72a80d613b6..a50f595194f0e746e901ee852f3a36a939f13fac 100644
--- a/packages/rocketchat-ui/views/app/room.coffee
+++ b/packages/rocketchat-ui/views/app/room.coffee
@@ -32,6 +32,9 @@ Template.room.helpers
 	hasMore: ->
 		return RoomHistoryManager.hasMore this._id
 
+	hasMoreNext: ->
+		return RoomHistoryManager.hasMoreNext this._id
+
 	isLoading: ->
 		return RoomHistoryManager.isLoading this._id
 
@@ -75,6 +78,11 @@ Template.room.helpers
 		else
 			return roomData.name
 
+	roomTopic: ->
+		roomData = Session.get('roomData' + this._id)
+		return '' unless roomData
+		return roomData.topic
+
 	roomIcon: ->
 		roomData = Session.get('roomData' + this._id)
 		return '' unless roomData?.t
@@ -101,26 +109,9 @@ Template.room.helpers
 		return '' unless roomData
 		return roomData.t is 'c'
 
-	canEditName: ->
-		roomData = Session.get('roomData' + this._id)
-		return '' unless roomData
-		if roomData.t in ['c', 'p']
-			return RocketChat.authz.hasAtLeastOnePermission('edit-room', this._id)
-		else
-			return ''
-
 	canDirectMessage: ->
 		return Meteor.user()?.username isnt this.username
 
-	roomNameEdit: ->
-		return Session.get('roomData' + this._id)?.name
-
-	editingTitle: ->
-		return 'hidden' if Session.get('editRoomTitle')
-
-	showEditingTitle: ->
-		return 'hidden' if not Session.get('editRoomTitle')
-
 	flexOpened: ->
 		return 'opened' if RocketChat.TabBar.isFlexOpen()
 
@@ -189,7 +180,7 @@ Template.room.helpers
 
 	formatUnreadSince: ->
 		room = ChatRoom.findOne(this._id, { reactive: false })
-		room = RoomManager.openedRooms[room.t + room.name]
+		room = RoomManager.openedRooms[room?.t + room?.name]
 		date = room?.unreadSince.get()
 		if not date? then return
 
@@ -210,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) ->
@@ -236,9 +229,18 @@ Template.room.events
 	"click .upload-progress > a": ->
 		Session.set "uploading-cancel-#{this.id}", true
 
-	"click .unread-bar > a": ->
+	"click .unread-bar > a.mark-read": ->
 		readMessage.readNow(true)
 
+	"click .unread-bar > a.jump-to": ->
+		message = RoomHistoryManager.getRoom(@_id)?.firstUnread.get()
+		if message?
+			RoomHistoryManager.getSurroundingMessages(message, 50)
+		else
+			subscription = ChatSubscription.findOne({ rid: @_id })
+			message = ChatMessage.find({ rid: @_id, ts: { $gt: subscription?.ls } }, { sort: { ts: 1 }, limit: 1 }).fetch()[0]
+			RoomHistoryManager.getSurroundingMessages(message, 50)
+
 	"click .flex-tab .more": (event, t) ->
 		if RocketChat.TabBar.isFlexOpen()
 			Session.set('rtcLayoutmode', 0)
@@ -287,21 +289,9 @@ Template.room.events
 			$('#room-title-field').focus().select()
 		, 10
 
-	'keydown #room-title-field': (event) ->
-		if event.keyCode is 27 # esc
-			Session.set('editRoomTitle', false)
-		else if event.keyCode is 13 # enter
-			renameRoom @_id, $(event.currentTarget).val()
-
-	'blur #room-title-field': (event) ->
-		# TUDO: create a configuration to select the desired behaviour
-		# renameRoom this._id, $(event.currentTarget).val()
-		Session.set('editRoomTitle', false)
-		$(".fixed-title").removeClass "visible"
-
 	"click .flex-tab .user-image > a" : (e) ->
 		RocketChat.TabBar.openFlex()
-		Session.set('showUserInfo', $(e.currentTarget).data('username'))
+		Session.set('showUserInfo', @username)
 
 	'click .user-card-message': (e) ->
 		roomData = Session.get('roomData' + this._arguments[1].rid)
@@ -313,9 +303,11 @@ Template.room.events
 		RocketChat.TabBar.setTemplate 'membersList'
 
 	'scroll .wrapper': _.throttle (e, instance) ->
-		if RoomHistoryManager.hasMore(@_id) is true and RoomHistoryManager.isLoading(@_id) is false
-			if e.target.scrollTop is 0
+		if RoomHistoryManager.isLoading(@_id) is false and (RoomHistoryManager.hasMore(@_id) is true or RoomHistoryManager.hasMoreNext(@_id) is true)
+			if RoomHistoryManager.hasMore(@_id) is true and e.target.scrollTop is 0
 				RoomHistoryManager.getMore(@_id)
+			else if RoomHistoryManager.hasMoreNext(@_id) is true and e.target.scrollTop >= e.target.scrollHeight - e.target.clientHeight
+				RoomHistoryManager.getMoreNext(@_id)
 	, 200
 
 	'click .load-more > a': ->
@@ -347,6 +339,8 @@ Template.room.events
 		dropDown.show()
 
 	'click .message-dropdown .message-action': (e, t) ->
+		e.preventDefault()
+		e.stopPropagation()
 		el = $(e.currentTarget)
 
 		button = RocketChat.MessageAction.getButtonById el.data('id')
@@ -368,14 +362,7 @@ Template.room.events
 
 	'click .image-to-download': (event) ->
 		ChatMessage.update {_id: this._arguments[1]._id, 'urls.url': $(event.currentTarget).data('url')}, {$set: {'urls.$.downloadImages': true}}
-
-	'click .pin-message': (event) ->
-		message = @_arguments[1]
-		instance = Template.instance()
-		if message.pinned
-			chatMessages[Session.get('openedRoom')].unpinMsg(message)
-		else
-			chatMessages[Session.get('openedRoom')].pinMsg(message)
+		ChatMessage.update {_id: this._arguments[1]._id, 'attachments.image_url': $(event.currentTarget).data('url')}, {$set: {'attachments.$.downloadImages': true}}
 
 	'dragenter .dropzone': (e) ->
 		e.currentTarget.classList.add 'over'
@@ -427,6 +414,35 @@ Template.room.events
 	'load img': (e, template) ->
 		template.sendToBottomIfNecessary?()
 
+	'click .jump-recent .jump-link': (e, template) ->
+		e.preventDefault()
+		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
@@ -435,17 +451,58 @@ 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
 
-	@autorun ->
-		self.subscribe 'fullUserData', Session.get('showUserInfo'), 1
+			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')
 
-Template.room.onDestroyed ->
-	RocketChat.TabBar.resetButtons()
+	this.getSelectedMessages = =>
+		messages = this.selectedMessages
+		addMessages = false
+		for message in this.selectedRange
+			if messages.indexOf(message) is -1
+				addMessages = true
+				break
 
-	window.removeEventListener 'resize', this.onWindowResize
+		if addMessages
+			previewMessages = _.compact(_.uniq(this.selectedMessages.concat(this.selectedRange)))
+		else
+			previewMessages = _.compact(_.difference(this.selectedMessages, this.selectedRange))
+
+		return previewMessages
 
+	@autorun =>
+		@subscribe 'fullUserData', Session.get('showUserInfo'), 1
+
+	Meteor.call 'getRoomModeratorsAndOwners', @data._id, (error, results) ->
+		if error
+			return toastr.error error.reason
+
+		for record in results
+			delete record._id
+			RoomModeratorsAndOwners.upsert { rid: record.rid, "u._id": record.u._id }, record
+
+Template.room.onDestroyed ->
+	window.removeEventListener 'resize', this.onWindowResize
 
 Template.room.onRendered ->
 	unless window.chatMessages
@@ -539,7 +596,7 @@ Template.room.onRendered ->
 			firstMessage = ChatMessage.findOne firstMessageOnScreen.id
 			if firstMessage?
 				subscription = ChatSubscription.findOne rid: template.data._id
-				template.unreadCount.set ChatMessage.find({rid: template.data._id, ts: {$lt: firstMessage.ts, $gt: subscription.ls}}).count()
+				template.unreadCount.set ChatMessage.find({rid: template.data._id, ts: {$lt: firstMessage.ts, $gt: subscription?.ls}}).count()
 			else
 				template.unreadCount.set 0
 	, 300
@@ -564,36 +621,3 @@ Template.room.onRendered ->
 			if webrtc.localUrl.get()?
 				RocketChat.TabBar.setTemplate 'membersList'
 				RocketChat.TabBar.openFlex()
-
-
-renameRoom = (rid, name) ->
-	name = name?.toLowerCase().trim()
-	console.log 'room renameRoom' if window.rocketDebug
-	room = Session.get('roomData' + rid)
-	if room.name is name
-		Session.set('editRoomTitle', false)
-		return false
-
-	Meteor.call 'saveRoomName', rid, name, (error, result) ->
-		if result
-			Session.set('editRoomTitle', false)
-			# If room was renamed then close current room and send user to the new one
-			RoomManager.close room.t + room.name
-			switch room.t
-				when 'c'
-					FlowRouter.go 'channel', name: name
-				when 'p'
-					FlowRouter.go 'group', name: name
-
-			toastr.success t('Room_name_changed_successfully')
-		if error
-			if error.error is 'name-invalid'
-				toastr.error t('Invalid_room_name', name)
-				return
-			if error.error is 'duplicate-name'
-				if room.t is 'c'
-					toastr.error t('Duplicate_channel_name', name)
-				else
-					toastr.error t('Duplicate_private_group_name', name)
-				return
-			toastr.error error.reason
diff --git a/packages/rocketchat-ui/views/app/room.html b/packages/rocketchat-ui/views/app/room.html
index 010ab8427bf99b2df4a97133967ce3face4de03a..483ef9d45651a00f0495917a096560d8f60b5140 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">
@@ -42,17 +39,20 @@
 				{{#if unreadCount}}
 					{{#if unreadSince}}
 						<div class="unread-bar">
+							<a class="jump-to">
+								{{_ "Jump_to_first_unread"}}
+							</a>
 							{{_ "S_new_messages_since_s" unreadCount formatUnreadSince}}
-							<a>
+							<a class="mark-read">
 								{{_ "Mark_as_read"}}
 							</a>
 						</div>
 					{{/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">
+				<div class="wrapper {{#if hasMoreNext}}has-more-next{{/if}}">
 					<ul aria-live="polite">
 						{{#if hasMore}}
 							<li class="load-more">
@@ -70,12 +70,24 @@
 						{{#each messagesHistory}}
 							{{#nrr nrrargs 'message' .}}{{/nrr}}
 						{{/each}}
+						{{#if hasMoreNext}}
+							<li class="load-more">
+								{{#if isLoading}}
+									<div class="load-more-loading">{{_ "Loading_more_from_history"}}...</div>
+								{{else}}
+									<a href="">{{_ "Has_more"}}...</a>
+								{{/if}}
+							</li>
+						{{/if}}
 					</ul>
 				</div>
 				<div class="new-message not">
 					<i class="icon-down-big"></i>
 					<span>{{_ "New_messages"}}</span>
 				</div>
+				<div class="jump-recent {{#unless hasMoreNext}}not{{/unless}}">
+					<span class="jump-link">{{_ "Jump_to_recent_messages"}} <i class="icon-level-down"></i></span>
+				</div>
 			</div>
 			<footer class="footer">
 				{{> messageBox}}
@@ -85,4 +97,4 @@
 			{{> Template.dynamic template=flexTemplate data=flexData}}
 		</section>
 	</div>
-</template>
\ No newline at end of file
+</template>
diff --git a/packages/rocketchat-ui/views/app/videoCall/videoButtons.html b/packages/rocketchat-ui/views/app/videoCall/videoButtons.html
index fac8fced5888c9c5a85f4eb91ddc92bd02923f37..d8f442d60ff704ea11351d6485286b55d59f520e 100644
--- a/packages/rocketchat-ui/views/app/videoCall/videoButtons.html
+++ b/packages/rocketchat-ui/views/app/videoCall/videoButtons.html
@@ -3,11 +3,11 @@
 		{{#if videoAvaliable}}
 			{{#unless videoActive}}
 				{{#if callInProgress}}
-					<button class="join-video-call button secondary"><i class="icon-videocam"></i>{{_ "Join"}}</button>
-					<button class="join-audio-call button secondary"><i class="icon-phone"></i>{{_ "Join"}}</button>
+					<button class="join-video-call button secondary" aria-label="{{_ "Join_video_call"}}"><i class="icon-videocam"></i></button>
+					<button class="join-audio-call button secondary" aria-label="{{_ "Join_audio_call"}}"><i class="icon-phone"></i></button>
 				{{else}}
-					<button class="start-video-call button"><i class="icon-videocam"></i>{{_ "Start"}}</button>
-					<button class="start-audio-call button"><i class="icon-phone"></i></button>
+					<button class="start-video-call button" aria-label="{{_ "Start_video_call"}}"><i class="icon-videocam"></i></button>
+					<button class="start-audio-call button" aria-label="{{_ "Start_audio_call"}}"><i class="icon-phone"></i></button>
 				{{/if}}
 			{{/unless}}
 		{{/if}}
diff --git a/packages/rocketchat-webrtc/i18n/ar.i18n.json b/packages/rocketchat-webrtc/i18n/ar.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..0e117a1ef1efa2c2143aabfe3e2fe9ea82bf4bd5 100644
--- a/packages/rocketchat-webrtc/i18n/ar.i18n.json
+++ b/packages/rocketchat-webrtc/i18n/ar.i18n.json
@@ -1 +1,5 @@
-{ }
\ No newline at end of file
+{
+  "WebRTC_Enable_Channel" : "تمكين للقنوات العامة",
+  "WebRTC_Enable_Direct" : "تمكين للرسائل المباشرة",
+  "WebRTC_Enable_Private" : "تمكين للقنوات الخاصة"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-webrtc/i18n/de.i18n.json b/packages/rocketchat-webrtc/i18n/de.i18n.json
index 4f6f648650c1927a007156851661ce52a758db0e..7376b712967a42f4fa7776549f3c78741cc21516 100644
--- a/packages/rocketchat-webrtc/i18n/de.i18n.json
+++ b/packages/rocketchat-webrtc/i18n/de.i18n.json
@@ -1,5 +1,5 @@
 {
-  "WebRTC_Enable_Channel" : "Aktivieren für öffentliche Kanäle",
-  "WebRTC_Enable_Direct" : "Aktivieren für Direktnachrichten",
-  "WebRTC_Enable_Private" : "Aktivieren für private Kanäle"
+  "WebRTC_Enable_Channel" : "Für öffentliche Kanäle aktivieren",
+  "WebRTC_Enable_Direct" : "Für private Nachrichten aktivieren",
+  "WebRTC_Enable_Private" : "Für private Kanäle aktivieren"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-webrtc/i18n/fr.i18n.json b/packages/rocketchat-webrtc/i18n/fr.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..588bdc0b4b23ac0f3cf08706a100691305ab7690 100644
--- a/packages/rocketchat-webrtc/i18n/fr.i18n.json
+++ b/packages/rocketchat-webrtc/i18n/fr.i18n.json
@@ -1 +1,5 @@
-{ }
\ No newline at end of file
+{
+  "WebRTC_Enable_Channel" : "Activer pour les canaux publics",
+  "WebRTC_Enable_Direct" : "Activer pour les messages directs",
+  "WebRTC_Enable_Private" : "Activer pour les canaux privés"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-webrtc/i18n/ko.i18n.json b/packages/rocketchat-webrtc/i18n/ko.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..122c0f35f3a99d300178a5845deb86cc6abd69fc 100644
--- a/packages/rocketchat-webrtc/i18n/ko.i18n.json
+++ b/packages/rocketchat-webrtc/i18n/ko.i18n.json
@@ -1 +1,5 @@
-{ }
\ No newline at end of file
+{
+  "WebRTC_Enable_Channel" : "공개 채널 사용",
+  "WebRTC_Enable_Direct" : "귓속말 사용",
+  "WebRTC_Enable_Private" : "비밀 그룹 사용"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-webrtc/i18n/nl.i18n.json b/packages/rocketchat-webrtc/i18n/nl.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..4df60fc80b8c5cb74fe0aaf5c65ef00ee257d0f5 100644
--- a/packages/rocketchat-webrtc/i18n/nl.i18n.json
+++ b/packages/rocketchat-webrtc/i18n/nl.i18n.json
@@ -1 +1,5 @@
-{ }
\ No newline at end of file
+{
+  "WebRTC_Enable_Channel" : "Toestaan voor openbare kanalen",
+  "WebRTC_Enable_Direct" : "Toestaan directe-berichten",
+  "WebRTC_Enable_Private" : "Toestaan voor privé-berichten"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-webrtc/i18n/ro.i18n.json b/packages/rocketchat-webrtc/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..c4481eb992373156babf2a2aff7ae75d05897cbb
--- /dev/null
+++ b/packages/rocketchat-webrtc/i18n/ro.i18n.json
@@ -0,0 +1,5 @@
+{
+  "WebRTC_Enable_Channel" : "Activați pentru canale publice",
+  "WebRTC_Enable_Direct" : "Activați pentru mesaje directe",
+  "WebRTC_Enable_Private" : "Activați pentru canale private"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-webrtc/i18n/ru.i18n.json b/packages/rocketchat-webrtc/i18n/ru.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..4fa803614951bdb558ea8550118f74dbe715c666 100644
--- a/packages/rocketchat-webrtc/i18n/ru.i18n.json
+++ b/packages/rocketchat-webrtc/i18n/ru.i18n.json
@@ -1 +1,5 @@
-{ }
\ No newline at end of file
+{
+  "WebRTC_Enable_Channel" : "Включить для публичных чатов",
+  "WebRTC_Enable_Direct" : "Включить для личных сообщений",
+  "WebRTC_Enable_Private" : "Включить для приватных чатов"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-webrtc/i18n/sr.i18n.json b/packages/rocketchat-webrtc/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-webrtc/i18n/sr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-webrtc/package.js b/packages/rocketchat-webrtc/package.js
index 5ed915027e3395829ab308aa4e8a7c66c611bc54..555b1db1f24e3d43213cb38a6eac3e3796b7587c 100644
--- a/packages/rocketchat-webrtc/package.js
+++ b/packages/rocketchat-webrtc/package.js
@@ -8,7 +8,7 @@ Package.describe({
 Package.onUse(function(api) {
 	api.versionsFrom('1.0');
 
-	api.use('rocketchat:lib@0.0.1');
+	api.use('rocketchat:lib');
 	api.use('coffeescript');
 
 	api.addFiles('adapter.js', 'client');
@@ -26,9 +26,8 @@ Package.onUse(function(api) {
 			return 'i18n/' + filename;
 		}
 	}));
-	api.use('tap:i18n@1.6.1', ['client', 'server']);
-	api.imply('tap:i18n');
-	api.addFiles(tapi18nFiles, ['client', 'server']);
+	api.use('tap:i18n');
+	api.addFiles(tapi18nFiles);
 
 	api.export('WebRTC');
 });
diff --git a/packages/rocketchat-wordpress/i18n/de.i18n.json b/packages/rocketchat-wordpress/i18n/de.i18n.json
index f269571244df1451a940dd96e71b0bb9cddcb336..a95a71ed381fa63f85db1a94ec543d4fc0aafcc5 100644
--- a/packages/rocketchat-wordpress/i18n/de.i18n.json
+++ b/packages/rocketchat-wordpress/i18n/de.i18n.json
@@ -1,6 +1,6 @@
 {
-  "API_Wordpress_URL" : "Wordpress URL",
-  "Accounts_OAuth_Wordpress" : "WordPress Login",
-  "Accounts_OAuth_Wordpress_id" : "Wordpress-ID",
-  "Accounts_OAuth_Wordpress_secret" : "WordPress Secret"
+  "API_Wordpress_URL" : "Wordpress-URL",
+  "Accounts_OAuth_Wordpress" : "Anmeldung über Wordpress",
+  "Accounts_OAuth_Wordpress_id" : "WordPress-ID",
+  "Accounts_OAuth_Wordpress_secret" : "Wordpress-Secret"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-wordpress/i18n/fr.i18n.json b/packages/rocketchat-wordpress/i18n/fr.i18n.json
index 315cdb25a08636af5fdb05ab0450f5c6d0b7e2b5..abda39cd1254929eabc5e416ae21479ef4dac1e7 100644
--- a/packages/rocketchat-wordpress/i18n/fr.i18n.json
+++ b/packages/rocketchat-wordpress/i18n/fr.i18n.json
@@ -1,6 +1,6 @@
 {
   "API_Wordpress_URL" : "WordPress URL",
   "Accounts_OAuth_Wordpress" : "WordPress Login",
-  "Accounts_OAuth_Wordpress_id" : "WordPress ID",
+  "Accounts_OAuth_Wordpress_id" : "ID WordPress",
   "Accounts_OAuth_Wordpress_secret" : "WordPress Secret"
 }
\ No newline at end of file
diff --git a/packages/rocketchat-wordpress/i18n/nl.i18n.json b/packages/rocketchat-wordpress/i18n/nl.i18n.json
index 6f31cf5a2e622e523ae008338072897b8e56c993..1de9bd9e80c19d058704b87b764e036db82b7dbc 100644
--- a/packages/rocketchat-wordpress/i18n/nl.i18n.json
+++ b/packages/rocketchat-wordpress/i18n/nl.i18n.json
@@ -1 +1,6 @@
-{ }
\ No newline at end of file
+{
+  "API_Wordpress_URL" : "WordPress URL",
+  "Accounts_OAuth_Wordpress" : "WordPress Inloggen",
+  "Accounts_OAuth_Wordpress_id" : "WordPress Id",
+  "Accounts_OAuth_Wordpress_secret" : "WordPress Geheim (secret)"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-wordpress/i18n/ro.i18n.json b/packages/rocketchat-wordpress/i18n/ro.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..18fe2bdf9468caecd50e8c0c3b7d5691d514b178
--- /dev/null
+++ b/packages/rocketchat-wordpress/i18n/ro.i18n.json
@@ -0,0 +1,6 @@
+{
+  "API_Wordpress_URL" : "URL WordPress",
+  "Accounts_OAuth_Wordpress" : "Autentificare WordPress",
+  "Accounts_OAuth_Wordpress_id" : " Id WordPress",
+  "Accounts_OAuth_Wordpress_secret" : "WordPress Secret"
+}
\ No newline at end of file
diff --git a/packages/rocketchat-wordpress/i18n/sr.i18n.json b/packages/rocketchat-wordpress/i18n/sr.i18n.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f31cf5a2e622e523ae008338072897b8e56c993
--- /dev/null
+++ b/packages/rocketchat-wordpress/i18n/sr.i18n.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/packages/rocketchat-wordpress/package.js b/packages/rocketchat-wordpress/package.js
index 6bd7e5d6bf208b792eee05be480017489ec51eb0..a219fc6b77a7db2ba3eebff603692a96eedbe513 100644
--- a/packages/rocketchat-wordpress/package.js
+++ b/packages/rocketchat-wordpress/package.js
@@ -1,30 +1,29 @@
 Package.describe({
-    name: 'rocketchat:wordpress',
-    version: '0.0.1',
-    summary: 'RocketChat settings for WordPress Oauth Flow'
+	name: 'rocketchat:wordpress',
+	version: '0.0.1',
+	summary: 'RocketChat settings for WordPress Oauth Flow'
 });
 
 Package.onUse(function(api) {
-    api.versionsFrom('1.0');
-    api.use('coffeescript');
-    api.use('rocketchat:lib@0.0.1');
-    api.use('rocketchat:custom-oauth');
-    api.addFiles("common.coffee");
-    api.addFiles('wordpress-login-button.css', 'client');
-    api.addFiles('startup.coffee', 'server');
-    
-    // TAPi18n
-    api.use('templating', 'client');
-    var _ = Npm.require('underscore');
-    var fs = Npm.require('fs');
-    tapi18nFiles = _.compact(_.map(fs.readdirSync('packages/rocketchat-wordpress/i18n'), function(filename) {
-        if (fs.statSync('packages/rocketchat-wordpress/i18n/' + filename).size > 16) {
-            return 'i18n/' + filename;
-        }
-    }));
-    api.use('tap:i18n@1.6.1', ['client', 'server']);
-    api.imply('tap:i18n');
-    api.addFiles(tapi18nFiles, ['client', 'server']);
+	api.versionsFrom('1.0');
+	api.use('coffeescript');
+	api.use('rocketchat:lib');
+	api.use('rocketchat:custom-oauth');
+	api.addFiles("common.coffee");
+	api.addFiles('wordpress-login-button.css', 'client');
+	api.addFiles('startup.coffee', 'server');
+
+	// TAPi18n
+	api.use('templating', 'client');
+	var _ = Npm.require('underscore');
+	var fs = Npm.require('fs');
+	tapi18nFiles = _.compact(_.map(fs.readdirSync('packages/rocketchat-wordpress/i18n'), function(filename) {
+		if (fs.statSync('packages/rocketchat-wordpress/i18n/' + filename).size > 16) {
+			return 'i18n/' + filename;
+		}
+	}));
+	api.use('tap:i18n');
+	api.addFiles(tapi18nFiles);
 });
 
 Package.onTest(function(api) {
diff --git a/private/node_scripts/unsubscribe_csv/package.json b/private/node_scripts/unsubscribe_csv/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..1efe93181ce21f7a771b053c5cb2b78832af3d30
--- /dev/null
+++ b/private/node_scripts/unsubscribe_csv/package.json
@@ -0,0 +1,20 @@
+{
+  "name": "unsubscribe_csv",
+  "version": "0.0.1",
+  "private": true,
+  "scripts": {
+    "start": "coffee unsubscribe.coffee",
+    "test": "mocha --compilers coffee:coffee-script --timeout 5s -R spec"
+  },
+  "dependencies": {
+    "coffee-script": "~1.6.3",
+    "commander": "^2.9.0",
+    "ddp": "^0.11.0",
+    "line-by-line": "^0.1.3",
+    "line-reader": "^0.2.4",
+    "moment": "^2.10.2",
+    "mongodb": "^2.1.0",
+    "underscore": "^1.6.0",
+    "wait.for": "^0.6.6"
+  }
+}
diff --git a/private/node_scripts/unsubscribe_csv/unsubscribe.coffee b/private/node_scripts/unsubscribe_csv/unsubscribe.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..450d03329f8c8f51b0b1c1643e3071d4d60329a6
--- /dev/null
+++ b/private/node_scripts/unsubscribe_csv/unsubscribe.coffee
@@ -0,0 +1,33 @@
+_ = require 'underscore'
+
+fs = require('fs')
+lineReader = require('line-reader')
+moment = require('moment')
+path = require('path')
+program = require('commander')
+wait = require('wait.for')
+
+MongoClient = require('mongodb').MongoClient
+
+program
+	.usage '[options]'
+	.option '-v, --verbose', 'Verbose', ((v, total) -> total + 1), 0
+	.option '-M, --mongo-db [mongo db]', 'Mongo DB', 'localhost:27017'
+	.option '-N, --db-name [db name]', 'DB Name', 'meteor'
+	.on '--help', ->
+		console.log '  Example:'
+		console.log ''
+		console.log '    $ coffee unsubscribe.coffee'
+		console.log ''
+	.parse process.argv
+
+wait.launchFiber ->
+	db = wait.forMethod MongoClient, 'connect', "mongodb://#{program.mongoDb}/#{program.dbName}", { replSet: { socketOptions: { connectTimeoutMS: 300000 } } }
+	User = db.collection 'users'
+	lineReader.eachLine './unsubscribe.csv', (line, last) ->
+		row = line.split ','
+		console.log row[0] if program.verbose
+		wait.launchFiber ->
+			updated = wait.forMethod User, 'update', { "emails.address": row[0] }, { $set: { "mailer.unsubscribed": true } }
+			if last
+				process.exit()
diff --git a/rocketchat.info b/rocketchat.info
deleted file mode 100644
index 49886ade63fb2c01118ec35a597fccb332138612..0000000000000000000000000000000000000000
--- a/rocketchat.info
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-	"version": "0.9.0"
-}
diff --git a/scalingo.json b/scalingo.json
new file mode 100644
index 0000000000000000000000000000000000000000..92ee06f04f6769510963a39856ab3d6e2565a9b8
--- /dev/null
+++ b/scalingo.json
@@ -0,0 +1,8 @@
+{
+  "name": "Rocket.Chat",
+  "repository": "https://github.com/RocketChat/Rocket.Chat",
+  "description": "Have your own open-source Slack-like online chat, built with Meteor.",
+  "logo": "https://raw.githubusercontent.com/RocketChat/Rocket.Chat/master/public/images/logo/512x512.png?v=3",
+  "website": "https://rocket.chat",
+  "addons": ["scalingo-mongodb"]
+}
diff --git a/server/lib/accounts.coffee b/server/lib/accounts.coffee
index b9531f2ea1a66a3b2e9ad3d86cd30195acb67e5c..061af1ad93515680b31ac12ae8eb5043322faadf 100644
--- a/server/lib/accounts.coffee
+++ b/server/lib/accounts.coffee
@@ -1,8 +1,8 @@
 # Deny Account.createUser in client and set Meteor.loginTokenExpires
 accountsConfig = { forbidClientAccountCreation: true, loginExpirationInDays: RocketChat.settings.get 'Accounts_LoginExpiration' }
 
-if RocketChat.settings.get('Account_AllowedDomainsList')
-	domainWhiteList = _.map RocketChat.settings.get('Account_AllowedDomainsList').split(','), (domain) -> domain.trim()
+if RocketChat.settings.get('Accounts_AllowedDomainsList')
+	domainWhiteList = _.map RocketChat.settings.get('Accounts_AllowedDomainsList').split(','), (domain) -> domain.trim()
 	accountsConfig.restrictCreationByEmailDomain = (email) ->
 		ret = false
 		for domain in domainWhiteList
@@ -24,8 +24,8 @@ Accounts.emailTemplates.verifyEmail.text = (user, url) ->
 
 resetPasswordText = Accounts.emailTemplates.resetPassword.text
 Accounts.emailTemplates.resetPassword.text = (user, url) ->
-	url = url.replace Meteor.absoluteUrl(), Meteor.absoluteUrl() + 'login/'
-	verifyEmailText user, url
+	url = url.replace /\/#\//, '/'
+	resetPasswordText user, url
 
 if RocketChat.settings.get 'Accounts_Enrollment_Email'
 	Accounts.emailTemplates.enrollAccount.text = (user, url) ->
@@ -69,16 +69,25 @@ Accounts.onCreateUser (options, user) ->
 	return user
 
 # Wrap insertUserDoc to allow executing code after Accounts.insertUserDoc is run
-Accounts.insertUserDoc = _.wrap Accounts.insertUserDoc, (insertUserDoc) ->
-	options = arguments[1]
-	user = arguments[2]
+Accounts.insertUserDoc = _.wrap Accounts.insertUserDoc, (insertUserDoc, options, user) ->
+	roles = []
+	if Match.test(user.globalRoles, [String]) and user.globalRoles.length > 0
+		roles = roles.concat user.globalRoles
+
+	delete user.globalRoles
+
 	_id = insertUserDoc.call(Accounts, options, user)
 
-	# when inserting first user give them admin privileges otherwise make a regular user
-	firstUser = RocketChat.models.Users.findOne({ _id: { $ne: 'rocket.cat' }}, { sort: { createdAt: 1 }})
-	roleName = if firstUser?._id is _id then 'admin' else 'user'
+	if roles.length is 0
+		# when inserting first user give them admin privileges otherwise make a regular user
+		firstUser = RocketChat.models.Users.findOne({ _id: { $ne: 'rocket.cat' }}, { sort: { createdAt: 1 }})
+		if firstUser?._id is _id
+			roles.push 'admin'
+		else
+			roles.push 'user'
+
+	RocketChat.authz.addUserRoles(_id, roles)
 
-	RocketChat.authz.addUsersToRoles(_id, roleName)
 	RocketChat.callbacks.run 'afterCreateUser', options, user
 	return _id
 
diff --git a/server/methods/addRoomModerator.coffee b/server/methods/addRoomModerator.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..eca8b3af439138094da44280fd74f6a36b72d90f
--- /dev/null
+++ b/server/methods/addRoomModerator.coffee
@@ -0,0 +1,25 @@
+Meteor.methods
+	addRoomModerator: (rid, userId) ->
+		unless Meteor.userId()
+			throw new Meteor.Error 'invalid-user', '[methods] addRoomModerator -> Invalid user'
+
+		check rid, String
+		check userId, String
+
+		unless RocketChat.authz.hasPermission Meteor.userId(), 'set-moderator', rid
+			throw new Meteor.Error 403, 'Not allowed'
+
+		subscription = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId rid, userId
+		unless subscription?
+			throw new Meteor.Error 'invalid-subscription', '[methods] addRoomModerator -> Invalid Subscription'
+
+		RocketChat.models.Subscriptions.addRoleById(subscription._id, 'moderator')
+
+		user = RocketChat.models.Users.findOneById userId
+		fromUser = RocketChat.models.Users.findOneById Meteor.userId()
+		RocketChat.models.Messages.createNewModeratorWithRoomIdAndUser rid, user,
+			u:
+				_id: fromUser._id
+				username: fromUser.username
+
+		return true
diff --git a/server/methods/addRoomOwner.coffee b/server/methods/addRoomOwner.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..d3838be0b0355221ff471b05021ec55f32cda053
--- /dev/null
+++ b/server/methods/addRoomOwner.coffee
@@ -0,0 +1,25 @@
+Meteor.methods
+	addRoomOwner: (rid, userId) ->
+		unless Meteor.userId()
+			throw new Meteor.Error 'invalid-user', '[methods] addRoomOwner -> Invalid user'
+
+		check rid, String
+		check userId, String
+
+		unless RocketChat.authz.hasPermission Meteor.userId(), 'set-owner', rid
+			throw new Meteor.Error 403, 'Not allowed'
+
+		subscription = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId rid, userId
+		unless subscription?
+			throw new Meteor.Error 'invalid-subscription', '[methods] addRoomOwner -> Invalid Subscription'
+
+		RocketChat.models.Subscriptions.addRoleById(subscription._id, 'owner')
+
+		user = RocketChat.models.Users.findOneById userId
+		fromUser = RocketChat.models.Users.findOneById Meteor.userId()
+		RocketChat.models.Messages.createNewOwnerWithRoomIdAndUser rid, user,
+			u:
+				_id: fromUser._id
+				username: fromUser.username
+
+		return true
diff --git a/server/methods/addUserToRoom.coffee b/server/methods/addUserToRoom.coffee
index cf1dd53963521cf98b32c9028b6ac8d069e52812..3cfd91d7346d9c36e1d7dbd40a9a3dc851f8b17a 100644
--- a/server/methods/addUserToRoom.coffee
+++ b/server/methods/addUserToRoom.coffee
@@ -1,8 +1,6 @@
 Meteor.methods
 	addUserToRoom: (data) ->
 		fromId = Meteor.userId()
-		console.log '[methods] addUserToRoom -> '.green, 'data:', data
-
 		unless Match.test data?.rid, String
 			throw new Meteor.Error 'invalid-rid'
 
diff --git a/server/methods/archiveRoom.coffee b/server/methods/archiveRoom.coffee
index abfcef70b12c8d3fd36e04f3e12911a13fd152eb..e1d86612d1d6241e8c52eca265dd7a0d2dccbd5f 100644
--- a/server/methods/archiveRoom.coffee
+++ b/server/methods/archiveRoom.coffee
@@ -3,8 +3,6 @@ Meteor.methods
 		if not Meteor.userId()
 			throw new Meteor.Error 'invalid-user', '[methods] archiveRoom -> Invalid user'
 
-		console.log '[methods] archiveRoom -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
-
 		room = RocketChat.models.Rooms.findOneById rid
 
 		if room.u? and room.u._id is Meteor.userId() or RocketChat.authz.hasRole(Meteor.userId(), 'admin')
diff --git a/server/methods/canAccessRoom.coffee b/server/methods/canAccessRoom.coffee
index 2d5cd6ff3303082c13fdf8211a7b5ec6e78334e1..4d84b6a8d7621582edb48132d0a90069189792c3 100644
--- a/server/methods/canAccessRoom.coffee
+++ b/server/methods/canAccessRoom.coffee
@@ -1,7 +1,5 @@
 Meteor.methods
 	canAccessRoom: (rid, userId) ->
-		console.log '[methods] canAccessRoom -> '.green, 'userId:', userId, 'rid:', rid
-
 		user = RocketChat.models.Users.findOneById userId, fields: username: 1
 
 		unless user?.username
@@ -10,7 +8,7 @@ Meteor.methods
 		unless rid
 			throw new Meteor.Error 'invalid-room', '[methods] canAccessRoom -> Cannot access empty room'
 
-		room = RocketChat.models.Rooms.findOneById rid, { fields: { usernames: 1, t: 1, name: 1 } }
+		room = RocketChat.models.Rooms.findOneById rid, { fields: { usernames: 1, t: 1, name: 1, muted: 1 } }
 
 		if room
 			if room.t is 'c'
@@ -21,6 +19,6 @@ Meteor.methods
 			if canAccess isnt true
 				return false
 			else
-				return _.pick room, ['_id', 't', 'name', 'usernames']
+				return _.pick room, ['_id', 't', 'name', 'usernames', 'muted']
 		else
 			throw new Meteor.Error 'invalid-room', '[methods] canAccessRoom -> Room ID is invalid'
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 3c8319079d3791ea17e6b1d4ca1eaa5c29b8528a..3edf800ec94e6e9c9c29e3f38cccc0a5a9d2353a 100644
--- a/server/methods/createChannel.coffee
+++ b/server/methods/createChannel.coffee
@@ -14,8 +14,6 @@ Meteor.methods
 		if RocketChat.authz.hasPermission(Meteor.userId(), 'create-c') isnt true
 			throw new Meteor.Error 'not-authorized', '[methods] createChannel -> Not authorized'
 
-		console.log '[methods] createChannel -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
-
 		now = new Date()
 		user = Meteor.user()
 
@@ -23,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
 
@@ -40,9 +41,6 @@ Meteor.methods
 		room = RocketChat.models.Rooms.createWithTypeNameUserAndUsernames 'c', name, user, members,
 			ts: now
 
-		# set creator as channel moderator.  permission limited to channel by scoping to rid
-		RocketChat.authz.addUsersToRoles(Meteor.userId(), 'moderator', room._id)
-
 		for username in members
 			member = RocketChat.models.Users.findOneByUsername username
 			if not member?
@@ -56,6 +54,9 @@ Meteor.methods
 
 			RocketChat.models.Subscriptions.createWithRoomAndUser room, member, extra
 
+		# set creator as channel moderator.  permission limited to channel by scoping to rid
+		RocketChat.authz.addUserRoles(Meteor.userId(), ['moderator','owner'], room._id)
+
 		Meteor.defer ->
 			RocketChat.callbacks.run 'afterCreateChannel', user, room
 
diff --git a/server/methods/createDirectMessage.coffee b/server/methods/createDirectMessage.coffee
index 5fa5934680c0a5389acd593b2143e48f296b7bc7..48dc97b1e5f313e8641644f2f7f6b98e9b7e2445 100644
--- a/server/methods/createDirectMessage.coffee
+++ b/server/methods/createDirectMessage.coffee
@@ -3,8 +3,6 @@ Meteor.methods
 		if not Meteor.userId()
 			throw new Meteor.Error 'invalid-user', "[methods] createDirectMessage -> Invalid user"
 
-		console.log '[methods] createDirectMessage -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
-
 		me = Meteor.user()
 
 		if me.username is username
diff --git a/server/methods/createPrivateGroup.coffee b/server/methods/createPrivateGroup.coffee
index 22080081372ebf7cf1f4b94c8ccb4a32e5a33dae..657fa879463b8d4cff8c1f08e0f0ebf22d4b2d41 100644
--- a/server/methods/createPrivateGroup.coffee
+++ b/server/methods/createPrivateGroup.coffee
@@ -6,8 +6,6 @@ Meteor.methods
 		unless RocketChat.authz.hasPermission(Meteor.userId(), 'create-p')
 			throw new Meteor.Error 'not-authorized', '[methods] createPrivateGroup -> Not authorized'
 
-		console.log '[methods] createPrivateGroup -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
-
 		try
 			nameValidation = new RegExp '^' + RocketChat.settings.get('UTF8_Names_Validation') + '$'
 		catch
@@ -26,14 +24,17 @@ 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,
 			ts: now
 
 		# set creator as group moderator.  permission limited to group by scoping to rid
-		RocketChat.authz.addUsersToRoles(Meteor.userId(), 'moderator', room._id)
+		RocketChat.authz.addUserRoles(Meteor.userId(), ['moderator','owner'], room._id)
 
 		for username in members
 			member = RocketChat.models.Users.findOneByUsername(username, { fields: { username: 1 }})
diff --git a/server/methods/deleteMessage.coffee b/server/methods/deleteMessage.coffee
index fbf66bb76b2545a3cdf63e1b89434ad6626fe2ff..5e96a7cc4abeb8b3eda5a8ba90173364862e81a5 100644
--- a/server/methods/deleteMessage.coffee
+++ b/server/methods/deleteMessage.coffee
@@ -15,8 +15,6 @@ Meteor.methods
 		unless hasPermission or (deleteAllowed and deleteOwn)
 			throw new Meteor.Error 'message-deleting-not-allowed', "[methods] deleteMessage -> Message deleting not allowed"
 
-		console.log '[methods] deleteMessage -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
-
 		keepHistory = RocketChat.settings.get 'Message_KeepHistory'
 		showDeletedStatus = RocketChat.settings.get 'Message_ShowDeletedStatus'
 
diff --git a/server/methods/eraseRoom.coffee b/server/methods/eraseRoom.coffee
index a8c6f8248b7acba6ebbbee73c64f3bb07dbbef4e..5c82b18cb4c9e922fccf4566ccefef080c5cab05 100644
--- a/server/methods/eraseRoom.coffee
+++ b/server/methods/eraseRoom.coffee
@@ -5,8 +5,6 @@ Meteor.methods
 		roomType = RocketChat.models.Rooms.findOneById(rid)?.t
 
 		if RocketChat.authz.hasPermission( fromId, "delete-#{roomType}", rid )
-			# console.log '[methods] eraseRoom -> '.green, 'fromId:', fromId, 'rid:', rid
-
 			# ChatRoom.update({ _id: rid}, {'$pull': { userWatching: Meteor.userId(), userIn: Meteor.userId() }})
 
 			RocketChat.models.Messages.removeByRoomId rid
diff --git a/server/methods/getRoomIdByNameOrId.coffee b/server/methods/getRoomIdByNameOrId.coffee
index 50d6a4a0c64ba06ddba90699d7cdc12eb87c44a0..4634081feb0e4b7528d8872e4f363fb02626268b 100644
--- a/server/methods/getRoomIdByNameOrId.coffee
+++ b/server/methods/getRoomIdByNameOrId.coffee
@@ -1,8 +1,6 @@
 Meteor.methods
 	getRoomIdByNameOrId: (rid) ->
 
-		console.log '[methods] getRoomIdByNameOrId-> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
-
 		room = RocketChat.models.Rooms.findOneById rid
 
 		if not room?
diff --git a/server/methods/getRoomModeratorsAndOwners.coffee b/server/methods/getRoomModeratorsAndOwners.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..37adf0601566e9d76ac1481a58837144ab540559
--- /dev/null
+++ b/server/methods/getRoomModeratorsAndOwners.coffee
@@ -0,0 +1,16 @@
+Meteor.methods
+	getRoomModeratorsAndOwners: (rid) ->
+		unless Meteor.userId()
+			throw new Meteor.Error 'invalid-user', '[methods] getRoomModeratorsAndOwners -> Invalid user'
+
+		check rid, String
+
+		options =
+			sort:
+				"u.username": 1
+			fields:
+				rid: 1
+				u: 1
+				roles: 1
+
+		return RocketChat.models.Subscriptions.findByRoomIdAndRoles(rid, ['moderator', 'owner'], options).fetch()
diff --git a/server/methods/getTotalChannels.coffee b/server/methods/getTotalChannels.coffee
index f791683e8c2486cd03f3a4ecc1605bfa0f095350..8c318d78a158ac6582264065c1ce547e1a40964d 100644
--- a/server/methods/getTotalChannels.coffee
+++ b/server/methods/getTotalChannels.coffee
@@ -3,5 +3,4 @@ Meteor.methods
     if not Meteor.userId()
       throw new Meteor.Error 'invalid-user', '[methods] getTotalChannels -> Invalid user'
 
-    console.log '[methods] getTotalChannels -> '.green, 'userId:', Meteor.userId()
     return RocketChat.models.Rooms.find({ t: 'c' }).count()
diff --git a/server/methods/hideRoom.coffee b/server/methods/hideRoom.coffee
index 3537394aef40fbd515a4daeb771e751e80fa2739..cbb2d6023c0d393943f2300b95a14a80d500ff64 100644
--- a/server/methods/hideRoom.coffee
+++ b/server/methods/hideRoom.coffee
@@ -3,6 +3,4 @@ Meteor.methods
 		if not Meteor.userId()
 			throw new Meteor.Error 'invalid-user', '[methods] hideRoom -> Invalid user'
 
-		console.log '[methods] hideRoom -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
-
 		RocketChat.models.Subscriptions.hideByRoomIdAndUserId rid, Meteor.userId()
diff --git a/server/methods/joinRoom.coffee b/server/methods/joinRoom.coffee
index 81666400b1463dfa6013ad410d5c7f9aa5862ca5..42e9630474dbfd1796ce0001408aa79fd05f119d 100644
--- a/server/methods/joinRoom.coffee
+++ b/server/methods/joinRoom.coffee
@@ -3,8 +3,6 @@ Meteor.methods
 
 		room = RocketChat.models.Rooms.findOneById rid
 
-		console.log '[methods] joinRoom -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
-
 		if not room?
 			throw new Meteor.Error 500, 'No channel with this id'
 
diff --git a/server/methods/leaveRoom.coffee b/server/methods/leaveRoom.coffee
index 4ff40c087fb97c4b32a5e931adbc13ca61c6b066..d54faba3fb162daa63eb23d20524759f47ebe0f6 100644
--- a/server/methods/leaveRoom.coffee
+++ b/server/methods/leaveRoom.coffee
@@ -1,8 +1,6 @@
 Meteor.methods
 	leaveRoom: (rid) ->
 		fromId = Meteor.userId()
-		# console.log '[methods] leaveRoom -> '.green, 'fromId:', fromId, 'rid:', rid
-
 		unless Meteor.userId()?
 			throw new Meteor.Error 300, 'Usuário não logado'
 
diff --git a/server/methods/loadHistory.coffee b/server/methods/loadHistory.coffee
index 921bfae150a9a21e46346007b69a7f1badc27e1f..3c3fea2213240a18fe28c2757947911de343c134 100644
--- a/server/methods/loadHistory.coffee
+++ b/server/methods/loadHistory.coffee
@@ -1,8 +1,6 @@
 Meteor.methods
 	loadHistory: (rid, end, limit=20, ls) ->
 		fromId = Meteor.userId()
-		# console.log '[methods] loadHistory -> '.green, 'fromId:', fromId, 'rid:', rid, 'end:', end, 'limit:', limit, 'skip:', skip
-
 		unless Meteor.call 'canAccessRoom', rid, fromId
 			return false
 
@@ -29,9 +27,12 @@ Meteor.methods
 			firstMessage = messages[messages.length - 1]
 			if firstMessage?.ts > ls
 				delete options.limit
-				unreadNotLoaded = RocketChat.models.Messages.findVisibleByRoomIdBetweenTimestamps(rid, ls, firstMessage.ts).count()
+				unreadMessages = RocketChat.models.Messages.findVisibleByRoomIdBetweenTimestamps(rid, ls, firstMessage.ts, { limit: 1, sort: { ts: 1 } })
+				firstUnread = unreadMessages.fetch()[0]
+				unreadNotLoaded = unreadMessages.count()
 
 		return {
 			messages: messages
+			firstUnread: firstUnread
 			unreadNotLoaded: unreadNotLoaded
 		}
diff --git a/server/methods/loadLocale.coffee b/server/methods/loadLocale.coffee
index f4ed82c228ab664c9e125380ed58dc8c057d6683..17f4c2d87586b94a344b30ef063629f9c3eae40b 100644
--- a/server/methods/loadLocale.coffee
+++ b/server/methods/loadLocale.coffee
@@ -1,6 +1,5 @@
 Meteor.methods
 	loadLocale: (locale) ->
-		console.log "[method] loadLocale: #{locale}".green
 		try
 			return Assets.getText "moment-locales/#{locale.toLowerCase()}.js"
 		catch e
diff --git a/server/methods/loadMissedMessages.coffee b/server/methods/loadMissedMessages.coffee
index e6c201aa77b229b7685c53bdc84114fcf201814e..7d22fe1fd452d4156892cdc4448fef34b5e0cdcc 100644
--- a/server/methods/loadMissedMessages.coffee
+++ b/server/methods/loadMissedMessages.coffee
@@ -1,8 +1,6 @@
 Meteor.methods
 	loadMissedMessages: (rid, start) ->
 		fromId = Meteor.userId()
-		# console.log '[methods] loadMissedMessages -> '.green, 'fromId:', fromId, 'rid:', rid, 'start:', start
-
 		unless Meteor.call 'canAccessRoom', rid, fromId
 			return false
 
diff --git a/server/methods/loadNextMessages.coffee b/server/methods/loadNextMessages.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..91a600bfc43bd3722cb7c108b8aa9b59580042da
--- /dev/null
+++ b/server/methods/loadNextMessages.coffee
@@ -0,0 +1,27 @@
+Meteor.methods
+	loadNextMessages: (rid, end, limit=20) ->
+		fromId = Meteor.userId()
+
+		unless Meteor.call 'canAccessRoom', rid, fromId
+			return false
+
+		options =
+			sort:
+				ts: 1
+			limit: limit
+
+		if not RocketChat.settings.get 'Message_ShowEditedStatus'
+			options.fields = { 'editedAt': 0 }
+
+		if end?
+			records = RocketChat.models.Messages.findVisibleByRoomIdAfterTimestamp(rid, end, options).fetch()
+		else
+			records = RocketChat.models.Messages.findVisibleByRoomId(rid, options).fetch()
+
+		messages = _.map records, (message) ->
+			message.starred = _.findWhere message.starred, { _id: fromId }
+			return message
+
+		return {
+			messages: messages
+		}
diff --git a/server/methods/loadSurroundingMessages.coffee b/server/methods/loadSurroundingMessages.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..0d63b37531c0fb9554f4eee93d8b99922063dbb4
--- /dev/null
+++ b/server/methods/loadSurroundingMessages.coffee
@@ -0,0 +1,46 @@
+Meteor.methods
+	loadSurroundingMessages: (message, limit=50) ->
+		fromId = Meteor.userId()
+
+		unless message?.rid
+			return false
+
+		unless Meteor.call 'canAccessRoom', message.rid, fromId
+			return false
+
+		if not RocketChat.settings.get 'Message_ShowEditedStatus'
+			options.fields = { 'editedAt': 0 }
+
+		limit = limit - 1
+
+		options =
+			sort:
+				ts: -1
+			limit: Math.ceil(limit/2)
+		records = RocketChat.models.Messages.findVisibleByRoomIdBeforeTimestamp(message.rid, message.ts, options).fetch()
+		messages = _.map records, (message) ->
+			message.starred = _.findWhere message.starred, { _id: fromId }
+			return message
+
+		moreBefore = messages.length is options.limit
+
+		messages.push message
+
+		options =
+			sort:
+				ts: 1
+			limit: Math.floor(limit/2)
+		records = RocketChat.models.Messages.findVisibleByRoomIdAfterTimestamp(message.rid, message.ts, options).fetch()
+		afterMessages = _.map records, (message) ->
+			message.starred = _.findWhere message.starred, { _id: fromId }
+			return message
+
+		moreAfter = afterMessages.length is options.limit
+
+		messages = messages.concat afterMessages
+
+		return {
+			messages: messages
+			moreBefore: moreBefore
+			moreAfter: moreAfter
+		}
diff --git a/server/methods/logoutCleanUp.coffee b/server/methods/logoutCleanUp.coffee
index 4bf8d65487eb9d10fc17352f82dd578116368672..7d5615c3cb8f9cb4f2a60998ef05af27715c9aa6 100644
--- a/server/methods/logoutCleanUp.coffee
+++ b/server/methods/logoutCleanUp.coffee
@@ -1,7 +1,5 @@
 Meteor.methods
 	logoutCleanUp: (user) ->
-		console.log '[methods] logoutCleanUp -> '.green, 'userId:', user._id
-
 		Meteor.defer ->
 
-			RocketChat.callbacks.run 'afterLogoutCleanUp', user
\ No newline at end of file
+			RocketChat.callbacks.run 'afterLogoutCleanUp', user
diff --git a/server/methods/messageSearch.coffee b/server/methods/messageSearch.coffee
index 0f1a714d39257666a34153074f08559bf414af16..4c5d99a6151c0075d38d1b7131916f805ca8fb5a 100644
--- a/server/methods/messageSearch.coffee
+++ b/server/methods/messageSearch.coffee
@@ -1,11 +1,9 @@
 Meteor.methods
-	messageSearch: (text, rid) ->
+	messageSearch: (text, rid, limit) ->
 		###
 			text = 'from:rodrigo mention:gabriel chat'
 		###
 
-		# console.log '[method] -> messageSearch', text
-
 		result =
 			messages: []
 			users: []
@@ -15,7 +13,7 @@ Meteor.methods
 		options =
 			sort:
 				ts: -1
-			limit: 20
+			limit: limit or 20
 
 		# Query for senders
 		from = []
@@ -56,14 +54,21 @@ Meteor.methods
 			# 		$meta: 'textScore'
 
 		if Object.keys(query).length > 0
+			query.t = { $ne: 'rm' } # hide removed messages (userful when searching for user messages)
+			query._hidden = { $ne: true } # don't return _hidden messages
+
 			# Filter by room
 			if rid?
 				query.rid = rid
 				try
 					if Meteor.call('canAccessRoom', rid, this.userId) isnt false
+						console.log query
 						result.messages = RocketChat.models.Messages.find(query, options).fetch()
 
 
+		# make sure we don't return more than limit results
+		# limit -= result.messages?.length
+
 		# ###
 		# # USERS
 		# ###
diff --git a/server/methods/migrate.coffee b/server/methods/migrate.coffee
index 915b4582f37ac9de86dd7a76f8c332ef4ef56917..3b01619a1c8b6f13010558481160048a68503054 100644
--- a/server/methods/migrate.coffee
+++ b/server/methods/migrate.coffee
@@ -3,12 +3,11 @@ Meteor.methods
 		user = Meteor.user()
 
 		if not user? or RocketChat.authz.hasPermission(user._id, 'run-migration') isnt true
-			console.log '[methods] createChannel -> Not authorized'
-			return
+			throw new Meteor.Error "not-authorized", '[methods] migrateTo'
 
 		this.unblock()
 		Migrations.migrateTo version
 		return version
 
 	getMigrationVersion: ->
-		return Migrations.getVersion()
\ No newline at end of file
+		return Migrations.getVersion()
diff --git a/server/methods/muteUserInRoom.coffee b/server/methods/muteUserInRoom.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..1cff2d7de019844ba684fbae04b6b89633396282
--- /dev/null
+++ b/server/methods/muteUserInRoom.coffee
@@ -0,0 +1,29 @@
+Meteor.methods
+	muteUserInRoom: (data) ->
+		fromId = Meteor.userId()
+		check(data, Match.ObjectIncluding({ rid: String, username: String }))
+
+		unless RocketChat.authz.hasPermission(fromId, 'mute-user', data.rid)
+			throw new Meteor.Error 'not-allowed', '[methods] muteUserInRoom -> Not allowed'
+
+		room = RocketChat.models.Rooms.findOneById data.rid
+		if not room
+			throw new Meteor.Error 'invalid-room', '[methods] muteUserInRoom -> Room ID is invalid'
+
+		if room.t not in ['c', 'p']
+			throw new Meteor.Error 'invalid-room-type', '[methods] muteUserInRoom -> Invalid room type'
+
+		if data.username not in (room?.usernames or [])
+			throw new Meteor.Error 'not-in-room', '[methods] muteUserInRoom -> User is not in this room'
+
+		mutedUser = RocketChat.models.Users.findOneByUsername data.username
+
+		RocketChat.models.Rooms.muteUsernameByRoomId data.rid, mutedUser.username
+
+		fromUser = RocketChat.models.Users.findOneById fromId
+		RocketChat.models.Messages.createUserMutedWithRoomIdAndUser data.rid, mutedUser,
+			u:
+				_id: fromUser._id
+				username: fromUser.username
+
+		return true
diff --git a/server/methods/openRoom.coffee b/server/methods/openRoom.coffee
index 9dcb5d818d2b672bb536588fa1cf509a83ce5060..2b2536c87f4fa3bd4fb049441568fc7d08cdf8e9 100644
--- a/server/methods/openRoom.coffee
+++ b/server/methods/openRoom.coffee
@@ -3,6 +3,4 @@ Meteor.methods
     if not Meteor.userId()
       throw new Meteor.Error 'invalid-user', '[methods] openRoom -> Invalid user'
 
-    console.log '[methods] openRoom -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
-
     RocketChat.models.Subscriptions.openByRoomIdAndUserId rid, Meteor.userId()
diff --git a/server/methods/readMessages.coffee b/server/methods/readMessages.coffee
index 35dc63a998dcf0afb813f014869daab2d1616318..985d6050505d2dda1c6015e198f6b151be3d4eca 100644
--- a/server/methods/readMessages.coffee
+++ b/server/methods/readMessages.coffee
@@ -3,6 +3,4 @@ Meteor.methods
 		if not Meteor.userId()
 			throw new Meteor.Error 'invalid-user', '[methods] readMessages -> Invalid user'
 
-		console.log '[methods] readMessages -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
-
 		RocketChat.models.Subscriptions.setAsReadByRoomIdAndUserId rid, Meteor.userId()
diff --git a/server/methods/removeRoomModerator.coffee b/server/methods/removeRoomModerator.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..50ee2aa570e39513389a893b4b9dd185722055ea
--- /dev/null
+++ b/server/methods/removeRoomModerator.coffee
@@ -0,0 +1,25 @@
+Meteor.methods
+	removeRoomModerator: (rid, userId) ->
+		unless Meteor.userId()
+			throw new Meteor.Error 'invalid-user', '[methods] removeRoomModerator -> Invalid user'
+
+		check rid, String
+		check userId, String
+
+		unless RocketChat.authz.hasPermission Meteor.userId(), 'set-moderator', rid
+			throw new Meteor.Error 403, 'Not allowed'
+
+		subscription = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId rid, userId
+		unless subscription?
+			throw new Meteor.Error 'invalid-subscription', '[methods] removeRoomModerator -> Invalid Subscription'
+
+		RocketChat.models.Subscriptions.removeRoleById(subscription._id, 'moderator')
+
+		user = RocketChat.models.Users.findOneById userId
+		fromUser = RocketChat.models.Users.findOneById Meteor.userId()
+		RocketChat.models.Messages.createModeratorRemovedWithRoomIdAndUser rid, user,
+			u:
+				_id: fromUser._id
+				username: fromUser.username
+
+		return true
diff --git a/server/methods/removeRoomOwner.coffee b/server/methods/removeRoomOwner.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..b29a5f431ec81f7e503a514ffb8c7eeff85ac584
--- /dev/null
+++ b/server/methods/removeRoomOwner.coffee
@@ -0,0 +1,25 @@
+Meteor.methods
+	removeRoomOwner: (rid, userId) ->
+		unless Meteor.userId()
+			throw new Meteor.Error 'invalid-user', '[methods] removeRoomOwner -> Invalid user'
+
+		check rid, String
+		check userId, String
+
+		unless RocketChat.authz.hasPermission Meteor.userId(), 'set-owner', rid
+			throw new Meteor.Error 403, 'Not allowed'
+
+		subscription = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId rid, userId
+		unless subscription?
+			throw new Meteor.Error 'invalid-subscription', '[methods] removeRoomOwner -> Invalid Subscription'
+
+		RocketChat.models.Subscriptions.removeRoleById(subscription._id, 'owner')
+
+		user = RocketChat.models.Users.findOneById userId
+		fromUser = RocketChat.models.Users.findOneById Meteor.userId()
+		RocketChat.models.Messages.createOwnerRemovedWithRoomIdAndUser rid, user,
+			u:
+				_id: fromUser._id
+				username: fromUser.username
+
+		return true
diff --git a/server/methods/removeUserFromRoom.coffee b/server/methods/removeUserFromRoom.coffee
index d600b6d991ce7a3b2a538bbc8cac8d4fdff2d68b..2c737d9e83d2cad82dfe0869a56d000d6f521d17 100644
--- a/server/methods/removeUserFromRoom.coffee
+++ b/server/methods/removeUserFromRoom.coffee
@@ -1,25 +1,29 @@
 Meteor.methods
 	removeUserFromRoom: (data) ->
 		fromId = Meteor.userId()
-		# console.log '[methods] removeUserFromRoom -> '.green, 'fromId:', fromId, 'data:', data
+		check(data, Match.ObjectIncluding({ rid: String, username: String }))
+
+		unless RocketChat.authz.hasPermission(fromId, 'remove-user', data.rid)
+			throw new Meteor.Error 'not-allowed', 'Not allowed'
 
 		room = RocketChat.models.Rooms.findOneById data.rid
 
-		if room.u?._id isnt Meteor.userId() and room.t is 'c'
-			throw new Meteor.Error 403, 'Not allowed'
+		if data.username not in (room?.usernames or [])
+			throw new Meteor.Error 'not-in-room', 'User is not in this room'
 
 		removedUser = RocketChat.models.Users.findOneByUsername data.username
 
 		RocketChat.models.Rooms.removeUsernameById data.rid, data.username
 
-		RocketChat.models.Subscriptions.removeByRoomIdAndUserId data.rid, data.username
+		RocketChat.models.Subscriptions.removeByRoomIdAndUserId data.rid, removedUser._id
 
-		switch room.t
-			when 'c'
-				RocketChat.authz.removeUsersFromRole(removedUser._id; 'channel-moderator',  data.rid)
-			when 'p'
-				RocketChat.authz.removeUsersFromRole(removedUser._id; 'group-moderator',  data.rid)
+		if room.t in [ 'c', 'p' ]
+			RocketChat.authz.removeUserFromRoles(removedUser._id, ['moderator', 'owner'], data.rid)
 
-		RocketChat.models.Messages.createUserRemovedWithRoomIdAndUser data.rid, removedUser
+		fromUser = RocketChat.models.Users.findOneById fromId
+		RocketChat.models.Messages.createUserRemovedWithRoomIdAndUser data.rid, removedUser,
+			u:
+				_id: fromUser._id
+				username: fromUser.username
 
 		return true
diff --git a/server/methods/resetAvatar.coffee b/server/methods/resetAvatar.coffee
index 0bb66f0d14023e2cc76900285df917a8e6bb21a9..e6ff5278eca16c6dfe81a6c2652438bab38e6dd8 100644
--- a/server/methods/resetAvatar.coffee
+++ b/server/methods/resetAvatar.coffee
@@ -6,8 +6,6 @@ Meteor.methods
 		unless RocketChat.settings.get("Accounts_AllowUserAvatarChange")
 			throw new Meteor.Error(403, "[methods] resetAvatar -> Invalid access")
 
-		console.log '[methods] resetAvatar -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
-
 		user = Meteor.user()
 
 		RocketChatFileAvatarInstance.deleteFile "#{user.username}.jpg"
diff --git a/server/methods/saveRoomName.coffee b/server/methods/saveRoomName.coffee
deleted file mode 100644
index 888d0c74b51766547dad7e04de19c72da7b5fa55..0000000000000000000000000000000000000000
--- a/server/methods/saveRoomName.coffee
+++ /dev/null
@@ -1,39 +0,0 @@
-Meteor.methods
-	saveRoomName: (rid, name) ->
-		if not Meteor.userId()
-			throw new Meteor.Error('invalid-user', "[methods] sendMessage -> Invalid user")
-
-		room = RocketChat.models.Rooms.findOneById rid
-
-		if room.t not in ['c', 'p']
-			throw new Meteor.Error 403, 'Not allowed'
-
-		unless RocketChat.authz.hasPermission(Meteor.userId(), 'edit-room', rid)
-		#if room.u._id isnt Meteor.userId() and not hasPermission
-			throw new Meteor.Error 403, 'Not allowed'
-
-		try
-			nameValidation = new RegExp '^' + RocketChat.settings.get('UTF8_Names_Validation') + '$'
-		catch
-			nameValidation = new RegExp '^[0-9a-zA-Z-_.]+$'
-
-		if not nameValidation.test name
-			throw new Meteor.Error 'name-invalid'
-
-		if RocketChat.settings.get 'UTF8_Names_Slugify'
-			name = _.slugify name
-
-		if name is room.name
-			return
-
-		# avoid duplicate names
-		if RocketChat.models.Rooms.findOneByName name
-			throw new Meteor.Error 'duplicate-name'
-
-		RocketChat.models.Rooms.setNameById rid, name
-
-		RocketChat.models.Subscriptions.updateNameByRoomId rid, name
-
-		RocketChat.models.Messages.createRoomRenamedWithRoomIdRoomNameAndUser rid, name, Meteor.user()
-
-		return name
diff --git a/server/methods/saveUserPreferences.coffee b/server/methods/saveUserPreferences.coffee
index 5cf457a2315b861da789c1a0fff7a71b3e7f15db..39da131efdbf58e2f71470af26eee20108d2c45a 100644
--- a/server/methods/saveUserPreferences.coffee
+++ b/server/methods/saveUserPreferences.coffee
@@ -1,7 +1,5 @@
 Meteor.methods
 	saveUserPreferences: (settings) ->
-		console.log '[method] saveUserPreferences', settings
-
 		if Meteor.userId()
 			preferences = {}
 
diff --git a/server/methods/setAvatarFromService.coffee b/server/methods/setAvatarFromService.coffee
index 0df26725a6bd97062776759430fa6a51aa7657b1..045d17ab62eba83481bcecfccf469a913da6d4ba 100644
--- a/server/methods/setAvatarFromService.coffee
+++ b/server/methods/setAvatarFromService.coffee
@@ -6,8 +6,6 @@ Meteor.methods
 		unless RocketChat.settings.get("Accounts_AllowUserAvatarChange")
 			throw new Meteor.Error(403, "[methods] resetAvatar -> Invalid access")
 
-		console.log '[methods] setAvatarFromService -> '.green, 'userId:', Meteor.userId(), 'contentType:', contentType, 'service:', service
-
 		user = Meteor.user()
 
 		if service is 'initials'
@@ -62,4 +60,4 @@ DDPRateLimiter.addRule
 	type: 'method'
 	name: 'setAvatarFromService'
 	userId: -> return true
-, 1, 60000
+, 1, 5000
diff --git a/server/methods/toogleFavorite.coffee b/server/methods/toogleFavorite.coffee
index 853bfe00c771cfc28e06313dff18b38b83739537..58c4faa75359c182bea83cc8c04689df91904df5 100644
--- a/server/methods/toogleFavorite.coffee
+++ b/server/methods/toogleFavorite.coffee
@@ -3,6 +3,4 @@ Meteor.methods
 		if not Meteor.userId()
 			throw new Meteor.Error('invalid-user', "[methods] toogleFavorite -> Invalid user")
 
-		console.log '[methods] toogleFavorite -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
-
 		RocketChat.models.Subscriptions.setFavoriteByRoomIdAndUserId rid, Meteor.userId(), f
diff --git a/server/methods/unarchiveRoom.coffee b/server/methods/unarchiveRoom.coffee
index eed9cbfdc2d048c87babee2d981d30270d4b57b4..b78a843b8e598437042609c128a7d7f586494407 100644
--- a/server/methods/unarchiveRoom.coffee
+++ b/server/methods/unarchiveRoom.coffee
@@ -1,9 +1,7 @@
 Meteor.methods
-	unArchiveRoom: (rid) ->
+	unarchiveRoom: (rid) ->
 		if not Meteor.userId()
-			throw new Meteor.Error 'invalid-user', '[methods] unArchiveRoom -> Invalid user'
-
-		console.log '[methods] unArchiveRoom -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
+			throw new Meteor.Error 'invalid-user', '[methods] unarchiveRoom -> Invalid user'
 
 		room = RocketChat.models.Rooms.findOneById rid
 
diff --git a/server/methods/unmuteUserInRoom.coffee b/server/methods/unmuteUserInRoom.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..cec5d061c342c87cbca3165e88e4be0d09df0758
--- /dev/null
+++ b/server/methods/unmuteUserInRoom.coffee
@@ -0,0 +1,29 @@
+Meteor.methods
+	unmuteUserInRoom: (data) ->
+		fromId = Meteor.userId()
+		check(data, Match.ObjectIncluding({ rid: String, username: String }))
+
+		unless RocketChat.authz.hasPermission(fromId, 'mute-user', data.rid)
+			throw new Meteor.Error 'not-allowed', '[methods] unmuteUserInRoom -> Not allowed'
+
+		room = RocketChat.models.Rooms.findOneById data.rid
+		if not room
+			throw new Meteor.Error 'invalid-room', '[methods] unmuteUserInRoom -> Room ID is invalid'
+
+		if room.t not in ['c', 'p']
+			throw new Meteor.Error 'invalid-room-type', '[methods] unmuteUserInRoom -> Invalid room type'
+
+		if data.username not in (room?.usernames or [])
+			throw new Meteor.Error 'not-in-room', '[methods] unmuteUserInRoom -> User is not in this room'
+
+		unmutedUser = RocketChat.models.Users.findOneByUsername data.username
+
+		RocketChat.models.Rooms.unmuteUsernameByRoomId data.rid, unmutedUser.username
+
+		fromUser = RocketChat.models.Users.findOneById fromId
+		RocketChat.models.Messages.createUserUnmutedWithRoomIdAndUser data.rid, unmutedUser,
+			u:
+				_id: fromUser._id
+				username: fromUser.username
+
+		return true
diff --git a/server/methods/updateMessage.coffee b/server/methods/updateMessage.coffee
index 09ce1aa2d6f58b05aac92e1e35985dddd3079e81..966c52399d5b877794094f8074bc2733dc047689 100644
--- a/server/methods/updateMessage.coffee
+++ b/server/methods/updateMessage.coffee
@@ -24,8 +24,6 @@ Meteor.methods
 			if currentTsDiff > blockEditInMinutes
 				throw new Meteor.Error 'message-editing-blocked'
 
-		console.log '[methods] updateMessage -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
-
 		# If we keep history of edits, insert a new message to store history information
 		if RocketChat.settings.get 'Message_KeepHistory'
 			RocketChat.models.Messages.cloneAndSaveAsHistoryById originalMessage._id
@@ -35,7 +33,7 @@ Meteor.methods
 			_id: Meteor.userId()
 			username: me.username
 
-		if urls = message.msg.match /([A-Za-z]{3,9}):\/\/([-;:&=\+\$,\w]+@{1})?([-A-Za-z0-9\.]+)+:?(\d+)?((\/[-\+=!:~%\/\.@\,\w]+)?\??([-\+=&!:;%@\/\.\,\w]+)?#?([\w]+)?)?/g
+		if urls = message.msg.match /([A-Za-z]{3,9}):\/\/([-;:&=\+\$,\w]+@{1})?([-A-Za-z0-9\.]+)+:?(\d+)?((\/[-\+=!:~%\/\.@\,\w]+)?\??([-\+=&!:;%@\/\.\,\w]+)?#?([^\s]+)?)?/g
 			message.urls = urls.map (url) -> url: url
 
 		message = RocketChat.callbacks.run 'beforeSaveMessage', message
diff --git a/server/publications/activeUsers.coffee b/server/publications/activeUsers.coffee
index ba420634b09432f4c04b9032fa4384234e17c7b0..65e3675b6a07b4ae6e9b6a6d35389ce3424724e8 100644
--- a/server/publications/activeUsers.coffee
+++ b/server/publications/activeUsers.coffee
@@ -2,8 +2,6 @@ Meteor.publish 'activeUsers', ->
 	unless this.userId
 		return this.ready()
 
-	console.log '[publish] activeUsers'.green
-
 	RocketChat.models.Users.findUsersNotOffline
 		fields:
 			username: 1
diff --git a/server/publications/adminRooms.coffee b/server/publications/adminRooms.coffee
index bceec2d8c51ac8f2cbdfddc8d1df7f223211d6cb..638077d5ee54be91879d0d941ee5517a099cfd95 100644
--- a/server/publications/adminRooms.coffee
+++ b/server/publications/adminRooms.coffee
@@ -15,14 +15,13 @@ Meteor.publish 'adminRooms', (filter, types, limit) ->
 			cl: 1
 			u: 1
 			usernames: 1
+			muted: 1
 		limit: limit
 		sort:
 			name: 1
 
 	filter = _.trim filter
 
-	console.log '[publish] adminRooms'.green, filter, types, limit
-
 	if filter and types.length
 		return RocketChat.models.Rooms.findByNameContainingAndTypes filter, types, options
 
diff --git a/server/publications/channelAutocomplete.coffee b/server/publications/channelAutocomplete.coffee
index eebbea4bc8f060b0313b12df539bb50cf4600f50..7586b0242ef676b1ed4fd7ff221ab482e2d7ed42 100644
--- a/server/publications/channelAutocomplete.coffee
+++ b/server/publications/channelAutocomplete.coffee
@@ -2,8 +2,6 @@ Meteor.publish 'channelAutocomplete', (name) ->
 	unless this.userId
 		return this.ready()
 
-	console.log '[publish] channelAutocomplete -> '.green, name
-
 	pub = this
 
 	options =
diff --git a/server/publications/filteredUsers.coffee b/server/publications/filteredUsers.coffee
index fd93452f85c12b144437e437639dfd8585ec14b8..d1316d71ea3bb97f05c7d6aee0207d03d5ae95f2 100644
--- a/server/publications/filteredUsers.coffee
+++ b/server/publications/filteredUsers.coffee
@@ -2,8 +2,6 @@ Meteor.publish 'filteredUsers', (name) ->
 	unless this.userId
 		return this.ready()
 
-	console.log '[publish] filteredUsers'.green, name
-
 	exp = new RegExp(name, 'i')
 
 	options =
diff --git a/server/publications/fullUserData.coffee b/server/publications/fullUserData.coffee
index 255a87542cf33bca2633ae11191100f541da4b2e..95173f5edb82d5b5b146bccfbe8f2630f4915f2e 100644
--- a/server/publications/fullUserData.coffee
+++ b/server/publications/fullUserData.coffee
@@ -31,8 +31,6 @@ Meteor.publish 'fullUserData', (filter, limit) ->
 		limit: limit
 		sort: { username: 1 }
 
-	console.log '[publish] fullUserData'.green, filter, limit
-
 	if filter
 		if limit is 1
 			return RocketChat.models.Users.findByUsername filter, options
diff --git a/server/publications/messages.coffee b/server/publications/messages.coffee
index b2ee7f04918743ce521be74707912ae02e439c00..6e0feba1ccd2acd2f2a6cd1269876ad3bfc43974 100644
--- a/server/publications/messages.coffee
+++ b/server/publications/messages.coffee
@@ -4,8 +4,6 @@ Meteor.publish 'messages', (rid, start) ->
 
 	publication = this
 
-	console.log '[publish] messages ->'.green, 'rid:', rid, 'start:', start
-
 	if typeof rid isnt 'string'
 		return this.ready()
 
diff --git a/server/publications/privateHistory.coffee b/server/publications/privateHistory.coffee
index 9f8eb31f87142cf87100ee0f40721bbd04690cc7..115796f52c8fdeea347acec3447d2df5f083481f 100644
--- a/server/publications/privateHistory.coffee
+++ b/server/publications/privateHistory.coffee
@@ -2,8 +2,6 @@ Meteor.publish 'privateHistory', ->
 	unless this.userId
 		return this.ready()
 
-	console.log '[publish] privateHistory'.green
-
 	RocketChat.models.Rooms.findByContainigUsername RocketChat.models.Users.findOneById(this.userId).username,
 		fields:
 			t: 1
diff --git a/server/publications/room.coffee b/server/publications/room.coffee
index 960f1c40de942e3305d9be872128fe3561d794da..711ba33bc7beb668441de639a521796f2246b3bd 100644
--- a/server/publications/room.coffee
+++ b/server/publications/room.coffee
@@ -2,8 +2,6 @@ Meteor.publish 'room', (typeName) ->
 	unless this.userId
 		return this.ready()
 
-	console.log '[publish] room ->'.green, 'arguments:', arguments
-
 	if typeof typeName isnt 'string'
 		return this.ready()
 
diff --git a/server/publications/roomFiles.coffee b/server/publications/roomFiles.coffee
index 38fce2de1f8c694f2dd8355aa188a918efa78946..e905e740d22f3bf844eb6254f85b37152b97c2e0 100644
--- a/server/publications/roomFiles.coffee
+++ b/server/publications/roomFiles.coffee
@@ -1,34 +1,35 @@
-Meteor.publish 'roomFiles', (rid) ->
-  unless this.userId
-    return this.ready()
-
-  console.log '[publish] roomFiles '.green, rid
-
-  pub = this
-
-  fileQuery =
-    rid: rid
-    complete: true
-    uploading: false
-
-  fileOptions =
-    fields:
-      _id: 1
-      rid: 1
-      name: 1
-      type: 1
-      url: 1
-
-  cursorFileListHandle = fileCollection.find(fileQuery, fileOptions).observeChanges
-    added: (_id, record) ->
-      pub.added('room_files', _id, record)
-
-    changed: (_id, record) ->
-      pub.changed('room_files', _id, record)
-
-    removed: (_id, record) ->
-      pub.removed('room_files', _id, record)
-
-  this.ready()
-  this.onStop ->
-    cursorFileListHandle.stop()
+Meteor.publish 'roomFiles', (rid, limit = 50) ->
+	unless this.userId
+		return this.ready()
+
+	pub = this
+
+	fileQuery =
+		rid: rid
+		complete: true
+		uploading: false
+
+	fileOptions =
+		limit: limit
+		sort:
+			uploadedAt: -1
+		fields:
+			_id: 1
+			rid: 1
+			name: 1
+			type: 1
+			url: 1
+
+	cursorFileListHandle = fileCollection.find(fileQuery, fileOptions).observeChanges
+		added: (_id, record) ->
+			pub.added('room_files', _id, record)
+
+		changed: (_id, record) ->
+			pub.changed('room_files', _id, record)
+
+		removed: (_id, record) ->
+			pub.removed('room_files', _id, record)
+
+	this.ready()
+	this.onStop ->
+		cursorFileListHandle.stop()
diff --git a/server/publications/roomSearch.coffee b/server/publications/roomSearch.coffee
index c499c1a89f7771e4d3f6a807e15cf389c35858de..f3357511223732ff78a673bbdddf9a0402e98fdf 100644
--- a/server/publications/roomSearch.coffee
+++ b/server/publications/roomSearch.coffee
@@ -2,8 +2,6 @@ Meteor.publish 'roomSearch', (selector, options, collName) ->
 	unless this.userId
 		return this.ready()
 
-	console.log '[publish] roomSearch -> '.green, 'selector:', selector, 'options:', options, 'collName:', collName
-
 	self = this
 	searchType = null
 	subHandleUsers = null
diff --git a/server/publications/spotlight.coffee b/server/publications/spotlight.coffee
index 9921d4987e40efab110209e0712d6644d562d07f..feec1ce6f654c85a39dad9b86e730485f2e7f2c3 100644
--- a/server/publications/spotlight.coffee
+++ b/server/publications/spotlight.coffee
@@ -2,8 +2,6 @@ Meteor.publish 'spotlight', (selector, options, collName) ->
 	if not this.userId? or not selector?.name?.$regex?
 		return this.ready()
 
-	console.log '[publish] spotlight -> '.green, 'selector:', selector, 'options:', options, 'collName:', collName
-
 	self = this
 	subHandleUsers = null
 	subHandleRooms = null
diff --git a/server/publications/subscription.coffee b/server/publications/subscription.coffee
index f188e99522e3e6e992eec9813ec4819f354692fe..2aca0e8f1579cfcabc1dd58be47b601abe3e2ca6 100644
--- a/server/publications/subscription.coffee
+++ b/server/publications/subscription.coffee
@@ -2,8 +2,6 @@ Meteor.publish 'subscription', ->
 	unless this.userId
 		return this.ready()
 
-	console.log '[publish] subscription'.green
-
 	RocketChat.models.Subscriptions.findByUserId this.userId,
 		fields:
 			t: 1
@@ -15,3 +13,4 @@ Meteor.publish 'subscription', ->
 			open: 1
 			alert: 1
 			unread: 1
+			archived: 1
diff --git a/server/publications/userAutocomplete.coffee b/server/publications/userAutocomplete.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..0f20eb20524cc1b47ce0124680924df57feb7617
--- /dev/null
+++ b/server/publications/userAutocomplete.coffee
@@ -0,0 +1,26 @@
+Meteor.publish 'userAutocomplete', (selector) ->
+	unless this.userId
+		return this.ready()
+
+	pub = this
+
+	options =
+		fields:
+			name: 1
+			username: 1
+			status: 1
+		limit: 10
+
+	exceptions = selector.exceptions or []
+
+	cursorHandle = RocketChat.models.Users.findActiveByUsernameRegexWithExceptions(selector.username, exceptions, options).observeChanges
+		added: (_id, record) ->
+			pub.added("autocompleteRecords", _id, record)
+		changed: (_id, record) ->
+			pub.changed("autocompleteRecords", _id, record)
+		removed: (_id, record) ->
+			pub.removed("autocompleteRecords", _id, record)
+	@ready()
+	@onStop ->
+		cursorHandle.stop()
+	return
diff --git a/server/publications/userChannels.coffee b/server/publications/userChannels.coffee
index dbacf03b444d152705d891c88411b3ef492b430a..9192dcc635d74892f168466e2dd3dd134745d1d2 100644
--- a/server/publications/userChannels.coffee
+++ b/server/publications/userChannels.coffee
@@ -5,8 +5,6 @@ Meteor.publish 'userChannels', (userId) ->
 	if RocketChat.authz.hasPermission( @userId, 'view-other-user-channels') isnt true
 		return this.ready()
 
-	console.log '[publish] userChannels'.green, userId
-
 	RocketChat.models.Subscriptions.findByUserId userId,
 		fields:
 			rid: 1,
diff --git a/server/publications/userData.coffee b/server/publications/userData.coffee
index f6e5eac51670a043ef7387f33fef2aecc18ecfbb..6f49343368144d518f9daf1a140fe1edcda38161 100644
--- a/server/publications/userData.coffee
+++ b/server/publications/userData.coffee
@@ -2,8 +2,6 @@ Meteor.publish 'userData', ->
 	unless this.userId
 		return this.ready()
 
-	console.log '[publish] userData'.green
-
 	RocketChat.models.Users.find this.userId,
 		fields:
 			name: 1
diff --git a/server/startup/avatar.coffee b/server/startup/avatar.coffee
index 45e9f590c99acbb6189c0eb721a6851938a08fe1..4951142cb4f13894e81883095aff6f7cdda9e0e6 100644
--- a/server/startup/avatar.coffee
+++ b/server/startup/avatar.coffee
@@ -11,12 +11,14 @@ Meteor.startup ->
 
 	console.log "Using #{storeType} for Avatar storage".green
 
-	transformWrite = undefined
-	if RocketChat.settings.get('Accounts_AvatarResize') is true
+	transformWrite = (file, readStream, writeStream) ->
+		if RocketChatFile.enabled is false or RocketChat.settings.get('Accounts_AvatarResize') isnt true
+			return readStream.pipe writeStream
+
 		height = RocketChat.settings.get 'Accounts_AvatarSize'
 		width = height
-		transformWrite = (file, readStream, writeStream) ->
-			RocketChatFile.gm(readStream, file.fileName).background('#ffffff').resize(width, height+'^>').gravity('Center').extent(width, height).stream('jpeg').pipe(writeStream)
+
+		RocketChatFile.gm(readStream, file.fileName).background('#ffffff').resize(width, height+'^>').gravity('Center').extent(width, height).stream('jpeg').pipe(writeStream)
 
 	path = "~/uploads"
 
diff --git a/server/startup/cron.coffee b/server/startup/cron.coffee
index be643bcf42edb3edb7f25a3983a8853a2c58fedb..9bd2f8dd958b685a8766a117639742b3af73f768 100644
--- a/server/startup/cron.coffee
+++ b/server/startup/cron.coffee
@@ -2,22 +2,23 @@
 SyncedCron.config
 	collectionName: 'rocketchat_cron_history'
 
+generateStatistics = ->
+	statistics = RocketChat.statistics.save()
+	statistics.host = Meteor.absoluteUrl()
+	unless RocketChat.settings.get 'Statistics_opt_out'
+		HTTP.post 'https://rocket.chat/stats',
+			data: statistics
+	return
+
 Meteor.startup ->
 	Meteor.defer ->
+		generateStatistics()
 
 		# Generate and save statistics every hour
 		SyncedCron.add
 			name: 'Generate and save statistics',
 			schedule: (parser) -># parser is a later.parse object
 				return parser.text 'every 1 hour'
-			job: ->
-				statistics = RocketChat.statistics.save()
-				statistics.host = Meteor.absoluteUrl()
-				unless RocketChat.settings.get 'Statistics_opt_out'
-					console.log 'Sending statistics data to Rocket.Chat'
-					HTTP.post 'https://rocket.chat/stats', 
-						data: statistics
-					
-				return
+			job: generateStatistics
 
 		SyncedCron.start()
diff --git a/server/startup/initialData.coffee b/server/startup/initialData.coffee
index 47ba296a93f53a23843ae99c2b7a8f3aa9ee0b25..045b6d0673a8f0ed61df01526010d774b2f8470d 100644
--- a/server/startup/initialData.coffee
+++ b/server/startup/initialData.coffee
@@ -41,7 +41,7 @@ Meteor.startup ->
 							name: 'Admin'
 
 						Accounts.setPassword id, process.env.ADMIN_PASS
-						RocketChat.authz.addUsersToRoles( id, 'admin')
+						RocketChat.authz.addUserRoles( id, 'admin')
 
 					else
 						console.log 'E-mail exists; ignoring environment variables ADMIN_EMAIL and ADMIN_PASS'.red
@@ -55,5 +55,5 @@ Meteor.startup ->
 			# get oldest user
 			oldestUser = RocketChat.models.Users.findOne({ _id: { $ne: 'rocket.cat' }}, { fields: { username: 1 }, sort: {createdAt: 1}})
 			if oldestUser
-				RocketChat.authz.addUsersToRoles( oldestUser._id, 'admin')
+				RocketChat.authz.addUserRoles( oldestUser._id, 'admin')
 				console.log "No admins are found. Set #{oldestUser.username} as admin for being the oldest user"
diff --git a/server/startup/migrations/v26.coffee b/server/startup/migrations/v26.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..2e45ece8dcf84e57aa92b139eac2172f43fc5862
--- /dev/null
+++ b/server/startup/migrations/v26.coffee
@@ -0,0 +1,5 @@
+Meteor.startup ->
+	Migrations.add
+		version: 26
+		up: ->
+			RocketChat.models.Messages.update({ t: 'rm' }, { $set: { mentions: [] } }, { multi: true })
diff --git a/server/startup/migrations/v27.coffee b/server/startup/migrations/v27.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..b3f6f7d7716b880f49b67110bb1557bd8ddf8021
--- /dev/null
+++ b/server/startup/migrations/v27.coffee
@@ -0,0 +1,11 @@
+Meteor.startup ->
+	Migrations.add
+		version: 27
+		up: ->
+			RocketChat.models.Users.update({}, { $rename: { roles: '_roles' } }, { multi: true })
+
+			RocketChat.models.Users.find({ _roles: { $exists: 1 } }).forEach (user) ->
+				for scope, roles of user._roles
+					RocketChat.models.Roles.addUserRoles(user._id, roles, scope)
+
+			RocketChat.models.Users.update({}, { $unset: { _roles: 1 } }, { multi: true })
diff --git a/server/startup/roomPublishes.coffee b/server/startup/roomPublishes.coffee
index 409131cc9b475f652eb67ce24a4306dd2a9d525f..85abbe2d8ccb891f66c209f5cc00ccbe94c80b74 100644
--- a/server/startup/roomPublishes.coffee
+++ b/server/startup/roomPublishes.coffee
@@ -7,6 +7,10 @@ Meteor.startup ->
 				cl: 1
 				u: 1
 				usernames: 1
+				topic: 1
+				muted: 1
+				archived: 1
+
 		return RocketChat.models.Rooms.findByTypeAndName 'c', identifier, options
 
 	RocketChat.roomTypes.setPublish 'p', (identifier) ->
@@ -17,6 +21,10 @@ Meteor.startup ->
 				cl: 1
 				u: 1
 				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
 
@@ -28,5 +36,6 @@ Meteor.startup ->
 				cl: 1
 				u: 1
 				usernames: 1
+				topic: 1
 		user = RocketChat.models.Users.findOneById this.userId, fields: username: 1
 		return RocketChat.models.Rooms.findByTypeContainigUsernames 'd', [user.username, identifier], options