public function selectMultipleUsers($fieldName, $users = [])
    {
        $identifier = $this->app->make(Identifier::class)->getString(32);
        $i18n = [
            'username' => t('Username'),
            'emailAddress' => t('Email Address'),
            'chooseUser' => t('Choose User'),
            'noUsers' => t('No users selected.'),
        ];
        $searchLink = $this->app->make(ResolverManagerInterface::class)->resolve(['/ccm/system/dialogs/user/search']);
        $valn = $this->app->make(Numbers::class);
        $userInfoRepository = $this->app->make(UserInfoRepository::class);
        $preselectedUsers = '';
        foreach ($users as $user) {
            if ($valn->integer($user)) {
                $user = $userInfoRepository->getById($user);
            }
            if (is_object($user)) {
                $preselectedUsers .= <<<EOT
<tr data-ccm-user-id="{$user->getUserID()}" class="ccm-list-record">
    <td><input type="hidden" name="{$fieldName}[]" value="{$user->getUserID()}" />{$user->getUserName()}</td>
    <td>{$user->getUserEmail()}</td>
    <td><a href="#" class="ccm-user-list-clear icon-link"><i class="fa fa-minus-circle ccm-user-list-clear-button"></i></a></td>
</tr>
EOT
                ;
            }
        }
        $noUsersStyle = $preselectedUsers === '' ? '' : ' style="display: none"';

        return <<<EOT
<table id="ccmUserSelect-{$identifier}" class="table table-condensed" cellspacing="0" cellpadding="0" border="0">
    <thead>
        <tr>
            <th>{$i18n['username']}</th>
            <th>{$i18n['emailAddress']}</th>
            <th style="width: 1px"><a class="icon-link ccm-user-select-item dialog-launch" dialog-append-buttons="true" dialog-width="90%" dialog-height="70%" dialog-modal="false" dialog-title="{$i18n['chooseUser']}" href="{$searchLink}"><i class="fa fa-plus-circle" /></a></th>
        </tr>
    </thead>
    <tbody>
        {$preselectedUsers}
        <tr class="ccm-user-selected-item-none"{$noUsersStyle}><td colspan="3">{$i18n['noUsers']}</td></tr>
    </tbody>
</table>
<script>
$(function() {
    var container = $('#ccmUserSelect-{$identifier}'),
        noUsersRow = container.find('tr.ccm-user-selected-item-none'),
        updateNoUsers = function() {
            if (container.find('tr[data-ccm-user-id]').length === 0) {
                noUsersRow.show();
            } else {
                noUsersRow.hide();
            }
        },
        userSelectCallback = function(e, data) {
            e.stopPropagation();
            var uID = data.uID,
                uName = data.uName,
                uEmail = data.uEmail;
            if (container.find('tr[data-ccm-user-id=' + uID + ']').length > 0) {
                return;
            }
            noUsersRow.before($('<tr data-ccm-user-id="' + uID + '" class="ccm-list-record" />')
                .append($('<td />')
                    .text(uName)
                    .prepend($('<input type="hidden" name="{$fieldName}[]" />').val(uID))
                )
                .append($('<td />')
                    .text(uEmail)
                )
                .append($('<td><a href="#" class="ccm-user-list-clear icon-link"><i class="fa fa-minus-circle ccm-user-list-clear-button"></i></a></td>'))
            );
            updateNoUsers();
        };
    container.on('click', 'a.ccm-user-list-clear', function(e) {
        e.preventDefault();
        $(this).closest('tr').remove();
        updateNoUsers();
    });
    container.find('.ccm-user-select-item')
        .dialog()
        .on('click', function(e) {
            ConcreteEvent.subscribe('UserSearchDialogSelectUser', userSelectCallback)
        })
    ;
    ConcreteEvent.subscribe('UserSearchDialogAfterSelectUser', function(e) {
        ConcreteEvent.unsubscribe('UserSearchDialogSelectUser');
        jQuery.fn.dialog.closeTop();
    });
});
</script>
EOT
        ;
    }