diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/Entity.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/Entity.java
index 18a30f6b..4cbb04e2 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/Entity.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/Entity.java
@@ -12,4 +12,6 @@ public interface Entity extends ModelIdAware {
 
     EntityType entityType();
 
+    String getName();
+
 }
diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/EntityIdAndName.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/EntityKeyAndName.java
similarity index 60%
rename from src/main/java/ch/ethz/seb/sebserver/gbl/model/EntityIdAndName.java
rename to src/main/java/ch/ethz/seb/sebserver/gbl/model/EntityKeyAndName.java
index 61f8b180..bb37b491 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/EntityIdAndName.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/EntityKeyAndName.java
@@ -9,30 +9,53 @@
 package ch.ethz.seb.sebserver.gbl.model;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
 @JsonIgnoreProperties(ignoreUnknown = true)
-public class EntityIdAndName implements ModelIdAware, ModelNameAware {
+public class EntityKeyAndName implements ModelIdAware, ModelNameAware {
 
+    @JsonProperty(value = "entityType", required = true)
+    public final EntityType entityType;
+    @JsonProperty(value = Domain.ATTR_ID, required = true)
     public final String id;
+    @JsonProperty(value = "name", required = true)
     public final String name;
 
     @JsonCreator
-    public EntityIdAndName(
+    public EntityKeyAndName(
+            @JsonProperty(value = "entityType", required = true) final EntityType entityType,
             @JsonProperty(value = Domain.ATTR_ID, required = true) final String id,
             @JsonProperty(value = "name", required = true) final String name) {
 
+        this.entityType = entityType;
         this.id = id;
         this.name = name;
     }
 
+    public EntityKeyAndName(final EntityKey entityKey, final String name) {
+
+        this.entityType = entityKey.entityType;
+        this.id = entityKey.entityId;
+        this.name = name;
+    }
+
+    public EntityType getEntityType() {
+        return this.entityType;
+    }
+
+    public String getId() {
+        return this.id;
+    }
+
     @Override
     public String getName() {
         return this.name;
     }
 
     @Override
+    @JsonIgnore
     public String getModelId() {
         return this.id;
     }
@@ -41,6 +64,7 @@ public class EntityIdAndName implements ModelIdAware, ModelNameAware {
     public int hashCode() {
         final int prime = 31;
         int result = 1;
+        result = prime * result + ((this.entityType == null) ? 0 : this.entityType.hashCode());
         result = prime * result + ((this.id == null) ? 0 : this.id.hashCode());
         result = prime * result + ((this.name == null) ? 0 : this.name.hashCode());
         return result;
@@ -54,7 +78,9 @@ public class EntityIdAndName implements ModelIdAware, ModelNameAware {
             return false;
         if (getClass() != obj.getClass())
             return false;
-        final EntityIdAndName other = (EntityIdAndName) obj;
+        final EntityKeyAndName other = (EntityKeyAndName) obj;
+        if (this.entityType != other.entityType)
+            return false;
         if (this.id == null) {
             if (other.id != null)
                 return false;
@@ -70,7 +96,7 @@ public class EntityIdAndName implements ModelIdAware, ModelNameAware {
 
     @Override
     public String toString() {
-        return "IdAndName [id=" + this.id + ", name=" + this.name + "]";
+        return "EntityIdAndName [entityType=" + this.entityType + ", id=" + this.id + ", name=" + this.name + "]";
     }
 
 }
diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/EntityProcessingReport.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/EntityProcessingReport.java
index 75a9ae85..d26fd8fd 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/EntityProcessingReport.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/EntityProcessingReport.java
@@ -8,13 +8,31 @@
 
 package ch.ethz.seb.sebserver.gbl.model;
 
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
 public class EntityProcessingReport {
 
-    // TODO
+    @JsonProperty(value = "source", required = true)
+    public final Collection<Entity> source;
+    @JsonProperty(value = "dependencies", required = true)
+    public final Collection<EntityKeyAndName> dependencies;
+    @JsonProperty(value = "errors", required = true)
+    public final Map<EntityKeyAndName, String> errors;
 
-    public EntityProcessingReport add(final Entity entity) {
-        // TODO
-        return this;
+    @JsonCreator
+    public EntityProcessingReport(
+            @JsonProperty(value = "source", required = true) final Collection<Entity> source,
+            @JsonProperty(value = "dependencies", required = true) final Collection<EntityKeyAndName> dependencies,
+            @JsonProperty(value = "errors", required = true) final Map<EntityKeyAndName, String> errors) {
+
+        this.source = Collections.unmodifiableCollection(source);
+        this.dependencies = Collections.unmodifiableCollection(dependencies);
+        this.errors = Collections.unmodifiableMap(errors);
     }
 
 }
diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/Institution.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/Institution.java
index ddda1853..9af50b45 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/Institution.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/Institution.java
@@ -17,7 +17,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import ch.ethz.seb.sebserver.gbl.model.Activatable;
 import ch.ethz.seb.sebserver.gbl.model.Domain;
 import ch.ethz.seb.sebserver.gbl.model.Domain.INSTITUTION;
-import ch.ethz.seb.sebserver.gbl.model.EntityIdAndName;
+import ch.ethz.seb.sebserver.gbl.model.EntityKeyAndName;
 import ch.ethz.seb.sebserver.gbl.model.EntityType;
 import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.GrantEntity;
 
@@ -86,6 +86,7 @@ public final class Institution implements GrantEntity, Activatable {
         return null;
     }
 
+    @Override
     public String getName() {
         return this.name;
     }
@@ -109,8 +110,11 @@ public final class Institution implements GrantEntity, Activatable {
                 + ", active=" + this.active + "]";
     }
 
-    public static EntityIdAndName toName(final Institution institution) {
-        return new EntityIdAndName(String.valueOf(institution.id), institution.name);
+    public static EntityKeyAndName toName(final Institution institution) {
+        return new EntityKeyAndName(
+                EntityType.INSTITUTION,
+                String.valueOf(institution.id),
+                institution.name);
     }
 
 }
diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/LmsSetup.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/LmsSetup.java
index 1c20f76b..824b0321 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/LmsSetup.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/LmsSetup.java
@@ -19,11 +19,17 @@ import ch.ethz.seb.sebserver.gbl.model.Activatable;
 import ch.ethz.seb.sebserver.gbl.model.Domain;
 import ch.ethz.seb.sebserver.gbl.model.Domain.INSTITUTION;
 import ch.ethz.seb.sebserver.gbl.model.Domain.LMS_SETUP;
+import ch.ethz.seb.sebserver.gbl.model.EntityKeyAndName;
 import ch.ethz.seb.sebserver.gbl.model.EntityType;
 import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.GrantEntity;
 
 public final class LmsSetup implements GrantEntity, Activatable {
 
+    public static final String FILTER_ATTR_INSTITUTION = "institution";
+    public static final String FILTER_ATTR_NAME = "name";
+    public static final String FILTER_ATTR_LMS_TYPE = "lms_type";
+    public static final String FILTER_ATTR_ACTIVE = "active";
+
     public enum LMSType {
         MOCKUP,
         MOODLE,
@@ -133,6 +139,7 @@ public final class LmsSetup implements GrantEntity, Activatable {
         return this.institutionId;
     }
 
+    @Override
     public String getName() {
         return this.name;
     }
@@ -179,4 +186,11 @@ public final class LmsSetup implements GrantEntity, Activatable {
                 + this.sebAuthSecret + ", active=" + this.active + "]";
     }
 
+    public static EntityKeyAndName toName(final LmsSetup lmsSetup) {
+        return new EntityKeyAndName(
+                EntityType.LMS_SETUP,
+                String.valueOf(lmsSetup.id),
+                lmsSetup.name);
+    }
+
 }
diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserActivityLog.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserActivityLog.java
index b08caca3..ed5c7fa9 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserActivityLog.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserActivityLog.java
@@ -84,6 +84,12 @@ public class UserActivityLog implements Entity {
                 : null;
     }
 
+    @Override
+    @JsonIgnore
+    public String getName() {
+        return getModelId();
+    }
+
     public String getUserUuid() {
         return this.userUUID;
     }
diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserFilter.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserFilter.java
index 6efd6c43..191672f4 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserFilter.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserFilter.java
@@ -15,7 +15,7 @@ public final class UserFilter {
     public static final String FILTER_ATTR_USER_NAME = "username";
     public static final String FILTER_ATTR_EMAIL = "email";
     public static final String FILTER_ATTR_LOCALE = "locale";
-    public static final String FILTER_ATTR_INSTITUTION = "institutionId";
+    public static final String FILTER_ATTR_INSTITUTION = "institution";
 
     public final Boolean active;
     public final Long institutionId;
diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserInfo.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserInfo.java
index 85a9e278..aa0edceb 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserInfo.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserInfo.java
@@ -122,6 +122,7 @@ public final class UserInfo implements GrantEntity, Activatable, Serializable {
         return this.uuid;
     }
 
+    @Override
     public String getName() {
         return this.name;
     }
diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserMod.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserMod.java
index c6cfb017..5b809a68 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserMod.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserMod.java
@@ -149,6 +149,7 @@ public final class UserMod implements GrantEntity {
         return this.newPassword;
     }
 
+    @Override
     public String getName() {
         return this.name;
     }
diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserRole.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserRole.java
index 3f604713..355cd9fd 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserRole.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserRole.java
@@ -27,4 +27,9 @@ public enum UserRole implements Entity {
     public String getModelId() {
         return name();
     }
+
+    @Override
+    public String getName() {
+        return name();
+    }
 }
diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/AuthorizationGrantService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/AuthorizationGrantService.java
index f217fa0e..65c10072 100644
--- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/AuthorizationGrantService.java
+++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/AuthorizationGrantService.java
@@ -21,6 +21,11 @@ import ch.ethz.seb.sebserver.gbl.util.Result;
  * has write, modify or even read-only rights on an entity instance or on an entity type. */
 public interface AuthorizationGrantService {
 
+    /** Gets the UserService that is bundled within the AuthorizationGrantService
+     * 
+     * @return the UserService that is bundled within the AuthorizationGrantService */
+    UserService getUserService();
+
     /** Checks if the current user has any privilege (base or institutional or owner) for the given EntityType and
      * PrivilegeType.
      *
diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/AuthorizationGrantServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/AuthorizationGrantServiceImpl.java
index f9299011..499a91d5 100644
--- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/AuthorizationGrantServiceImpl.java
+++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/AuthorizationGrantServiceImpl.java
@@ -51,6 +51,11 @@ public class AuthorizationGrantServiceImpl implements AuthorizationGrantService
         }
     }
 
+    @Override
+    public UserService getUserService() {
+        return this.userService;
+    }
+
     /** Initialize the (hard-coded) grants */
     @PostConstruct
     public void init() {
diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionService.java
index 053c62a4..5aad6299 100644
--- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionService.java
+++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionService.java
@@ -8,13 +8,18 @@
 
 package ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction;
 
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.springframework.stereotype.Service;
 
 import ch.ethz.seb.sebserver.gbl.model.EntityKey;
 import ch.ethz.seb.sebserver.gbl.model.EntityProcessingReport;
+import ch.ethz.seb.sebserver.gbl.model.EntityType;
 import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
 import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
 
@@ -22,20 +27,23 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
 @WebServiceProfile
 public class BulkActionService {
 
-    private final Collection<BulkActionSupport> supporter;
+    private final Map<EntityType, BulkActionSupport> supporter;
     private final UserActivityLogDAO userActivityLogDAO;
 
     public BulkActionService(
             final Collection<BulkActionSupport> supporter,
             final UserActivityLogDAO userActivityLogDAO) {
 
-        this.supporter = supporter;
+        this.supporter = new HashMap<>();
+        for (final BulkActionSupport support : supporter) {
+            this.supporter.put(support.entityType(), support);
+        }
         this.userActivityLogDAO = userActivityLogDAO;
     }
 
     public void collectDependencies(final BulkAction action) {
         checkProcessing(action);
-        for (final BulkActionSupport sup : this.supporter) {
+        for (final BulkActionSupport sup : this.supporter.values()) {
             action.dependencies.addAll(sup.getDependencies(action));
         }
         action.alreadyProcessed = true;
@@ -44,7 +52,7 @@ public class BulkActionService {
     public void doBulkAction(final BulkAction action) {
         checkProcessing(action);
 
-        final BulkActionSupport supportForSource = getSupporterForSource(action);
+        final BulkActionSupport supportForSource = this.supporter.get(action.sourceType);
         if (supportForSource == null) {
             action.alreadyProcessed = true;
             return;
@@ -54,10 +62,10 @@ public class BulkActionService {
 
         if (!action.dependencies.isEmpty()) {
             // process dependencies first...
-            final List<BulkActionSupport> dependantSupporterInHierarchicalOrder =
-                    getDependantSupporterInHierarchicalOrder(action);
+            final List<BulkActionSupport> dependancySupporter =
+                    getDependancySupporter(action);
 
-            for (final BulkActionSupport support : dependantSupporterInHierarchicalOrder) {
+            for (final BulkActionSupport support : dependancySupporter) {
                 action.result.addAll(support.processBulkAction(action));
             }
         }
@@ -73,14 +81,19 @@ public class BulkActionService {
             doBulkAction(action);
         }
 
-        final EntityProcessingReport report = new EntityProcessingReport();
-
         // TODO
 
-        return report;
+        return new EntityProcessingReport(
+                Collections.emptyList(),
+                Collections.emptyList(),
+                Collections.emptyMap());
     }
 
     private void processUserActivityLog(final BulkAction action) {
+        if (action.type.activityType == null) {
+            return;
+        }
+
         for (final EntityKey key : action.dependencies) {
             this.userActivityLogDAO.log(
                     action.type.activityType,
@@ -98,21 +111,50 @@ public class BulkActionService {
         }
     }
 
-    private BulkActionSupport getSupporterForSource(final BulkAction action) {
-        for (final BulkActionSupport support : this.supporter) {
-            if (support.entityType() == action.sourceType) {
-                return support;
+    private List<BulkActionSupport> getDependancySupporter(final BulkAction action) {
+        switch (action.type) {
+            case ACTIVATE:
+            case DEACTIVATE:
+            case HARD_DELETE: {
+                final List<BulkActionSupport> dependantSupporterInHierarchicalOrder =
+                        getDependantSupporterInHierarchicalOrder(action);
+                Collections.reverse(dependantSupporterInHierarchicalOrder);
+                return dependantSupporterInHierarchicalOrder;
             }
+            default:
+                return getDependantSupporterInHierarchicalOrder(action);
         }
-
-        return null;
     }
 
     private List<BulkActionSupport> getDependantSupporterInHierarchicalOrder(final BulkAction action) {
-
-        // TODO
-
-        return null;
+        switch (action.sourceType) {
+            case INSTITUTION:
+                return Arrays.asList(
+                        this.supporter.get(EntityType.LMS_SETUP),
+                        this.supporter.get(EntityType.USER),
+                        this.supporter.get(EntityType.EXAM),
+                        this.supporter.get(EntityType.CLIENT_CONNECTION),
+                        this.supporter.get(EntityType.CONFIGURATION_NODE));
+            case LMS_SETUP:
+                return Arrays.asList(
+                        this.supporter.get(EntityType.EXAM),
+                        this.supporter.get(EntityType.CLIENT_CONNECTION));
+            case USER:
+                return Arrays.asList(
+                        this.supporter.get(EntityType.EXAM),
+                        this.supporter.get(EntityType.CLIENT_CONNECTION),
+                        this.supporter.get(EntityType.CONFIGURATION_NODE));
+            case EXAM:
+                return Arrays.asList(
+                        this.supporter.get(EntityType.EXAM),
+                        this.supporter.get(EntityType.CLIENT_CONNECTION));
+            case CONFIGURATION:
+                return Arrays.asList(
+                        this.supporter.get(EntityType.EXAM),
+                        this.supporter.get(EntityType.CLIENT_CONNECTION));
+            default:
+                return Collections.emptyList();
+        }
     }
 
     private void checkProcessing(final BulkAction action) {
diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionSupport.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionSupport.java
index 449feb81..d3bd7a05 100644
--- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionSupport.java
+++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionSupport.java
@@ -10,8 +10,13 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction;
 
 import java.util.Collection;
 import java.util.Set;
+import java.util.stream.Collectors;
 
+import org.springframework.transaction.annotation.Transactional;
+
+import ch.ethz.seb.sebserver.gbl.model.Entity;
 import ch.ethz.seb.sebserver.gbl.model.EntityKey;
+import ch.ethz.seb.sebserver.gbl.model.EntityKeyAndName;
 import ch.ethz.seb.sebserver.gbl.model.EntityType;
 import ch.ethz.seb.sebserver.gbl.util.Result;
 
@@ -24,6 +29,22 @@ public interface BulkActionSupport {
 
     Set<EntityKey> getDependencies(BulkAction bulkAction);
 
+    Result<Collection<Entity>> bulkLoadEntities(Collection<EntityKey> keys);
+
+    @Transactional(readOnly = true)
+    default Result<Collection<EntityKeyAndName>> bulkLoadEntityNames(final Collection<EntityKey> keys) {
+        return Result.tryCatch(() -> {
+            return bulkLoadEntities(keys)
+                    .getOrThrow()
+                    .stream()
+                    .map(entity -> new EntityKeyAndName(
+                            EntityType.INSTITUTION,
+                            entity.getModelId(),
+                            entity.getName()))
+                    .collect(Collectors.toList());
+        });
+    }
+
     Collection<Result<EntityKey>> processBulkAction(BulkAction bulkAction);
 
 }
diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/InstitutionDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/InstitutionDAOImpl.java
index 8913417b..d0b1ec9e 100644
--- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/InstitutionDAOImpl.java
+++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/InstitutionDAOImpl.java
@@ -27,6 +27,7 @@ import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
+import ch.ethz.seb.sebserver.gbl.model.Entity;
 import ch.ethz.seb.sebserver.gbl.model.EntityKey;
 import ch.ethz.seb.sebserver.gbl.model.EntityType;
 import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
@@ -150,7 +151,6 @@ public class InstitutionDAOImpl implements InstitutionDAO, BulkActionSupport {
     @Transactional
     public Collection<Result<EntityKey>> delete(final Set<EntityKey> all) {
         final Collection<Result<EntityKey>> result = new ArrayList<>();
-
         final List<Long> ids = extractIdsFromKeys(all, result);
 
         try {
@@ -177,6 +177,24 @@ public class InstitutionDAOImpl implements InstitutionDAO, BulkActionSupport {
         return Collections.emptySet();
     }
 
+    @Override
+    @Transactional(readOnly = true)
+    public Result<Collection<Entity>> bulkLoadEntities(final Collection<EntityKey> keys) {
+        return Result.tryCatch(() -> {
+            final Collection<Result<EntityKey>> result = new ArrayList<>();
+            final List<Long> ids = extractIdsFromKeys(keys, result);
+
+            return this.institutionRecordMapper.selectByExample()
+                    .where(InstitutionRecordDynamicSqlSupport.id, isIn(ids))
+                    .build()
+                    .execute()
+                    .stream()
+                    .map(InstitutionDAOImpl::toDomainModel)
+                    .map(res -> res.getOrThrow())
+                    .collect(Collectors.toList());
+        });
+    }
+
     @Override
     @Transactional
     public Collection<Result<EntityKey>> processBulkAction(final BulkAction bulkAction) {
diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/LmsSetupDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/LmsSetupDAOImpl.java
index 0602ec3c..a708c138 100644
--- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/LmsSetupDAOImpl.java
+++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/LmsSetupDAOImpl.java
@@ -29,11 +29,13 @@ import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
+import ch.ethz.seb.sebserver.gbl.model.Entity;
 import ch.ethz.seb.sebserver.gbl.model.EntityKey;
 import ch.ethz.seb.sebserver.gbl.model.EntityType;
 import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
 import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LMSType;
 import ch.ethz.seb.sebserver.gbl.util.Result;
+import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.InstitutionRecordDynamicSqlSupport;
 import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.LmsSetupRecordDynamicSqlSupport;
 import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.LmsSetupRecordMapper;
 import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.LmsSetupRecord;
@@ -210,6 +212,24 @@ public class LmsSetupDAOImpl implements LmsSetupDAO, BulkActionSupport {
         return Collections.emptySet();
     }
 
+    @Override
+    @Transactional(readOnly = true)
+    public Result<Collection<Entity>> bulkLoadEntities(final Collection<EntityKey> keys) {
+        return Result.tryCatch(() -> {
+            final Collection<Result<EntityKey>> result = new ArrayList<>();
+            final List<Long> ids = extractIdsFromKeys(keys, result);
+
+            return this.lmsSetupRecordMapper.selectByExample()
+                    .where(InstitutionRecordDynamicSqlSupport.id, isIn(ids))
+                    .build()
+                    .execute()
+                    .stream()
+                    .map(LmsSetupDAOImpl::toDomainModel)
+                    .map(res -> res.getOrThrow())
+                    .collect(Collectors.toList());
+        });
+    }
+
     @Override
     @Transactional
     public Collection<Result<EntityKey>> processBulkAction(final BulkAction bulkAction) {
diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserDaoImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserDaoImpl.java
index 4d4047d7..63241f26 100644
--- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserDaoImpl.java
+++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserDaoImpl.java
@@ -39,12 +39,14 @@ import org.springframework.transaction.annotation.Transactional;
 import ch.ethz.seb.sebserver.WebSecurityConfig;
 import ch.ethz.seb.sebserver.gbl.model.APIMessage.APIMessageException;
 import ch.ethz.seb.sebserver.gbl.model.APIMessage.ErrorMessage;
+import ch.ethz.seb.sebserver.gbl.model.Entity;
 import ch.ethz.seb.sebserver.gbl.model.EntityKey;
 import ch.ethz.seb.sebserver.gbl.model.EntityType;
 import ch.ethz.seb.sebserver.gbl.model.user.UserFilter;
 import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
 import ch.ethz.seb.sebserver.gbl.model.user.UserMod;
 import ch.ethz.seb.sebserver.gbl.util.Result;
+import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.InstitutionRecordDynamicSqlSupport;
 import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.RoleRecordDynamicSqlSupport;
 import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.RoleRecordMapper;
 import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.UserRecordDynamicSqlSupport;
@@ -274,6 +276,24 @@ public class UserDaoImpl implements UserDAO, BulkActionSupport {
         return Collections.emptySet();
     }
 
+    @Override
+    @Transactional(readOnly = true)
+    public Result<Collection<Entity>> bulkLoadEntities(final Collection<EntityKey> keys) {
+        return Result.tryCatch(() -> {
+            final Collection<Result<EntityKey>> result = new ArrayList<>();
+            final List<Long> ids = extractIdsFromKeys(keys, result);
+
+            return this.userRecordMapper.selectByExample()
+                    .where(InstitutionRecordDynamicSqlSupport.id, isIn(ids))
+                    .build()
+                    .execute()
+                    .stream()
+                    .map(this::toDomainModel)
+                    .map(res -> res.getOrThrow())
+                    .collect(Collectors.toList());
+        });
+    }
+
     @Override
     @Transactional
     public Collection<Result<EntityKey>> processBulkAction(final BulkAction bulkAction) {
diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/InstitutionController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/InstitutionController.java
index 80a9c183..d349aa7f 100644
--- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/InstitutionController.java
+++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/InstitutionController.java
@@ -21,7 +21,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
-import ch.ethz.seb.sebserver.gbl.model.EntityIdAndName;
+import ch.ethz.seb.sebserver.gbl.model.EntityKeyAndName;
 import ch.ethz.seb.sebserver.gbl.model.EntityKey;
 import ch.ethz.seb.sebserver.gbl.model.EntityProcessingReport;
 import ch.ethz.seb.sebserver.gbl.model.EntityType;
@@ -31,7 +31,6 @@ import ch.ethz.seb.sebserver.gbl.util.Result;
 import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.AuthorizationGrantService;
 import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.PrivilegeType;
 import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.SEBServerUser;
-import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.UserService;
 import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkAction;
 import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkAction.Type;
 import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionService;
@@ -46,19 +45,17 @@ public class InstitutionController {
 
     private final InstitutionDAO institutionDAO;
     private final AuthorizationGrantService authorizationGrantService;
-    private final UserService userService;
     private final UserActivityLogDAO userActivityLogDAO;
     private final BulkActionService bulkActionService;
 
     public InstitutionController(
             final InstitutionDAO institutionDAO,
             final AuthorizationGrantService authorizationGrantService,
-            final UserService userService, final UserActivityLogDAO userActivityLogDAO,
+            final UserActivityLogDAO userActivityLogDAO,
             final BulkActionService bulkActionService) {
 
         this.institutionDAO = institutionDAO;
         this.authorizationGrantService = authorizationGrantService;
-        this.userService = userService;
         this.userActivityLogDAO = userActivityLogDAO;
         this.bulkActionService = bulkActionService;
     }
@@ -68,7 +65,9 @@ public class InstitutionController {
 
         checkBaseReadPrivilege();
 
-        final SEBServerUser currentUser = this.userService.getCurrentUser();
+        final SEBServerUser currentUser = this.authorizationGrantService
+                .getUserService()
+                .getCurrentUser();
         final Long institutionId = currentUser.institutionId();
         return this.institutionDAO.byId(institutionId).getOrThrow();
 
@@ -94,7 +93,7 @@ public class InstitutionController {
         checkBaseReadPrivilege();
 
         if (!this.authorizationGrantService.hasBasePrivilege(
-                EntityType.USER,
+                EntityType.INSTITUTION,
                 PrivilegeType.READ_ONLY)) {
 
             // User has only institutional privilege, can see only the institution he/she belongs to
@@ -105,40 +104,24 @@ public class InstitutionController {
     }
 
     @RequestMapping(path = "/names", method = RequestMethod.GET)
-    public Collection<EntityIdAndName> getNames(
+    public Collection<EntityKeyAndName> getNames(
             @RequestParam(name = Institution.FILTER_ATTR_ACTIVE, required = false) final Boolean active) {
 
-        checkBaseReadPrivilege();
-
-        if (!this.authorizationGrantService.hasBasePrivilege(
-                EntityType.USER,
-                PrivilegeType.READ_ONLY)) {
-
-            // User has only institutional privilege, can see only the institution he/she belongs to
-            return Arrays.asList(getOwn())
-                    .stream()
-                    .map(Institution::toName)
-                    .collect(Collectors.toList());
-
-        } else {
-
-            return this.institutionDAO.all(inst -> true, active)
-                    .getOrThrow()
-                    .stream()
-                    .map(Institution::toName)
-                    .collect(Collectors.toList());
-        }
+        return getAll(active)
+                .stream()
+                .map(Institution::toName)
+                .collect(Collectors.toList());
     }
 
     @RequestMapping(path = "/create", method = RequestMethod.PUT)
     public Institution create(@Valid @RequestBody final Institution institution) {
-        return _saveInstitution(institution, PrivilegeType.WRITE)
+        return save(institution, PrivilegeType.WRITE)
                 .getOrThrow();
     }
 
     @RequestMapping(path = "/save", method = RequestMethod.POST)
     public Institution save(@Valid @RequestBody final Institution institution) {
-        return _saveInstitution(institution, PrivilegeType.MODIFY)
+        return save(institution, PrivilegeType.MODIFY)
                 .getOrThrow();
     }
 
@@ -197,7 +180,7 @@ public class InstitutionController {
                 .getOrThrow();
     }
 
-    private Result<Institution> _saveInstitution(final Institution institution, final PrivilegeType privilegeType) {
+    private Result<Institution> save(final Institution institution, final PrivilegeType privilegeType) {
 
         final ActivityType activityType = (institution.id == null)
                 ? ActivityType.CREATE
diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/LmsSetupController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/LmsSetupController.java
index 451fee2c..c0691edb 100644
--- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/LmsSetupController.java
+++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/LmsSetupController.java
@@ -8,14 +8,199 @@
 
 package ch.ethz.seb.sebserver.webservice.weblayer.api;
 
+import java.util.Collection;
+import java.util.stream.Collectors;
+
+import javax.validation.Valid;
+
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
+import ch.ethz.seb.sebserver.gbl.model.EntityKeyAndName;
+import ch.ethz.seb.sebserver.gbl.model.EntityKey;
+import ch.ethz.seb.sebserver.gbl.model.EntityProcessingReport;
+import ch.ethz.seb.sebserver.gbl.model.EntityType;
+import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
+import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LMSType;
 import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
+import ch.ethz.seb.sebserver.gbl.util.Result;
+import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.AuthorizationGrantService;
+import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.PermissionDeniedException;
+import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.PrivilegeType;
+import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.SEBServerUser;
+import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkAction;
+import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkAction.Type;
+import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionService;
+import ch.ethz.seb.sebserver.webservice.servicelayer.dao.LmsSetupDAO;
+import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
+import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO.ActivityType;
 
 @WebServiceProfile
 @RestController
 @RequestMapping("/${sebserver.webservice.api.admin.endpoint}" + RestAPI.ENDPOINT_LMS_SETUP)
 public class LmsSetupController {
 
+    private final LmsSetupDAO lmsSetupDAO;
+    private final AuthorizationGrantService authorizationGrantService;
+    private final UserActivityLogDAO userActivityLogDAO;
+    private final BulkActionService bulkActionService;
+
+    public LmsSetupController(
+            final LmsSetupDAO lmsSetupDAO,
+            final AuthorizationGrantService authorizationGrantService,
+            final UserActivityLogDAO userActivityLogDAO,
+            final BulkActionService bulkActionService) {
+
+        this.lmsSetupDAO = lmsSetupDAO;
+        this.authorizationGrantService = authorizationGrantService;
+        this.userActivityLogDAO = userActivityLogDAO;
+        this.bulkActionService = bulkActionService;
+    }
+
+    @RequestMapping(method = RequestMethod.GET)
+    public Collection<LmsSetup> getAll(
+            @RequestParam(name = LmsSetup.FILTER_ATTR_INSTITUTION, required = false) final Long institutionId,
+            @RequestParam(name = LmsSetup.FILTER_ATTR_NAME, required = false) final String name,
+            @RequestParam(name = LmsSetup.FILTER_ATTR_LMS_TYPE, required = false) final LMSType lmsType,
+            @RequestParam(name = LmsSetup.FILTER_ATTR_ACTIVE, required = false) final Boolean active) {
+
+        checkBaseReadPrivilege();
+
+        final SEBServerUser currentUser = this.authorizationGrantService
+                .getUserService()
+                .getCurrentUser();
+        final Long usersInstitution = currentUser.institutionId();
+        final Long instId = (institutionId != null) ? institutionId : usersInstitution;
+
+        if (!this.authorizationGrantService.hasBasePrivilege(
+                EntityType.LMS_SETUP,
+                PrivilegeType.READ_ONLY) &&
+                instId != usersInstitution) {
+
+            throw new PermissionDeniedException(
+                    EntityType.LMS_SETUP,
+                    PrivilegeType.READ_ONLY,
+                    currentUser.getUserInfo().uuid);
+        }
+
+        return this.lmsSetupDAO
+                .allMatching(instId, name, lmsType, active)
+                .getOrThrow();
+    }
+
+    @RequestMapping(path = "/names", method = RequestMethod.GET)
+    public Collection<EntityKeyAndName> getNames(
+            @RequestParam(name = LmsSetup.FILTER_ATTR_INSTITUTION, required = false) final Long institutionId,
+            @RequestParam(name = LmsSetup.FILTER_ATTR_NAME, required = false) final String name,
+            @RequestParam(name = LmsSetup.FILTER_ATTR_LMS_TYPE, required = false) final LMSType lmsType,
+            @RequestParam(name = LmsSetup.FILTER_ATTR_ACTIVE, required = false) final Boolean active) {
+
+        return getAll(institutionId, name, lmsType, active)
+                .stream()
+                .map(LmsSetup::toName)
+                .collect(Collectors.toList());
+    }
+
+    @RequestMapping(path = "/{id}", method = RequestMethod.GET)
+    public LmsSetup getById(@PathVariable final Long id) {
+
+        checkBaseReadPrivilege();
+
+        return this.lmsSetupDAO
+                .byId(id)
+                .flatMap(inst -> this.authorizationGrantService.checkGrantOnEntity(
+                        inst,
+                        PrivilegeType.READ_ONLY))
+                .getOrThrow();
+    }
+
+    @RequestMapping(path = "/create", method = RequestMethod.PUT)
+    public LmsSetup create(@Valid @RequestBody final LmsSetup lmsSetup) {
+        return save(lmsSetup, PrivilegeType.WRITE)
+                .getOrThrow();
+    }
+
+    @RequestMapping(path = "/save", method = RequestMethod.POST)
+    public LmsSetup save(@Valid @RequestBody final LmsSetup lmsSetup) {
+        return save(lmsSetup, PrivilegeType.MODIFY)
+                .getOrThrow();
+    }
+
+    @RequestMapping(path = "/{id}/activate", method = RequestMethod.POST)
+    public LmsSetup activate(@PathVariable final Long id) {
+        return setActive(id, true);
+    }
+
+    @RequestMapping(value = "/{id}/deactivate", method = RequestMethod.POST)
+    public LmsSetup deactivate(@PathVariable final Long id) {
+        return setActive(id, false);
+    }
+
+    @RequestMapping(path = "/{id}/delete", method = RequestMethod.DELETE)
+    public EntityProcessingReport deleteUser(@PathVariable final Long id) {
+        checkPrivilegeForInstitution(id, PrivilegeType.WRITE);
+
+        return this.bulkActionService.createReport(new BulkAction(
+                Type.DEACTIVATE,
+                EntityType.LMS_SETUP,
+                new EntityKey(id, EntityType.LMS_SETUP)));
+    }
+
+    @RequestMapping(path = "/{id}/hard-delete", method = RequestMethod.DELETE)
+    public EntityProcessingReport hardDeleteUser(@PathVariable final Long id) {
+        checkPrivilegeForInstitution(id, PrivilegeType.WRITE);
+
+        return this.bulkActionService.createReport(new BulkAction(
+                Type.HARD_DELETE,
+                EntityType.LMS_SETUP,
+                new EntityKey(id, EntityType.LMS_SETUP)));
+    }
+
+    private void checkPrivilegeForInstitution(final Long id, final PrivilegeType type) {
+        this.authorizationGrantService.checkHasAnyPrivilege(
+                EntityType.LMS_SETUP,
+                type);
+
+        this.lmsSetupDAO.byId(id)
+                .flatMap(institution -> this.authorizationGrantService.checkGrantOnEntity(
+                        institution,
+                        type))
+                .getOrThrow();
+    }
+
+    private LmsSetup setActive(final Long id, final boolean active) {
+        checkPrivilegeForInstitution(id, PrivilegeType.MODIFY);
+
+        this.bulkActionService.doBulkAction(new BulkAction(
+                (active) ? Type.ACTIVATE : Type.DEACTIVATE,
+                EntityType.LMS_SETUP,
+                new EntityKey(id, EntityType.LMS_SETUP)));
+
+        return this.lmsSetupDAO
+                .byId(id)
+                .getOrThrow();
+    }
+
+    private Result<LmsSetup> save(final LmsSetup lmsSetup, final PrivilegeType privilegeType) {
+
+        final ActivityType activityType = (lmsSetup.id == null)
+                ? ActivityType.CREATE
+                : ActivityType.MODIFY;
+
+        return this.authorizationGrantService
+                .checkGrantOnEntity(lmsSetup, privilegeType)
+                .flatMap(this.lmsSetupDAO::save)
+                .flatMap(inst -> this.userActivityLogDAO.log(activityType, inst));
+    }
+
+    private void checkBaseReadPrivilege() {
+        this.authorizationGrantService.checkHasAnyPrivilege(
+                EntityType.LMS_SETUP,
+                PrivilegeType.READ_ONLY);
+    }
+
 }
diff --git a/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/AuthorizationGrantServiceTest.java b/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/AuthorizationGrantServiceTest.java
index 447a3f83..b82312c6 100644
--- a/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/AuthorizationGrantServiceTest.java
+++ b/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/AuthorizationGrantServiceTest.java
@@ -100,6 +100,11 @@ public class AuthorizationGrantServiceTest {
                 return "1";
             }
 
+            @Override
+            public String getName() {
+                return getModelId();
+            }
+
         };
     }