diff --git a/circle/dashboard/autocomplete_light_registry.py b/circle/dashboard/autocomplete_light_registry.py
index 96ce13d..8ff9d94 100644
--- a/circle/dashboard/autocomplete_light_registry.py
+++ b/circle/dashboard/autocomplete_light_registry.py
@@ -1,33 +1,88 @@
 import autocomplete_light
+from django.contrib.auth.models import User
+from django.utils.html import escape
 from django.utils.translation import ugettext as _
 
 from .views import AclUpdateView
+from .models import Profile
 
 
-class AclUserAutocomplete(autocomplete_light.AutocompleteGenericBase):
+def highlight(field, q, none_wo_match=True):
+    """
+    >>> highlight('<b>Akkount Krokodil', 'kro', False)
+    u'&lt;b&gt;Akkount <span class="autocomplete-hl">Kro</span>kodil'
+    """
+
+    if not field:
+        return None
+    try:
+        match = field.lower().index(q.lower())
+    except ValueError:
+        match = None
+    if q and match is not None:
+        match_end = match + len(q)
+        return (escape(field[:match])
+                + '<span class="autocomplete-hl">'
+                + escape(field[match:match_end])
+                + '</span>' + escape(field[match_end:]))
+    elif none_wo_match:
+        return None
+    else:
+        return escape(field)
+
+
+class AclUserGroupAutocomplete(autocomplete_light.AutocompleteGenericBase):
     search_fields = (
-        ('^first_name', 'last_name', 'username', '^email', 'profile__org_id'),
-        ('^name', 'groupprofile__org_id'),
+        ('first_name', 'last_name', 'username', 'email', 'profile__org_id'),
+        ('name', 'groupprofile__org_id'),
     )
-    autocomplete_js_attributes = {'placeholder': _("Name of group or user")}
-    choice_html_format = u'<span data-value="%s"><span>%s</span> %s</span>'
+    choice_html_format = (u'<span data-value="%s"><span style="display:none"'
+                          u'>%s</span>%s</span>')
 
-    def choice_html(self, choice):
-        try:
-            name = choice.get_full_name()
-        except AttributeError:
-            name = _('group')
-        if name:
-            name = u'(%s)' % name
+    def choice_displayed_text(self, choice):
+        q = unicode(self.request.GET.get('q', ''))
+        name = highlight(unicode(choice), q, False)
+        if isinstance(choice, User):
+            extra_fields = [highlight(choice.get_full_name(), q, False),
+                            highlight(choice.email, q)]
+            try:
+                extra_fields.append(highlight(choice.profile.org_id, q))
+            except Profile.DoesNotExist:
+                pass
+            return '%s (%s)' % (name, ', '.join(f for f in extra_fields
+                                                if f))
+        else:
+            return _('%s (group)') % name
 
+    def choice_html(self, choice):
         return self.choice_html_format % (
-            self.choice_value(choice), self.choice_label(choice), name)
+            self.choice_value(choice), self.choice_label(choice),
+            self.choice_displayed_text(choice))
 
     def choices_for_request(self):
         user = self.request.user
         self.choices = (AclUpdateView.get_allowed_users(user),
                         AclUpdateView.get_allowed_groups(user))
-        return super(AclUserAutocomplete, self).choices_for_request()
+        return super(AclUserGroupAutocomplete, self).choices_for_request()
+
+    def autocomplete_html(self):
+        html = []
+
+        for choice in self.choices_for_request():
+            html.append(self.choice_html(choice))
+
+        if not html:
+            html = self.empty_html_format % _('no matches found').capitalize()
+
+        return self.autocomplete_html_format % ''.join(html)
+
+
+class AclUserAutocomplete(AclUserGroupAutocomplete):
+    def choices_for_request(self):
+        user = self.request.user
+        self.choices = (AclUpdateView.get_allowed_users(user), )
+        return super(AclUserGroupAutocomplete, self).choices_for_request()
 
 
+autocomplete_light.register(AclUserGroupAutocomplete)
 autocomplete_light.register(AclUserAutocomplete)
diff --git a/circle/dashboard/forms.py b/circle/dashboard/forms.py
index 94fe926..1f623e8 100644
--- a/circle/dashboard/forms.py
+++ b/circle/dashboard/forms.py
@@ -1055,9 +1055,29 @@ class UserCreationForm(OrgUserCreationForm):
         return user
 
 
-class AclUserAddForm(forms.Form):
+class AclUserOrGroupAddForm(forms.Form):
     name = forms.CharField(widget=autocomplete_light.TextWidget(
-        'AclUserAutocomplete', attrs={'class': 'form-control'}))
+        'AclUserGroupAutocomplete',
+        autocomplete_js_attributes={'placeholder': _("Name of group or user")},
+        attrs={'class': 'form-control'}))
+
+
+class TransferOwnershipForm(forms.Form):
+    name = forms.CharField(
+        widget=autocomplete_light.TextWidget(
+            'AclUserAutocomplete',
+            autocomplete_js_attributes={"placeholder": _("Name of user")},
+            attrs={'class': 'form-control'}),
+        label=_("E-mail address or identifier of user"))
+
+
+class AddGroupMemberForm(forms.Form):
+    new_member = forms.CharField(
+        widget=autocomplete_light.TextWidget(
+            'AclUserAutocomplete',
+            autocomplete_js_attributes={"placeholder": _("Name of user")},
+            attrs={'class': 'form-control'}),
+        label=_("E-mail address or identifier of user"))
 
 
 class UserKeyForm(forms.ModelForm):
diff --git a/circle/dashboard/static/dashboard/dashboard.css b/circle/dashboard/static/dashboard/dashboard.css
index 213fa0b..be9f243 100644
--- a/circle/dashboard/static/dashboard/dashboard.css
+++ b/circle/dashboard/static/dashboard/dashboard.css
@@ -591,11 +591,15 @@ footer a, footer a:hover, footer a:visited {
   width: 100px;
 }
 
+#group-detail-user-table tr:last-child td:nth-child(2) {
+  text-align: left;
+}
+
 #group-detail-perm-header {
   margin-top: 25px;
 }
 
-textarea[name="list-new-namelist"] {
+textarea[name="new_members"] {
   max-width: 500px;
   min-height: 80px;
   margin-bottom: 10px;
@@ -960,3 +964,12 @@ textarea[name="list-new-namelist"] {
 #vm-activity-state {
   margin-bottom: 15px;
 }
+
+.autocomplete-hl {
+  color: #b20000;
+  font-weight: bold;
+}
+
+.hilight .autocomplete-hl {
+  color: orange;
+}
diff --git a/circle/dashboard/templates/dashboard/_modal.html b/circle/dashboard/templates/dashboard/_modal.html
index 08e5d91..cc5a5b9 100644
--- a/circle/dashboard/templates/dashboard/_modal.html
+++ b/circle/dashboard/templates/dashboard/_modal.html
@@ -2,6 +2,12 @@
 <div class="modal fade" id="confirmation-modal" tabindex="-1" role="dialog">
   <div class="modal-dialog">
     <div class="modal-content">
+      {% if box_title and ajax_title %}
+      <div class="modal-header">
+        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+        <h4 class="modal-title">{{ box_title }}</h4>
+      </div>
+      {% endif %}
       <div class="modal-body">
         {% if template %}
           {% include template %}
diff --git a/circle/dashboard/templates/dashboard/group-detail.html b/circle/dashboard/templates/dashboard/group-detail.html
index 794691c..f683ad8 100644
--- a/circle/dashboard/templates/dashboard/group-detail.html
+++ b/circle/dashboard/templates/dashboard/group-detail.html
@@ -89,13 +89,12 @@
         <tr>
           <td><i class="fa fa-plus"></i></td>
           <td colspan="2">
-            <input type="text" class="form-control" name="list-new-name"
-            placeholder="{% trans "Name of user" %}">
+            {{addmemberform.new_member}}
           </td>
         </tr>
   </tbody>
   </table>
-  <textarea name="list-new-namelist" class="form-control"
+  <textarea name="new_members" class="form-control"
     placeholder="{% trans "Add multiple users at once (one identifier per line)." %}"></textarea>
   <div class="form-actions">
     <button type="submit" class="btn btn-success">{% trans "Save" %}</button>
diff --git a/circle/dashboard/templates/dashboard/vm-detail/access.html b/circle/dashboard/templates/dashboard/vm-detail/access.html
index 3f35486..b716552 100644
--- a/circle/dashboard/templates/dashboard/vm-detail/access.html
+++ b/circle/dashboard/templates/dashboard/vm-detail/access.html
@@ -9,8 +9,10 @@
   {% endblocktrans %}
   {% endif %}
   {% if user == instance.owner or user.is_superuser %}
+  <span class="operation-wrapper">
   <a href="{% url "dashboard.views.vm-transfer-ownership" instance.pk %}"
-      class="btn btn-link">{% trans "Transfer ownership..." %}</a>
+      class="btn btn-link operation">{% trans "Transfer ownership..." %}</a>
+  </span>
   {% endif %}
 </p>
 <h3>{% trans "Permissions"|capfirst %}</h3>
diff --git a/circle/dashboard/templates/dashboard/vm-detail/tx-owner.html b/circle/dashboard/templates/dashboard/vm-detail/tx-owner.html
index cd3174c..5c0a54c 100644
--- a/circle/dashboard/templates/dashboard/vm-detail/tx-owner.html
+++ b/circle/dashboard/templates/dashboard/vm-detail/tx-owner.html
@@ -1,25 +1,16 @@
-{% extends "dashboard/base.html" %}
 {% load i18n %}
 
-{% block content %}
-  <div class="body-content">
-    <div class="panel panel-default">
-      <div class="panel-heading">
-        <h3 class="no-margin">
-          {% trans "Transfer ownership" %}
-        </h3>
-      </div>
-      <div class="panel-body">
-        <div class="pull-right">
-          <form action="" method="POST">
-            {% csrf_token %}
-            <label>
-              {% trans "E-mail address or identifier of user" %}:
-              <input name="name">
-            </label>
-            <input type="submit">
-          </form>
+<div class="pull-right">
+    <form action="{% url "dashboard.views.vm-transfer-ownership" pk=instance.pk %}" method="POST" style="max-width: 400px;">
+    {% csrf_token %}
+    <label>
+        {{ form.name.label }}
+    </label>
+    <div class="input-group">
+        {{form.name}}
+        <div class="input-group-btn">
+            <input type="submit" value="{% trans "Save" %}" class="btn btn-primary">
         </div>
-      </div>
-  </div>
-{% endblock %}
+    </div>
+    </form>
+</div>
diff --git a/circle/dashboard/tests/test_views.py b/circle/dashboard/tests/test_views.py
index 895853d..e15e546 100644
--- a/circle/dashboard/tests/test_views.py
+++ b/circle/dashboard/tests/test_views.py
@@ -1134,7 +1134,7 @@ class GroupDetailTest(LoginMixin, TestCase):
         c = Client()
         user_in_group = self.g1.user_set.count()
         response = c.post('/dashboard/group/' +
-                          str(self.g1.pk) + '/', {'list-new-name': 'user3'})
+                          str(self.g1.pk) + '/', {'new_member': 'user3'})
         self.assertEqual(user_in_group,
                          self.g1.user_set.count())
         self.assertEqual(response.status_code, 302)
@@ -1144,7 +1144,7 @@ class GroupDetailTest(LoginMixin, TestCase):
         self.login(c, 'user3')
         user_in_group = self.g1.user_set.count()
         response = c.post('/dashboard/group/' +
-                          str(self.g1.pk) + '/', {'list-new-name': 'user3'})
+                          str(self.g1.pk) + '/', {'new_member': 'user3'})
         self.assertEqual(user_in_group, self.g1.user_set.count())
         self.assertEqual(response.status_code, 403)
 
@@ -1153,7 +1153,7 @@ class GroupDetailTest(LoginMixin, TestCase):
         self.login(c, 'superuser')
         user_in_group = self.g1.user_set.count()
         response = c.post('/dashboard/group/' +
-                          str(self.g1.pk) + '/', {'list-new-name': 'user3'})
+                          str(self.g1.pk) + '/', {'new_member': 'user3'})
         self.assertEqual(user_in_group + 1, self.g1.user_set.count())
         self.assertEqual(response.status_code, 302)
 
@@ -1162,7 +1162,7 @@ class GroupDetailTest(LoginMixin, TestCase):
         self.login(c, 'user0')
         user_in_group = self.g1.user_set.count()
         response = c.post('/dashboard/group/' +
-                          str(self.g1.pk) + '/', {'list-new-name': 'user3'})
+                          str(self.g1.pk) + '/', {'new_member': 'user3'})
         self.assertEqual(user_in_group + 1, self.g1.user_set.count())
         self.assertEqual(response.status_code, 302)
 
@@ -1172,7 +1172,7 @@ class GroupDetailTest(LoginMixin, TestCase):
         user_in_group = self.g1.user_set.count()
         response = c.post('/dashboard/group/' +
                           str(self.g1.pk) + '/',
-                          {'list-new-namelist': 'user1\r\nuser2'})
+                          {'new_members': 'user1\r\nuser2'})
         self.assertEqual(user_in_group + 2, self.g1.user_set.count())
         self.assertEqual(response.status_code, 302)
 
@@ -1182,7 +1182,7 @@ class GroupDetailTest(LoginMixin, TestCase):
         user_in_group = self.g1.user_set.count()
         response = c.post('/dashboard/group/' +
                           str(self.g1.pk) + '/',
-                          {'list-new-namelist': 'user1\r\nnoname\r\nuser2'})
+                          {'new_members': 'user1\r\nnoname\r\nuser2'})
         self.assertEqual(user_in_group + 2, self.g1.user_set.count())
         self.assertEqual(response.status_code, 302)
 
@@ -1192,7 +1192,7 @@ class GroupDetailTest(LoginMixin, TestCase):
         user_in_group = self.g1.user_set.count()
         response = c.post('/dashboard/group/' +
                           str(self.g1.pk) + '/',
-                          {'list-new-namelist': 'user1\r\nuser2'})
+                          {'new_members': 'user1\r\nuser2'})
         self.assertEqual(user_in_group, self.g1.user_set.count())
         self.assertEqual(response.status_code, 403)
 
@@ -1201,7 +1201,7 @@ class GroupDetailTest(LoginMixin, TestCase):
         user_in_group = self.g1.user_set.count()
         response = c.post('/dashboard/group/' +
                           str(self.g1.pk) + '/',
-                          {'list-new-namelist': 'user1\r\nuser2'})
+                          {'new_members': 'user1\r\nuser2'})
         self.assertEqual(user_in_group, self.g1.user_set.count())
         self.assertEqual(response.status_code, 302)
 
@@ -1471,8 +1471,8 @@ class TransferOwnershipViewTest(LoginMixin, TestCase):
         c2 = self.u2.notification_set.count()
         c = Client()
         self.login(c, 'user2')
-        response = c.post('/dashboard/vm/1/tx/')
-        assert response.status_code == 400
+        response = c.post('/dashboard/vm/1/tx/', {'name': 'userx'})
+        assert response.status_code == 403
         self.assertEqual(self.u2.notification_set.count(), c2)
 
     def test_owned_offer(self):
diff --git a/circle/dashboard/views.py b/circle/dashboard/views.py
index c1afcf1..c28052c 100644
--- a/circle/dashboard/views.py
+++ b/circle/dashboard/views.py
@@ -70,9 +70,10 @@ from .forms import (
     UserCreationForm, GroupProfileUpdateForm, UnsubscribeForm,
     VmSaveForm, UserKeyForm, VmRenewForm, VmStateChangeForm,
     CirclePasswordChangeForm, VmCreateDiskForm, VmDownloadDiskForm,
-    TraitsForm, RawDataForm, GroupPermissionForm, AclUserAddForm,
+    TraitsForm, RawDataForm, GroupPermissionForm, AclUserOrGroupAddForm,
     VmResourcesForm, VmAddInterfaceForm, VmListSearchForm,
-    TemplateListSearchForm, ConnectCommandForm
+    TemplateListSearchForm, ConnectCommandForm,
+    TransferOwnershipForm, AddGroupMemberForm
 )
 
 from .tables import (
@@ -390,7 +391,7 @@ class VmDetailView(CheckedDetailView):
         ).all()
         context['acl'] = AclUpdateView.get_acl_data(
             instance, self.request.user, 'dashboard.views.vm-acl')
-        context['aclform'] = AclUserAddForm()
+        context['aclform'] = AclUserOrGroupAddForm()
         context['os_type_icon'] = instance.os_type.replace("unknown",
                                                            "question")
         # ipv6 infos
@@ -1282,7 +1283,8 @@ class GroupDetailView(CheckedDetailView):
         context['acl'] = AclUpdateView.get_acl_data(
             self.object.profile, self.request.user,
             'dashboard.views.group-acl')
-        context['aclform'] = AclUserAddForm()
+        context['aclform'] = AclUserOrGroupAddForm()
+        context['addmemberform'] = AddGroupMemberForm()
         context['group_profile_form'] = GroupProfileUpdate.get_form_object(
             self.request, self.object.profile)
 
@@ -1299,17 +1301,15 @@ class GroupDetailView(CheckedDetailView):
 
         if request.POST.get('new_name'):
             return self.__set_name(request)
-        if request.POST.get('list-new-name'):
+        if request.POST.get('new_member'):
             return self.__add_user(request)
-        if request.POST.get('list-new-namelist'):
+        if request.POST.get('new_members'):
             return self.__add_list(request)
-        if (request.POST.get('list-new-name') is not None) and \
-                (request.POST.get('list-new-namelist') is not None):
-            return redirect(reverse_lazy("dashboard.views.group-detail",
-                                         kwargs={'pk': self.get_object().pk}))
+        return redirect(reverse_lazy("dashboard.views.group-detail",
+                                     kwargs={'pk': self.get_object().pk}))
 
     def __add_user(self, request):
-        name = request.POST['list-new-name']
+        name = request.POST['new_member']
         self.__add_username(request, name)
         return redirect(reverse_lazy("dashboard.views.group-detail",
                                      kwargs={'pk': self.object.pk}))
@@ -1328,9 +1328,7 @@ class GroupDetailView(CheckedDetailView):
                 messages.warning(request, _('User "%s" not found.') % name)
 
     def __add_list(self, request):
-        if not self.get_has_level()(request.user, 'operator'):
-            raise PermissionDenied()
-        userlist = request.POST.get('list-new-namelist').split('\r\n')
+        userlist = request.POST.get('new_members').split('\r\n')
         for line in userlist:
             self.__add_username(request, line)
         return redirect(reverse_lazy("dashboard.views.group-detail",
@@ -1717,7 +1715,7 @@ class TemplateDetail(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
             obj, self.request.user, 'dashboard.views.template-acl')
         context['disks'] = obj.disks.all()
         context['is_owner'] = obj.has_level(self.request.user, 'owner')
-        context['aclform'] = AclUserAddForm()
+        context['aclform'] = AclUserOrGroupAddForm()
         return context
 
     def get_success_url(self):
@@ -2768,11 +2766,30 @@ class FavouriteView(TemplateView):
             return HttpResponse("Added.")
 
 
-class TransferOwnershipView(LoginRequiredMixin, DetailView):
+class TransferOwnershipView(CheckedDetailView, DetailView):
     model = Instance
-    template_name = 'dashboard/vm-detail/tx-owner.html'
+
+    def get_template_names(self):
+        if self.request.is_ajax():
+            return ['dashboard/_modal.html']
+        else:
+            return ['dashboard/nojs-wrapper.html']
+
+    def get_context_data(self, *args, **kwargs):
+        context = super(TransferOwnershipView, self).get_context_data(
+            *args, **kwargs)
+        context['form'] = TransferOwnershipForm()
+        context.update({
+            'box_title': _("Transfer ownership"),
+            'ajax_title': True,
+            'template': "dashboard/vm-detail/tx-owner.html",
+        })
+        return context
 
     def post(self, request, *args, **kwargs):
+        form = TransferOwnershipForm(request.POST)
+        if not form.is_valid():
+            return self.get(request)
         try:
             new_owner = search_user(request.POST['name'])
         except User.DoesNotExist:
diff --git a/circle/network/views.py b/circle/network/views.py
index 28f3579..123de84 100644
--- a/circle/network/views.py
+++ b/circle/network/views.py
@@ -42,7 +42,7 @@ from operator import itemgetter
 from itertools import chain
 import json
 from dashboard.views import AclUpdateView
-from dashboard.forms import AclUserAddForm
+from dashboard.forms import AclUserOrGroupAddForm
 
 
 class SuccessMessageMixin(FormMixin):
@@ -660,7 +660,7 @@ class VlanDetail(LoginRequiredMixin, SuperuserRequiredMixin,
         context['vlan_vid'] = self.kwargs.get('vid')
         context['acl'] = AclUpdateView.get_acl_data(
             self.object, self.request.user, 'network.vlan-acl')
-        context['aclform'] = AclUserAddForm()
+        context['aclform'] = AclUserOrGroupAddForm()
         return context
 
     success_url = reverse_lazy('network.vlan_list')