diff --git a/ihtml/themes/breezy/management/select-footer.tpl b/ihtml/themes/breezy/management/select-footer.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..b95e1c4f578cfb5c16c55e0ded8d58f47e2ff5cf
--- /dev/null
+++ b/ihtml/themes/breezy/management/select-footer.tpl
@@ -0,0 +1,7 @@
+<p class="plugbottom">
+{if $MULTISELECT}
+  <input type="submit" name="add_finish" value="{msgPool type=addButton}"/>
+  &nbsp;
+{/if}
+  <input type="submit" name="add_cancel" value="{msgPool type=cancelButton}"/>
+</p>
diff --git a/include/management/class_management.inc b/include/management/class_management.inc
index 4c503239ccff31998619eb6082f2dcfacef37cff..8984646a2ca03f6596350f45a9fc57cf02da78b2 100644
--- a/include/management/class_management.inc
+++ b/include/management/class_management.inc
@@ -85,13 +85,10 @@ class management
   {
     global $config, $class_mapping;
 
-    $plInfos = pluglist::pluginInfos(get_class($this));
     if ($objectTypes === FALSE) {
+      $plInfos = pluglist::pluginInfos(get_class($this));
       $objectTypes  = $plInfos['plManages'];
     }
-    $this->headline = $plInfos['plShortName'];
-    $this->title    = $plInfos['plTitle'];
-    $this->icon     = $plInfos['plIcon'];
 
     if (!preg_match('/^geticon/', $this->icon)) {
       $this->icon = get_template_path($this->icon);
@@ -109,6 +106,7 @@ class management
 
     $this->objectTypes = array_values($objectTypes);
 
+    $this->setUpHeadline();
     $this->setUpListing();
     $this->setUpFilter();
 
@@ -143,6 +141,15 @@ class management
     $this->filter   = new managementFilter($this);
   }
 
+  protected function setUpHeadline()
+  {
+    $plInfos = pluglist::pluginInfos(get_class($this));
+
+    $this->headline = $plInfos['plShortName'];
+    $this->title    = $plInfos['plTitle'];
+    $this->icon     = $plInfos['plIcon'];
+  }
+
   protected function configureActions()
   {
     global $config;
@@ -484,7 +491,6 @@ class management
     $smarty->assign('FILTER',       $filterRender);
     $smarty->assign('ACTIONS',      $actionMenu);
     $smarty->assign('SIZELIMIT',    $ui->getSizeLimitHandler()->renderWarning());
-    $smarty->assign('MULTISELECT',  $this->listing->multiSelect);
     $smarty->assign('NAVIGATION',   $this->listing->renderNavigation());
     $smarty->assign('BASE',         $this->listing->renderBase());
     $smarty->assign('HEADLINE',     $this->headline);
@@ -504,6 +510,11 @@ class management
       // Build ul/li list
       $action->fillMenuItems($menuActions);
     }
+
+    if (empty($actions)) {
+      return '';
+    }
+
     $smarty = get_smarty();
     $smarty->assign('actions', $menuActions);
     return $smarty->fetch(get_template_path('management/actionmenu.tpl'));
diff --git a/include/management/class_managementListing.inc b/include/management/class_managementListing.inc
index cd7ce66d185ce6b5b6d5a8ede5fc9b4d5dee1ef2..391dd87912d953c24ff6be6750e56cc6e5af2bb9 100644
--- a/include/management/class_managementListing.inc
+++ b/include/management/class_managementListing.inc
@@ -31,8 +31,6 @@ class managementListing
 {
   public $pid;
 
-  public $multiSelect = TRUE;
-
   protected $entries      = array();
   protected $entriesIndex = array();
   protected $base;
@@ -41,6 +39,7 @@ class managementListing
   protected $sortColumn     = NULL;
 
   protected $baseMode         = TRUE;
+  protected $multiSelect      = TRUE;
   protected $bases            = array();
   protected $header           = array();
   protected $objectTypeCount  = array();
@@ -58,12 +57,13 @@ class managementListing
    *
    * \param string $parent management instance
    */
-  function __construct($parent, $baseMode = TRUE)
+  function __construct($parent, $baseMode = TRUE, $multiSelect = TRUE)
   {
     global $config, $ui;
 
-    $this->parent   = $parent;
-    $this->baseMode = $baseMode;
+    $this->parent       = $parent;
+    $this->baseMode     = $baseMode;
+    $this->multiSelect  = $multiSelect;
 
     // Initialize pid
     $this->pid = preg_replace('/[^0-9]/', '', microtime(TRUE));
@@ -554,6 +554,11 @@ class managementListing
     }
     return NULL;
   }
+
+  function getMultiSelect()
+  {
+    return $this->multiSelect;
+  }
 }
 
 ?>
diff --git a/include/management/class_selectManagement.inc b/include/management/class_selectManagement.inc
new file mode 100644
index 0000000000000000000000000000000000000000..a39cbf52b828709fd8b724f1a18ab0a15dc342be
--- /dev/null
+++ b/include/management/class_selectManagement.inc
@@ -0,0 +1,69 @@
+<?php
+/*
+  This code is part of FusionDirectory (http://www.fusiondirectory.org/)
+  Copyright (C) 2017-2018  FusionDirectory
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+/*!
+ * \brief Management class for selection dialogs
+ */
+class selectManagement extends management
+{
+  protected $skipHeader         = TRUE;
+  protected $skipCpHandler      = TRUE;
+  public static $skipSnapshots  = TRUE;
+
+  protected $multiSelect = TRUE;
+
+  /* Default columns */
+  public static $columns = array(
+    array('ObjectTypeColumn', array()),
+    array('LinkColumn',       array('attributes' => 'nameAttr',    'label' => 'Name')),
+    array('LinkColumn',       array('attributes' => 'description', 'label' => 'Description')),
+  );
+
+  function __construct($objectTypes = FALSE, $multiSelect = TRUE)
+  {
+    parent::__construct($objectTypes);
+    $this->multiSelect = $multiSelect;
+  }
+
+  protected function setUpListing()
+  {
+    $this->listing  = new managementListing($this, TRUE, $this->multiSelect);
+  }
+
+  protected function setUpHeadline()
+  {
+    $this->headline = _('Please select the desired entries');
+  }
+
+  protected function configureActions()
+  {
+    $this->registerAction(new HiddenAction('configure',       'configureDialog'));
+  }
+
+  function renderList()
+  {
+    $list = parent::renderList();
+
+    $smarty = get_smarty();
+    $smarty->assign('MULTISELECT',  $this->multiSelect);
+
+    return $list.$smarty->fetch(get_template_path('management/select-footer.tpl'));
+  }
+}
diff --git a/include/management/columns/class_LinkColumn.inc b/include/management/columns/class_LinkColumn.inc
index 0102eae7b1a9207c9df0c55fd255b11815b5709b..c6847b434f9640ade350c2cb83ebb134f02f3dc1 100644
--- a/include/management/columns/class_LinkColumn.inc
+++ b/include/management/columns/class_LinkColumn.inc
@@ -29,7 +29,15 @@ class LinkColumn extends Column
     if ($value == '') {
       return '&nbsp;';
     } else {
-      return '<a href="?plug='.$_GET['plug'].'&amp;PID='.$entry->getPid().'&amp;act=listing_edit_'.$entry->row.'" title="'.$entry->dn.'">'.htmlentities($value, ENT_COMPAT, 'UTF-8').'</a>';
+      if ($this->parent->parent instanceof selectManagement) {
+        if ($this->parent->getMultiSelect()) {
+          return '<label title="'.$entry->dn.'" for="listing_selected_'.$entry->row.'">'.htmlentities($value, ENT_COMPAT, 'UTF-8').'</label>';
+        } else {
+          return '<a href="?plug='.$_GET['plug'].'&amp;PID='.$entry->getPid().'&amp;act=listing_select_'.$entry->row.'&amp;add_finish=1" title="'.$entry->dn.'">'.htmlentities($value, ENT_COMPAT, 'UTF-8').'</a>';
+        }
+      } else {
+        return '<a href="?plug='.$_GET['plug'].'&amp;PID='.$entry->getPid().'&amp;act=listing_edit_'.$entry->row.'" title="'.$entry->dn.'">'.htmlentities($value, ENT_COMPAT, 'UTF-8').'</a>';
+      }
     }
   }
 }
diff --git a/include/select/objectSelect/class_objectSelect.inc b/include/select/objectSelect/class_objectSelect.inc
index 46942b4cbb0d9023fe82f5088067d4b2084cb46f..90c9b31bf9e1a8e1ae7669e1fce5276ab0d6929c 100644
--- a/include/select/objectSelect/class_objectSelect.inc
+++ b/include/select/objectSelect/class_objectSelect.inc
@@ -23,12 +23,12 @@
  */
 class objectSelect extends userSelect
 {
-  protected $objectTypes = array(
-    'user', 'ogroup',
-    'application',
-    'terminal', 'workstation', 'server', 'printer', 'phone',
-    'simpleSecurityObject'
-  );
-  protected $autoFilterAttributes = array('dn', 'cn', 'uid', 'description', 'mail');
+  //~ protected $objectTypes = array(
+    //~ 'user', 'ogroup',
+    //~ 'application',
+    //~ 'terminal', 'workstation', 'server', 'printer', 'phone',
+    //~ 'simpleSecurityObject'
+  //~ );
+  //~ protected $autoFilterAttributes = array('dn', 'cn', 'uid', 'description', 'mail');
 }
 ?>
diff --git a/include/select/userGroupSelect/class_userGroupSelect.inc b/include/select/userGroupSelect/class_userGroupSelect.inc
deleted file mode 100644
index 51d991f374abc051bb8c385e2e7543f8de81faee..0000000000000000000000000000000000000000
--- a/include/select/userGroupSelect/class_userGroupSelect.inc
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-/*
-  This code is part of FusionDirectory (http://www.fusiondirectory.org/)
-  Copyright (C) 2013-2016  FusionDirectory
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-*/
-
-/*!
- * \brief User and/or POSIX group selection
- */
-class userGroupSelect extends userSelect
-{
-  protected $objectTypes = array('user', 'group');
-  protected $autoFilterAttributes = array('dn', 'cn', 'uid', 'description', 'mail');
-
-  function __construct()
-  {
-    if (class_available('mixedGroup')) {
-      $this->objectTypes = array('user', 'ogroup');
-    }
-    parent::__construct();
-  }
-}
-
-/*!
- * \brief User, user group and/or role selection
- */
-class userGroupRoleSelect extends userGroupSelect
-{
-  protected $objectTypes = array('user', 'group', 'role', 'ogroup');
-}
-?>
diff --git a/include/select/userSelect/class_userSelect.inc b/include/select/userSelect/class_userSelect.inc
index 9235434f842b1e3a9e6f6b797acc3ebda5032d0d..fbcd0f6db54ad70d5698afce5a5b83837f8a556a 100644
--- a/include/select/userSelect/class_userSelect.inc
+++ b/include/select/userSelect/class_userSelect.inc
@@ -21,26 +21,11 @@
 /*!
  * \brief User selection
  */
-class userSelect extends simpleSelectManagement
+class userSelect extends selectManagement
 {
-  protected $objectTypes          = array('user');
-  protected $autoFilterAttributes = array('dn', 'cn', 'uid', 'description', 'mail');
-
-  function parseXML ($file)
+  function __construct($objectTypes = FALSE)
   {
-    $data = parent::parseXML($file);
-    $data['list']['table']['layout'] = '|20px;c||||';
-    $columns = array (
-      array (
-        'label'         => _('Login'),
-        'sortAttribute' => 'uid',
-        'sortType'      => 'string',
-        'value'         => '%{filter:selectLink(pid,row,dn,uid)}',
-        'export'        => 'true',
-      ),
-    );
-    array_splice($data['list']['table']['column'], 2, 0, $columns);
-    return $data;
+    parent::__construct(['user']);
   }
 }
 
diff --git a/include/simpleplugin/class_dialogAttributes.inc b/include/simpleplugin/class_dialogAttributes.inc
index 997f560261c75007975a334e8ee5f5c3877e3a0c..bdd6c8c65b0992f4aa4d01f23350d2a7d88a3e81 100644
--- a/include/simpleplugin/class_dialogAttributes.inc
+++ b/include/simpleplugin/class_dialogAttributes.inc
@@ -78,24 +78,21 @@ class GenericSelectDialog extends GenericDialog
   {
     $result = $this->dialog->detectPostActions();
     if (isset($result['targets'])) {
-      $headpage = $this->dialog->getHeadpage();
+      if ($this->dialog instanceof selectManagement) {
+        $headpage = $this->dialog->listing;
+      } else {
+        $headpage = $this->dialog->getHeadpage();
+      }
       foreach ($result['targets'] as $dn) {
-        $attrs = $headpage->getEntry($dn);
+        $entry = $headpage->getEntry($dn);
 
-        $this->attribute->addValue($dn, $attrs);
+        $this->attribute->addValue($dn, $entry);
       }
     }
     return FALSE;
   }
 }
 
-/*! \brief User selection dialog
- */
-class UserSelectDialog extends GenericSelectDialog
-{
-  protected $dialogClass = 'userSelect';
-}
-
 /*! \brief User selection dialog allowing only one user to get selected
  */
 class SingleUserSelectDialog extends GenericDialog
@@ -113,10 +110,9 @@ class SingleUserSelectDialog extends GenericDialog
   {
     $result = $this->dialog->detectPostActions();
     if (isset($result['targets']) && count($result['targets'])) {
-      $headpage = $this->dialog->getHeadpage();
-      $dn       = $result['targets'][0];
-      $attrs    = $headpage->getEntry($dn);
-      $this->attribute->handleDialogResult($dn, $attrs);
+      $dn     = $result['targets'][0];
+      $entry  = $this->dialog->listing->getEntry($dn);
+      $this->attribute->handleDialogResult($dn, $entry);
     }
     return FALSE;
   }
@@ -129,20 +125,6 @@ class SystemSelectDialog extends GenericSelectDialog
   protected $dialogClass = 'systemSelect';
 }
 
-/*! \brief User group selection dialog
- */
-class UserGroupSelectDialog extends GenericSelectDialog
-{
-  protected $dialogClass = 'userGroupSelect';
-}
-
-/*! \brief User group or/and role selection dialog
- */
-class UserGroupRoleSelectDialog extends GenericSelectDialog
-{
-  protected $dialogClass = 'userGroupRoleSelect';
-}
-
 /*! \brief Group selection dialog
  */
 class GroupSelectDialog extends GenericSelectDialog
@@ -394,7 +376,13 @@ class GenericDialogAttribute extends DialogAttribute
       ) {
       $value = $dn;
     } else {
-      $value = $attrs[$this->store_attr][0];
+      if (is_array($attrs)) {
+        // simpleSelectManagement
+        $value = $attrs[$this->store_attr][0];
+      } else {
+        // selectManagement
+        $value = $attrs[$this->store_attr];
+      }
     }
     if (!in_array($value, $this->value)) {
       end($this->value);
@@ -460,7 +448,13 @@ class GenericDialogAttribute extends DialogAttribute
       if ($this->display_attr == 'dn') {
         $this->displays[$i] = $attrs['dn'];
       } else {
-        $this->displays[$i] = $attrs[$this->display_attr][0];
+        if (is_array($attrs)) {
+          // simpleSelectManagement or LDAP data
+          $this->displays[$i] = $attrs[$this->display_attr][0];
+        } else {
+          // selectManagement
+          $this->displays[$i] = $attrs[$this->display_attr];
+        }
       }
     }
   }
@@ -496,15 +490,50 @@ class GenericDialogAttribute extends DialogAttribute
   }
 }
 
-/*! \brief This class allows to handle an attribute for selecting user
+/*! \brief Generic dialog for selection using a selectManagement class
+ */
+class GenericSelectManagementDialog extends GenericSelectDialog
+{
+  protected $dialogClass = 'selectManagement';
+
+  function __construct($simplePlugin, $attribute)
+  {
+    $this->attribute  = $attribute;
+    $this->dialog     = new $this->dialogClass(...$this->attribute->selectManagementParameters);
+  }
+}
+
+/*! \brief This class allows to handle an attribute for selecting objects
+ *
+ * It looks like a SetAttribute, but clicking "Add" will open a dialog that allow to select one or more objects.
+ * It stores their dn as values, but displays the cn.
+ *
+ */
+class ObjectsDialogAttribute extends GenericDialogAttribute
+{
+  protected $dialogClass  = 'GenericSelectManagementDialog';
+
+  public $selectManagementParameters;
+
+  function __construct ($label, $description, $ldapName, $required, array $objectTypes, $defaultValue = array(), $store_attr = 'dn', $display_attr = 'cn', $acl = '')
+  {
+    parent::__construct($label, $description, $ldapName, $required, $defaultValue, $store_attr, $display_attr, $acl);
+    $this->selectManagementParameters = array($objectTypes, TRUE);
+  }
+}
+
+/*! \brief This class allows to handle an attribute for selecting users
  *
  * It looks like a SetAttribute, but clicking "Add" will open a dialog that allow to select one or more users.
  * It stores their dn as values, but displays the cn.
  *
  */
-class UsersAttribute extends GenericDialogAttribute
+class UsersAttribute extends ObjectsDialogAttribute
 {
-  protected $dialogClass  = 'UserSelectDialog';
+  function __construct ($label, $description, $ldapName, $required = FALSE, $defaultValue = array(), $store_attr = 'dn', $display_attr = 'cn', $acl = '')
+  {
+    parent::__construct($label, $description, $ldapName, $required, array('user'), $defaultValue, $store_attr, $display_attr, $acl);
+  }
 }
 
 /*! \brief This class allows to handle an attribute for selecting user or groups
@@ -512,9 +541,12 @@ class UsersAttribute extends GenericDialogAttribute
  * It looks like a SetAttribute, but clicking "Add" will open a dialog that allow to select one or more users or groups.
  * It stores their dn as values, but displays the cn.
  */
-class UsersGroupsAttribute extends GenericDialogAttribute
+class UsersGroupsRolesAttribute extends ObjectsDialogAttribute
 {
-  protected $dialogClass = 'UserGroupSelectDialog';
+  function __construct ($label, $description, $ldapName, $required = FALSE, $defaultValue = array(), $store_attr = 'dn', $display_attr = 'cn', $acl = '')
+  {
+    parent::__construct($label, $description, $ldapName, $required, array('user', 'group', 'role', 'ogroup'), $defaultValue, $store_attr, $display_attr, $acl);
+  }
 
   protected function ldapAttributesToGet ()
   {
@@ -526,31 +558,38 @@ class UsersGroupsAttribute extends GenericDialogAttribute
     if (!isset($attrs[$this->display_attr])) {
       unset($this->value[$i]);
     } else {
+      if (is_array($attrs['cn'])) {
+        $cn = $attrs['cn'][0];
+      } else {
+        $cn = $attrs['cn'];
+      }
       if ($this->display_attr == 'dn') {
         $this->displays[$i] = $attrs['dn'];
       } elseif (in_array('posixGroup', $attrs['objectClass'])) {
-        $this->displays[$i] = sprintf(_('POSIX group %s'), trim($attrs['cn'][0]));
+        $this->displays[$i] = sprintf(_('POSIX group %s'), trim($cn));
       } elseif (in_array('organizationalRole', $attrs['objectClass'])) {
-        $this->displays[$i] = sprintf(_('Role %s'), trim($attrs['cn'][0]));
+        $this->displays[$i] = sprintf(_('Role %s'), trim($cn));
       } elseif (in_array('groupOfNames', $attrs['objectClass'])) {
-        $this->displays[$i] = sprintf(_('Group %s'), trim($attrs['cn'][0]));
-      } elseif (isset($attrs['uid'][0])) {
-        $this->displays[$i] = trim($attrs['uid'][0]);
+        $this->displays[$i] = sprintf(_('Group %s'), trim($cn));
+      } elseif (isset($attrs['uid'])) {
+        if (is_array($attrs['uid'])) {
+          $uid = $attrs['uid'][0];
+        } else {
+          $uid = $attrs['uid'];
+        }
+        $this->displays[$i] = trim($uid);
       } else {
-        $this->displays[$i] = $attrs[$this->display_attr][0];
+        if (is_array($attrs[$this->display_attr])) {
+          $display = $attrs[$this->display_attr][0];
+        } else {
+          $display = $attrs[$this->display_attr];
+        }
+        $this->displays[$i] = $display;
       }
     }
   }
 }
 
-/*!
- * \brief This class allows to handle an attribute for selecting users, groups or roles
- */
-class UsersGroupsRolesAttribute extends UsersGroupsAttribute
-{
-  protected $dialogClass = 'UserGroupRoleSelectDialog';
-}
-
 /*! \brief This class allows to handle an attribute for selecting groups
  *
  * It looks like a SetAttribute, but clicking "Add" will open a dialog that allow to select one or more groups.
@@ -752,10 +791,10 @@ class UserAttribute extends DialogButtonAttribute
     $this->setRequired($required);
   }
 
-  function handleDialogResult ($dn, array $attrs)
+  function handleDialogResult ($dn, ListingEntry $entry)
   {
     $this->setValue($dn);
-    $this->buttonText = $attrs['cn'][0];
+    $this->buttonText = $entry['cn'];
   }
 
   function renderFormInput ()