GUACAMOLE-1293: Merge user count UI improvements for anonymous users.

diff --git a/guacamole/src/main/frontend/src/app/client/directives/guacClientUserCount.js b/guacamole/src/main/frontend/src/app/client/directives/guacClientUserCount.js
index 313d59c..3c42fc3 100644
--- a/guacamole/src/main/frontend/src/app/client/directives/guacClientUserCount.js
+++ b/guacamole/src/main/frontend/src/app/client/directives/guacClientUserCount.js
@@ -45,6 +45,9 @@
     directive.controller = ['$scope', '$injector', '$element',
         function guacClientUserCountController($scope, $injector, $element) {
 
+        // Required types
+        var AuthenticationResult = $injector.get('AuthenticationResult');
+
         // Required services
         var $translate = $injector.get('$translate');
 
@@ -117,7 +120,10 @@
          *     The username of the user that joined.
          */
         var notifyUserJoined = function notifyUserJoined(username) {
-            notify('CLIENT.TEXT_USER_JOINED', username);
+            if ($scope.isAnonymous(username))
+                notify('CLIENT.TEXT_ANONYMOUS_USER_JOINED', username);
+            else
+                notify('CLIENT.TEXT_USER_JOINED', username);
         };
 
         /**
@@ -128,7 +134,10 @@
          *     The username of the user that left.
          */
         var notifyUserLeft = function notifyUserLeft(username) {
-            notify('CLIENT.TEXT_USER_LEFT', username);
+            if ($scope.isAnonymous(username))
+                notify('CLIENT.TEXT_ANONYMOUS_USER_LEFT', username);
+            else
+                notify('CLIENT.TEXT_USER_LEFT', username);
         };
 
         /**
@@ -143,6 +152,38 @@
          */
         var oldClient = null;
 
+        /**
+         * Returns whether the given username represents an anonymous user.
+         *
+         * @param {!string} username
+         *     The username of the user to check.
+         *
+         * @returns {!boolean}
+         *     true if the given username represents an anonymous user, false
+         *     otherwise.
+         */
+        $scope.isAnonymous = function isAnonymous(username) {
+            return username === AuthenticationResult.ANONYMOUS_USERNAME;
+        };
+
+        /**
+         * Returns the translation key of the translation string that should be
+         * used to render the number of connections a user with the given
+         * username has to the current connection. The appropriate string will
+         * vary by whether the user is anonymous.
+         *
+         * @param {!string} username
+         *     The username of the user to check.
+         *
+         * @returns {!string}
+         *     The translation key of the translation string that should be
+         *     used to render the number of connections the user with the given
+         *     username has to the current connection.
+         */
+        $scope.getUserCountTranslationKey = function getUserCountTranslationKey(username) {
+            return $scope.isAnonymous(username) ? 'CLIENT.INFO_ANONYMOUS_USER_COUNT' : 'CLIENT.INFO_USER_COUNT';
+        };
+
         // Update visible notifications as users join/leave
         $scope.$watchGroup([ 'client', 'client.userCount' ], function usersChanged() {
 
diff --git a/guacamole/src/main/frontend/src/app/client/styles/tiled-client-grid.css b/guacamole/src/main/frontend/src/app/client/styles/tiled-client-grid.css
index 86c9047..7ec0cdf 100644
--- a/guacamole/src/main/frontend/src/app/client/styles/tiled-client-grid.css
+++ b/guacamole/src/main/frontend/src/app/client/styles/tiled-client-grid.css
@@ -244,6 +244,11 @@
     display: inline-block;
 }
 
+.tiled-client-grid .client-user-count .client-user-count-user.anonymous {
+    font-style: italic;
+    opacity: 0.5;
+}
+
 .tiled-client-grid .client-user-count .client-user-count-users {
     width: 256px;
     max-width: 75vw;
diff --git a/guacamole/src/main/frontend/src/app/client/templates/guacClientUserCount.html b/guacamole/src/main/frontend/src/app/client/templates/guacClientUserCount.html
index c03abbf..fa7eff9 100644
--- a/guacamole/src/main/frontend/src/app/client/templates/guacClientUserCount.html
+++ b/guacamole/src/main/frontend/src/app/client/templates/guacClientUserCount.html
@@ -2,8 +2,10 @@
     <span class="client-user-count-value">{{ client.userCount }}</span>
     <ul class="client-user-count-messages"></ul>
     <ul class="client-user-count-users">
-        <li class="client-user-count-user" ng-repeat="user in userCounts | toArray | orderBy: key"
-            translate="CLIENT.INFO_USER_COUNT"
+        <li class="client-user-count-user"
+            ng-repeat="user in userCounts | toArray | orderBy: key"
+            ng-class="{ anonymous : isAnonymous(user.key) }"
+            translate="{{ getUserCountTranslationKey(user.key) }}"
             translate-values="{ USERNAME : user.key, COUNT : user.value }"></li>
     </ul>
 </div>
diff --git a/guacamole/src/main/frontend/src/translations/en.json b/guacamole/src/main/frontend/src/translations/en.json
index 77b59d1..036949b 100644
--- a/guacamole/src/main/frontend/src/translations/en.json
+++ b/guacamole/src/main/frontend/src/translations/en.json
@@ -126,9 +126,10 @@
         "HELP_MOUSE_MODE_RELATIVE" : "Drag to move the mouse pointer and tap to click. The click occurs at the location of the pointer.",
         "HELP_SHARE_LINK"          : "The current connection is being shared, and can be accessed by anyone with the following {LINKS, plural, one{link} other{links}}:",
 
-        "INFO_CONNECTION_SHARED" : "This connection is now shared.",
-        "INFO_NO_FILE_TRANSFERS" : "No file transfers.",
-        "INFO_USER_COUNT"        : "{USERNAME}{COUNT, plural, one{} other{ (#)}}",
+        "INFO_ANONYMOUS_USER_COUNT" : "Anonymous{COUNT, plural, one{} other{ (#)}}",
+        "INFO_CONNECTION_SHARED"    : "This connection is now shared.",
+        "INFO_NO_FILE_TRANSFERS"    : "No file transfers.",
+        "INFO_USER_COUNT"           : "{USERNAME}{COUNT, plural, one{} other{ (#)}}",
 
         "NAME_INPUT_METHOD_NONE"   : "None",
         "NAME_INPUT_METHOD_OSK"    : "On-screen keyboard",
@@ -149,6 +150,8 @@
         
         "SECTION_HEADER_MOUSE_MODE"     : "Mouse emulation mode",
 
+        "TEXT_ANONYMOUS_USER_JOINED"      : "An anonymous user has joined the connection.",
+        "TEXT_ANONYMOUS_USER_LEFT"        : "An anonymous user has left the connection.",
         "TEXT_ZOOM_AUTO_FIT"              : "Automatically fit to browser window",
         "TEXT_CLIENT_STATUS_IDLE"         : "Idle.",
         "TEXT_CLIENT_STATUS_CONNECTING"   : "Connecting to Guacamole...",