diff --git a/smp-docker/images/build-docker-images.sh b/smp-docker/images/build-docker-images.sh
index 8d287d78397e50a5e01a14d43d612960d779826f..b718e430dbb42b403ec472b1e9c78d60f177020d 100755
--- a/smp-docker/images/build-docker-images.sh
+++ b/smp-docker/images/build-docker-images.sh
@@ -145,8 +145,6 @@ validateAndPrepareArtefacts() {
       cp "${ORACLE_ARTEFACTS}/${WEBLOGIC_14_FILE}" ./oracle/weblogic-14.1.1.0/
     fi
 
-
-
   if [[ ! -d "./tomcat-mysql-smp-sml/artefacts/" ]]; then
     mkdir -p "./tomcat-mysql-smp-sml/artefacts"
   fi
diff --git a/smp-server-library/pom.xml b/smp-server-library/pom.xml
index 27898b2467151108a6e6aa39bc2890575e96d190..b80feff4ac2b5b4a5edf54fbf282ba4ae5aba0c4 100644
--- a/smp-server-library/pom.xml
+++ b/smp-server-library/pom.xml
@@ -156,7 +156,18 @@
             <artifactId>xmlsec</artifactId>
         </dependency>
 
-        <!-- Tests -->
+        <!-- Test dependencies -->
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-junit</artifactId>
+
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+
         <dependency>
             <groupId>pl.pragmatists</groupId>
             <artifactId>JUnitParams</artifactId>
@@ -187,7 +198,7 @@
             <scope>test</scope>
         </dependency>
 
-        <!-- Test dependencies -->
+
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-jpa</artifactId>
@@ -215,11 +226,6 @@
             <artifactId>h2</artifactId>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-junit</artifactId>
-            <scope>test</scope>
-        </dependency>
     </dependencies>
 
     <build>
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIResourceService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIResourceService.java
index 7e89bcd4137529f5a91cb8e4ba7311bdc3ae3a6a..5f2a03cf70781b053a3e0bfba733a3717ce783f4 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIResourceService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIResourceService.java
@@ -32,6 +32,7 @@ import java.util.Optional;
 import java.util.stream.Collectors;
 
 /**
+ *
  * @author Joze Rihtarsic
  * @since 5.0
  */
@@ -269,8 +270,17 @@ public class UIResourceService {
         return result;
     }
 
+    /**
+     * Add or update a member to a resource
+     *
+     * @param resourceId resource id to add member to
+     * @param groupId   group id to add member to
+     * @param memberRO member data
+     * @param memberId member id (optional) if null then add member, if not null then update member
+     * @return added member RO
+     */
     @Transactional
-    public MemberRO addMemberToResource(Long resourceId, Long groupId, MemberRO memberRO, Long memberId) {
+    public MemberRO addUpdateMemberToResource(Long resourceId, Long groupId, MemberRO memberRO, Long memberId) {
         LOG.info("Add member [{}] to resource [{}]", memberRO.getUsername(), resourceId);
         validateGroupAndResource(resourceId, groupId, "AddMemberToResource");
 
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java
index aab158ef1a5da057c0824b2c17c00cc4f1532ae4..9eff4c771001f60e6cd06bfd1350939288a92a61 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java
@@ -1,7 +1,6 @@
 package eu.europa.ec.edelivery.smp.services.ui;
 
 import eu.europa.ec.edelivery.security.utils.SecurityUtils;
-import eu.europa.ec.edelivery.security.utils.X509CertificateUtils;
 import eu.europa.ec.edelivery.smp.config.SMPEnvironmentProperties;
 import eu.europa.ec.edelivery.smp.data.dao.BaseDao;
 import eu.europa.ec.edelivery.smp.data.dao.CredentialDao;
@@ -32,10 +31,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.io.StringWriter;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
 import java.time.OffsetDateTime;
-import java.util.Base64;
 import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
@@ -43,6 +39,8 @@ import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 /**
+ * Service for user management in UI. It provides methods for user CRUD operations and user credential management.
+ *
  * @author Joze Rihtarsic
  * @since 4.1
  */
@@ -78,11 +76,11 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
     /**
      * Method returns user resource object list for  UI list page.
      *
-     * @param page
-     * @param pageSize
-     * @param sortField
-     * @param sortOrder
-     * @param filter
+     * @param page      - page number
+     * @param pageSize  - page size
+     * @param sortField - sort field
+     * @param sortOrder - sort order
+     * @param filter    - filter object
      * @return ServiceResult with list
      */
     @Transactional
@@ -239,7 +237,7 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
         dbCredential.setLastFailedLoginAttempt(null);
         dbCredential.setSequentialLoginFailureCount(null);
         // if the credentials are not managed by the session , e.g. new  - the persist it
-        if (dbCredential.getId()==null) {
+        if (dbCredential.getId() == null) {
             credentialDao.persist(dbCredential);
         }
         return dbCredential.getUser();
@@ -327,7 +325,7 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
 
         Optional<DBUser> testUser = userDao.findUserByUsername(user.getUsername());
         if (testUser.isPresent()) {
-            throw new SMPRuntimeException(ErrorCode.INVALID_REQUEST, "CreateUser", "User with username ["+user.getUsername()+"] already exists!");
+            throw new SMPRuntimeException(ErrorCode.INVALID_REQUEST, "CreateUser", "User with username [" + user.getUsername() + "] already exists!");
         }
         DBUser dbUser = new DBUser();
         // update user data by admin
@@ -367,7 +365,7 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
     @Transactional(readOnly = true)
     public UserRO getUserById(Long userId) {
         DBUser user = userDao.findUser(userId).orElseThrow(() -> new SMPRuntimeException(ErrorCode.USER_NOT_EXISTS));
-        UserRO result =  convertToRo(user);
+        UserRO result = convertToRo(user);
 
         return result;
 
@@ -386,7 +384,7 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
         return credentialROList;
     }
 
-    public CredentialRO convertAndValidateCertificateCredential(DBCredential credential){
+    public CredentialRO convertAndValidateCertificateCredential(DBCredential credential) {
         CredentialRO credentialRO = conversionService.convert(credential, CredentialRO.class);
         if (credential.getCertificate() != null) {
             DBCertificate dbCert = credential.getCertificate();
@@ -396,7 +394,7 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
                 certificateRO = truststoreService.getCertificateData(dbCert.getPemEncoding(), true, false);
 
             } else {
-                 certificateRO = conversionService.convert(credential.getCertificate(), CertificateRO.class);
+                certificateRO = conversionService.convert(credential.getCertificate(), CertificateRO.class);
             }
             credentialRO.setCertificate(certificateRO);
         }
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/TestUtilsDao.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/TestUtilsDao.java
index 815d69a46c0ee915b47c9aa87e0d37a9bd66316b..363d6fe519313921f12fd4aa0e6c4eca0da1e309 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/TestUtilsDao.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/TestUtilsDao.java
@@ -710,4 +710,14 @@ public class TestUtilsDao {
     public DBDomainMember getDomainMemberU1D2Viewer() {
         return domainMemberU1D2Viewer;
     }
+
+    public DBResourceMember getResourceMemberU1R1_D2G1RD1_Admin() {
+        return resourceMemberU1R1_D2G1RD1_Admin;
+    }
+
+    public DBResourceMember getResourceMemberU1R2_D2G1RD1_Viewer(){
+        return resourceMemberU1R2_D2G1RD1_Viewer;
+    }
+
+
 }
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIResourceServiceTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIResourceServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..946b5a0f61583f979abb799150069e2d81b22770
--- /dev/null
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIResourceServiceTest.java
@@ -0,0 +1,157 @@
+package eu.europa.ec.edelivery.smp.services.ui;
+
+import eu.europa.ec.edelivery.smp.config.ConversionTestConfig;
+import eu.europa.ec.edelivery.smp.data.dao.ResourceDao;
+import eu.europa.ec.edelivery.smp.data.dao.ResourceMemberDao;
+import eu.europa.ec.edelivery.smp.data.enums.MembershipRoleType;
+import eu.europa.ec.edelivery.smp.data.enums.VisibilityType;
+import eu.europa.ec.edelivery.smp.data.model.doc.DBResource;
+import eu.europa.ec.edelivery.smp.data.model.user.DBResourceMember;
+import eu.europa.ec.edelivery.smp.data.ui.MemberRO;
+import eu.europa.ec.edelivery.smp.data.ui.ResourceRO;
+import eu.europa.ec.edelivery.smp.data.ui.ServiceResult;
+import eu.europa.ec.edelivery.smp.services.AbstractServiceIntegrationTest;
+import eu.europa.ec.edelivery.smp.testutil.TestROUtils;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.convert.ConversionService;
+import org.springframework.test.context.ContextConfiguration;
+
+import java.util.Optional;
+import java.util.UUID;
+
+import static eu.europa.ec.edelivery.smp.testutil.TestConstants.TEST_SG_SCHEMA_1;
+import static org.junit.Assert.*;
+
+@ContextConfiguration(classes = {UIResourceService.class, ConversionTestConfig.class})
+public class UIResourceServiceTest extends AbstractServiceIntegrationTest {
+    @Autowired
+    protected UIResourceService testInstance;
+
+    @Autowired
+    ResourceDao resourceDao;
+    @Autowired
+    ResourceMemberDao resourceMemberDao;
+    @Autowired
+    ConversionService conversionService;
+
+    @Before
+    public void prepareDatabase() {
+        // setup initial data!
+        testUtilsDao.clearData();
+        testUtilsDao.createResourceMemberships();
+    }
+
+    @Test
+    public void  testGetGroupResources() {
+        ServiceResult<ResourceRO> result =  testInstance.getGroupResources(testUtilsDao.getGroupD1G1().getId(), -1, -1, null);
+        // one resource is expected  - see the data in testUtilsDao.createResources()
+        assertNotNull(result);
+        assertEquals(1, result.getCount().intValue());
+    }
+
+    @Test
+    public void  testGetResourcesForUserAndGroup() {
+        ServiceResult<ResourceRO> resultAdmin =  testInstance.getResourcesForUserAndGroup(testUtilsDao.getUser1().getId(), MembershipRoleType.ADMIN,
+                testUtilsDao.getGroupD1G1().getId(), -1, -1, null);
+
+        ServiceResult<ResourceRO> resultViewer =  testInstance.getResourcesForUserAndGroup(testUtilsDao.getUser1().getId(), MembershipRoleType.VIEWER,
+                testUtilsDao.getGroupD1G1().getId(), -1, -1, null);
+        // see the data in testUtilsDao.createResourceMemberships()
+        assertEquals(1, resultAdmin.getCount().intValue());
+        assertEquals(0, resultViewer.getCount().intValue());
+    }
+
+    @Test
+    public void testCreateResourceForGroup(){
+        // given
+        ResourceRO testResource = TestROUtils.createResource(UUID.randomUUID().toString(), TEST_SG_SCHEMA_1,
+                testUtilsDao.getDomainResourceDefD1R1().getResourceDef().getIdentifier());
+
+        // when
+        ResourceRO result = testInstance.createResourceForGroup(testResource, testUtilsDao.getGroupD1G1().getId(),
+                testUtilsDao.getD1().getId(),testUtilsDao.getUser1().getId());
+        // then
+        assertNotNull(result);
+        assertEquals(testResource.getIdentifierValue(), result.getIdentifierValue());
+        assertEquals(testResource.getIdentifierScheme(), result.getIdentifierScheme());
+    }
+
+    @Test
+    public void testUpdateResourceForGroup(){
+        // given
+        DBResource dbResource = testUtilsDao.getResourceD1G1RD1();
+        ResourceRO testResource = TestROUtils.createResource( dbResource.getIdentifierValue(), dbResource.getIdentifierScheme(),dbResource.getDomainResourceDef().getResourceDef().getIdentifier());
+        assertNotEquals(dbResource.getVisibility(), VisibilityType.PRIVATE);
+        testResource.setVisibility(VisibilityType.PRIVATE);
+
+        // when
+        ResourceRO result = testInstance.updateResourceForGroup(testResource, dbResource.getId(),
+                testUtilsDao.getGroupD1G1().getId(),testUtilsDao.getD1().getId());
+        // then
+        assertNotNull(result);
+        assertEquals(testResource.getIdentifierValue(), result.getIdentifierValue());
+        assertEquals(testResource.getIdentifierScheme(), result.getIdentifierScheme());
+        assertEquals(VisibilityType.PRIVATE, result.getVisibility());
+    }
+
+    @Test
+    public void testDeleteResourceFromGroup(){
+        // given
+        ResourceRO testResource = TestROUtils.createResource(UUID.randomUUID().toString(), TEST_SG_SCHEMA_1,
+                testUtilsDao.getDomainResourceDefD1R1().getResourceDef().getIdentifier());
+        ResourceRO result = testInstance.createResourceForGroup(testResource, testUtilsDao.getGroupD1G1().getId(),
+                testUtilsDao.getD1().getId(),testUtilsDao.getUser1().getId());
+        Long resourceId = new Long(result.getResourceId());
+        assertNotNull(resourceDao.find(resourceId));
+        // when
+        testInstance.deleteResourceFromGroup(resourceId, testUtilsDao.getGroupD1G1().getId(),testUtilsDao.getD1().getId());
+        // then
+        assertNull(resourceDao.find(resourceId));
+    }
+
+    @Test
+    public void testGetResourceMembers(){
+        // given
+        // see the data in testUtilsDao.createResourceMemberships()
+        // when
+        ServiceResult<MemberRO> resourceMembers = testInstance.getResourceMembers(testUtilsDao.getResourceD1G1RD1().getId(), testUtilsDao.getGroupD1G1().getId(),-1,-1, null);
+        // then
+        assertNotNull(resourceMembers);
+        assertEquals(1, resourceMembers.getCount().intValue());
+        assertEquals(testUtilsDao.getUser1().getUsername(), resourceMembers.getServiceEntities().get(0).getUsername());
+    }
+
+    @Test
+    public void testAddUpdateMemberToResourceUpdate(){
+        // given
+        // see the data in testUtilsDao.createResourceMemberships()
+        DBResourceMember resourceMember = testUtilsDao.getResourceMemberU1R1_D2G1RD1_Admin();
+        MemberRO member = conversionService.convert(resourceMember, MemberRO.class);
+        member.setRoleType(MembershipRoleType.VIEWER);
+        // when
+        testInstance.addUpdateMemberToResource(testUtilsDao.getResourceD2G1RD1().getId(), testUtilsDao.getGroupD2G1().getId(), member, resourceMember.getId());
+        // then
+        DBResourceMember result = resourceMemberDao.find(resourceMember.getId());
+        assertNotNull(result);
+        assertEquals(MembershipRoleType.VIEWER, result.getRole());
+    }
+
+    @Test
+    public void testAddUpdateMemberToResourceUAdd(){
+        // given
+        int memberCount = testInstance.getResourceMembers(testUtilsDao.getResourceD1G1RD1().getId(), testUtilsDao.getGroupD1G1().getId(),-1,-1, null).getCount().intValue();
+        DBResourceMember dbMember = new DBResourceMember();
+        dbMember.setRole(MembershipRoleType.VIEWER);
+        dbMember.setUser(testUtilsDao.getUser2());
+        dbMember.setResource(testUtilsDao.getResourceD1G1RD1());
+        MemberRO member = conversionService.convert(dbMember, MemberRO.class);
+
+        // when
+        testInstance.addUpdateMemberToResource(testUtilsDao.getResourceD1G1RD1().getId(), testUtilsDao.getGroupD1G1().getId(), member, null);
+        // then
+        ServiceResult<MemberRO> resourceMembers = testInstance.getResourceMembers(testUtilsDao.getResourceD1G1RD1().getId(), testUtilsDao.getGroupD1G1().getId(),-1,-1, null);
+        assertEquals(memberCount+1, resourceMembers.getCount().intValue());
+    }
+}
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupServiceUpdateListIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupServiceUpdateListIntegrationTest.java
index 34d76194a8c44da4388c1976c79ce7f8850b99b0..be90cab4b616647c8e412fbba48eeb3b3778ca75 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupServiceUpdateListIntegrationTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupServiceUpdateListIntegrationTest.java
@@ -85,7 +85,7 @@ public class UIServiceGroupServiceUpdateListIntegrationTest extends AbstractServ
         serviceGroupDao.persistFlushDetach(d);
         return d;
     }
-
+/*
     @Test
     public void addNewServiceGroupTestSMLRecords() {
         // given
@@ -105,7 +105,7 @@ public class UIServiceGroupServiceUpdateListIntegrationTest extends AbstractServ
         assertEquals(serviceGroupRO.getParticipantIdentifier(), lst.get(0).getParticipantIdentifier());
         assertEquals(serviceGroupRO.getParticipantScheme(), lst.get(0).getParticipantScheme());
     }
-/*
+
     @Test
     @Transactional
     public void updateServiceGroupTestSMLRecordsRemoveDomain() {
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIUserServiceIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIUserServiceIntegrationTest.java
index 85c2d62f30f6ed412fd5d80ae2b68199a09c859a..93760e4107975bc82ef420384c6463dcf1a0ada4 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIUserServiceIntegrationTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIUserServiceIntegrationTest.java
@@ -2,31 +2,31 @@ package eu.europa.ec.edelivery.smp.services.ui;
 
 
 import eu.europa.ec.edelivery.smp.config.ConversionTestConfig;
-import eu.europa.ec.edelivery.smp.data.dao.ResourceDao;
 import eu.europa.ec.edelivery.smp.data.enums.ApplicationRoleType;
+import eu.europa.ec.edelivery.smp.data.enums.CredentialTargetType;
+import eu.europa.ec.edelivery.smp.data.enums.CredentialType;
 import eu.europa.ec.edelivery.smp.data.model.user.DBCredential;
 import eu.europa.ec.edelivery.smp.data.model.user.DBUser;
-import eu.europa.ec.edelivery.smp.data.ui.ServiceResult;
-import eu.europa.ec.edelivery.smp.data.ui.UserRO;
+import eu.europa.ec.edelivery.smp.data.ui.*;
 import eu.europa.ec.edelivery.smp.data.ui.enums.EntityROStatus;
 import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException;
 import eu.europa.ec.edelivery.smp.services.AbstractServiceIntegrationTest;
 import eu.europa.ec.edelivery.smp.testutil.TestDBUtils;
+import eu.europa.ec.edelivery.smp.testutil.TestROUtils;
 import org.hamcrest.CoreMatchers;
 import org.hamcrest.MatcherAssert;
-import org.junit.Assert;
-import org.junit.Ignore;
-import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.ExpectedException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.security.crypto.bcrypt.BCrypt;
 import org.springframework.test.context.ContextConfiguration;
 
+import java.math.BigInteger;
+import java.util.List;
 import java.util.Optional;
 import java.util.UUID;
 
+import static eu.europa.ec.edelivery.smp.testutil.SMPAssert.assertEqualDates;
 import static org.junit.Assert.*;
 
 
@@ -38,12 +38,10 @@ import static org.junit.Assert.*;
  */
 @ContextConfiguration(classes = {UIUserService.class, ConversionTestConfig.class})
 public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest {
-    @Rule
-    public ExpectedException expectedExeption = ExpectedException.none();
+
     @Autowired
     protected UIUserService testInstance;
-    @Autowired
-    protected ResourceDao serviceGroupDao;
+
 
     protected void insertDataObjects(int size) {
         for (int i = 0; i < size; i++) {
@@ -117,8 +115,6 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest
         assertEquals(user.getEmailAddress(), oUsr.get().getEmailAddress());
     }
 
-
-
     @Test
     public void testDeleteUser() {
         // given
@@ -141,7 +137,6 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest
     }
 
     @Test
-    @Ignore
     public void testUpdateUserPasswordNotMatchReqExpression() {
         long authorizedUserId = 1L;
         long userToUpdateId = 1L;
@@ -190,7 +185,6 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest
     }
 
     @Test
-    @Ignore
     public void testUpdateUserPasswordOK() {
         DBUser user = TestDBUtils.createDBUserByUsername(UUID.randomUUID().toString());
         DBCredential credential = TestDBUtils.createDBCredentialForUser(user, null, null, null);
@@ -227,4 +221,193 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest
         assertEquals(userRO.getEmailAddress(), changedUser.getEmailAddress());
     }
 
+
+    @Test
+    public void testCreateAccessTokenForUser() {
+        DBUser user = TestDBUtils.createDBUserByUsername(UUID.randomUUID().toString());
+        userDao.persistFlushDetach(user);
+        CredentialRO credentialRO = new CredentialRO();
+        credentialRO.setCredentialType(CredentialType.ACCESS_TOKEN);
+        credentialRO.setDescription("test description");
+
+        AccessTokenRO accessToken = testInstance.createAccessTokenForUser(user.getId(), credentialRO);
+
+        assertNotNull(accessToken);
+        assertNotNull(accessToken.getValue());
+        assertNotNull(accessToken.getIdentifier());
+        assertNotNull(accessToken.getCredential());
+        assertNotNull(accessToken.getCredential().getCredentialId());
+        assertNotNull(accessToken.getExpireOn());
+        assertNotNull(accessToken.getGeneratedOn());
+        assertEquals(credentialRO.getDescription(), accessToken.getCredential().getDescription());
+        assertEquals(accessToken.getIdentifier(), accessToken.getCredential().getName());
+        assertEqualDates(accessToken.getExpireOn(), accessToken.getCredential().getExpireOn());
+        assertEqualDates(accessToken.getGeneratedOn(), accessToken.getCredential().getActiveFrom());
+    }
+
+    @Test
+    public void testStoreCertificateCredentialForUser() throws Exception {
+        DBUser user = TestDBUtils.createDBUserByUsername(UUID.randomUUID().toString());
+        userDao.persistFlushDetach(user);
+        CertificateRO certificateRO = TestROUtils.createCertificateRO("CN=Test,OU=Test,O=Test,L=Test,ST=Test,C=EU", BigInteger.TEN);
+
+        CredentialRO credentialRO = new CredentialRO();
+        credentialRO.setCredentialType(CredentialType.CERTIFICATE);
+        credentialRO.setDescription("test description");
+        credentialRO.setCertificate(certificateRO);
+
+        CredentialRO result = testInstance.storeCertificateCredentialForUser(user.getId(), credentialRO);
+
+        assertNotNull(result);
+        assertNotNull(result.getCertificate());
+        assertEquals(certificateRO.getCertificateId(), result.getName());
+        assertEqualDates(certificateRO.getValidTo(), result.getExpireOn());
+        assertEqualDates(certificateRO.getValidFrom(), result.getActiveFrom());
+        assertEquals(credentialRO.getDescription(), result.getDescription());
+    }
+
+    @Test
+    public void testUpdateUserProfile() {
+        DBUser user = TestDBUtils.createDBUserByUsername(UUID.randomUUID().toString());
+        userDao.persistFlushDetach(user);
+        UserRO userRO = new UserRO();
+        userRO.setUsername(UUID.randomUUID().toString());
+        // add opposite to current role
+        userRO.setRole(user.getApplicationRole() == ApplicationRoleType.USER ? ApplicationRoleType.SYSTEM_ADMIN : ApplicationRoleType.USER);
+        userRO.setEmailAddress(UUID.randomUUID().toString());
+        userRO.setFullName(UUID.randomUUID().toString());
+        userRO.setSmpTheme(UUID.randomUUID().toString());
+        userRO.setSmpLocale(UUID.randomUUID().toString());
+
+        testInstance.updateUserProfile(user.getId(), userRO);
+
+        DBUser changedUser = userDao.findUser(user.getId()).get();
+        // fields must not change
+        assertEquals(user.getUsername(), changedUser.getUsername());
+        assertEquals(user.getApplicationRole(), changedUser.getApplicationRole());
+        // changed
+        assertEquals(userRO.getEmailAddress(), changedUser.getEmailAddress());
+        assertEquals(userRO.getSmpTheme(), changedUser.getSmpTheme());
+        assertEquals(userRO.getSmpLocale(), changedUser.getSmpLocale());
+        assertEquals(userRO.getEmailAddress(), changedUser.getEmailAddress());
+        assertEquals(userRO.getFullName(), changedUser.getFullName());
+    }
+
+    @Test
+    public void testGetUserCredentials() {
+        DBUser user = TestDBUtils.createDBUserByUsername(UUID.randomUUID().toString());
+        userDao.persistFlushDetach(user);
+        CredentialRO credentialRO = new CredentialRO();
+        credentialRO.setCredentialType(CredentialType.ACCESS_TOKEN);
+        credentialRO.setDescription("test description");
+
+        testInstance.createAccessTokenForUser(user.getId(), credentialRO);
+
+        List<CredentialRO> result = testInstance.getUserCredentials(user.getId(), CredentialType.ACCESS_TOKEN, CredentialTargetType.REST_API);
+        List<CredentialRO> result2 = testInstance.getUserCredentials(user.getId(), CredentialType.CERTIFICATE, CredentialTargetType.REST_API);
+
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        assertEquals(0, result2.size());
+        assertEquals(credentialRO.getDescription(), result.get(0).getDescription());
+    }
+
+    @Test
+    public void testGetUserCertificateCredential() throws Exception {
+        DBUser user = TestDBUtils.createDBUserByUsername(UUID.randomUUID().toString());
+        userDao.persistFlushDetach(user);
+
+        CertificateRO certificateRO = TestROUtils.createCertificateRO("CN=Test,OU=Test,O=Test,L=Test,ST=Test,C=EU", BigInteger.TEN);
+
+        CredentialRO credentialRO = new CredentialRO();
+        credentialRO.setCredentialType(CredentialType.CERTIFICATE);
+        credentialRO.setDescription("test description");
+        credentialRO.setCertificate(certificateRO);
+        credentialRO = testInstance.storeCertificateCredentialForUser(user.getId(), credentialRO);
+        // the credential id for the test is not encrypted and we can use "Long parsing".
+        CredentialRO result = testInstance.getUserCertificateCredential(user.getId(), new Long(credentialRO.getCredentialId()));
+
+        assertNotNull(result);
+        assertEquals(credentialRO.getCredentialId(), result.getCredentialId());
+        assertEquals(credentialRO.getDescription(), result.getDescription());
+        assertEquals(credentialRO.getCertificate().getCertificateId(), result.getCertificate().getCertificateId());
+    }
+
+    @Test
+    public void testDeleteUserCredentials() {
+        DBUser user = TestDBUtils.createDBUserByUsername(UUID.randomUUID().toString());
+        userDao.persistFlushDetach(user);
+        CredentialRO credentialRO = new CredentialRO();
+        credentialRO.setCredentialType(CredentialType.ACCESS_TOKEN);
+        credentialRO.setDescription("test description");
+        testInstance.createAccessTokenForUser(user.getId(), credentialRO);
+
+        List<CredentialRO> result = testInstance.getUserCredentials(user.getId(), CredentialType.ACCESS_TOKEN, CredentialTargetType.REST_API);
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        assertEquals(credentialRO.getDescription(), result.get(0).getDescription());
+        // the credential id for the test is not encrypted and we can use "Long parsing".
+        testInstance.deleteUserCredentials(user.getId(), new Long(result.get(0).getCredentialId()), CredentialType.ACCESS_TOKEN, CredentialTargetType.REST_API);
+
+        result = testInstance.getUserCredentials(user.getId(), CredentialType.ACCESS_TOKEN, CredentialTargetType.REST_API);
+        assertNotNull(result);
+        assertEquals(0, result.size());
+    }
+
+    @Test
+    public void testUpdateUserCredentials() {
+        DBUser user = TestDBUtils.createDBUserByUsername(UUID.randomUUID().toString());
+        userDao.persistFlushDetach(user);
+        CredentialRO credentialRO = new CredentialRO();
+        credentialRO.setCredentialType(CredentialType.ACCESS_TOKEN);
+        credentialRO.setDescription("test description");
+        testInstance.createAccessTokenForUser(user.getId(), credentialRO);
+
+        List<CredentialRO> result = testInstance.getUserCredentials(user.getId(), CredentialType.ACCESS_TOKEN, CredentialTargetType.REST_API);
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        assertEquals(credentialRO.getDescription(), result.get(0).getDescription());
+
+        CredentialRO credentialRO2 = new CredentialRO();
+        credentialRO2.setCredentialType(CredentialType.ACCESS_TOKEN);
+        credentialRO2.setDescription("test description 2");
+        // the credential id for the test is not encrypted and we can use "Long parsing".
+        testInstance.updateUserCredentials(user.getId(), new Long(result.get(0).getCredentialId()), CredentialType.ACCESS_TOKEN, CredentialTargetType.REST_API, credentialRO2);
+
+        result = testInstance.getUserCredentials(user.getId(), CredentialType.ACCESS_TOKEN, CredentialTargetType.REST_API);
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        assertEquals(credentialRO2.getDescription(), result.get(0).getDescription());
+    }
+
+    @Test
+    public void testSearchUsers() {
+        long count = testInstance.searchUsers(-1, -1, null).getCount();
+        DBUser user = TestDBUtils.createDBUserByUsername(UUID.randomUUID().toString());
+        userDao.persistFlushDetach(user);
+
+        ServiceResult<SearchUserRO> result = testInstance.searchUsers(-1, -1, null);
+        assertNotNull(result);
+        assertEquals(count + 1, result.getServiceEntities().size());
+        assertEquals(user.getUsername(), result.getServiceEntities().get(0).getUsername());
+        assertEquals(user.getFullName(), result.getServiceEntities().get(0).getFullName());
+    }
+
+    @Test
+    public void testSearchUsersFilter() {
+        long count = testInstance.searchUsers(-1, -1, null).getCount();
+        DBUser user = TestDBUtils.createDBUserByUsername(UUID.randomUUID().toString());
+        DBUser user2 = TestDBUtils.createDBUserByUsername("TESTuser_" + UUID.randomUUID());
+        DBUser user3 = TestDBUtils.createDBUserByUsername("test_" + UUID.randomUUID());
+        userDao.persistFlushDetach(user);
+        userDao.persistFlushDetach(user2);
+        userDao.persistFlushDetach(user3);
+
+        ServiceResult<SearchUserRO> result = testInstance.searchUsers(-1, -1, "test");
+        assertNotNull(result);
+        assertEquals(count + 2, result.getServiceEntities().size());
+        MatcherAssert.assertThat(result.getServiceEntities().get(0).getUsername(), CoreMatchers.containsStringIgnoringCase("test"));
+        MatcherAssert.assertThat(result.getServiceEntities().get(1).getUsername(), CoreMatchers.containsStringIgnoringCase("test"));
+
+    }
 }
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/SMPAssert.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/SMPAssert.java
new file mode 100644
index 0000000000000000000000000000000000000000..08c27ec4fcb5ebd7c5ea3fa82ae70ba46dfe5fac
--- /dev/null
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/SMPAssert.java
@@ -0,0 +1,23 @@
+package eu.europa.ec.edelivery.smp.testutil;
+
+import java.time.OffsetDateTime;
+
+import static org.junit.Assert.assertEquals;
+
+public class SMPAssert {
+
+    private SMPAssert() {
+    }
+
+    public static void assertEqualDates(OffsetDateTime expected, OffsetDateTime actual) {
+        if (expected == actual) {
+            return;
+        }
+        // if one of them is null, but not both check in previous if
+        if (expected == null || actual == null) {
+            throw new AssertionError("Expected " + expected + " but was " + actual);
+        }
+        // compare instant
+        assertEquals(expected.toInstant(), actual.toInstant());
+    }
+}
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestROUtils.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestROUtils.java
index 6846c01ead5e844f3aac250eebfd0b6d617e50a4..7a444f72c58737f716d2f360777754323c7684c7 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestROUtils.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestROUtils.java
@@ -1,11 +1,11 @@
 package eu.europa.ec.edelivery.smp.testutil;
 
 import eu.europa.ec.edelivery.smp.conversion.X509CertificateToCertificateROConverter;
+import eu.europa.ec.edelivery.smp.data.enums.VisibilityType;
 import eu.europa.ec.edelivery.smp.data.model.DBDomain;
 import eu.europa.ec.edelivery.smp.data.ui.*;
 import eu.europa.ec.edelivery.smp.data.ui.enums.EntityROStatus;
 
-import java.io.IOException;
 import java.math.BigInteger;
 import java.security.cert.X509Certificate;
 import java.util.Arrays;
@@ -39,42 +39,24 @@ public class TestROUtils {
         return sgd;
     }
 
-    public static ServiceGroupRO createROServiceGroup() {
-        return createROServiceGroup(TestConstants.TEST_SG_ID_1, TestConstants.TEST_SG_SCHEMA_1);
+    public static ResourceRO createResource() {
+        return createResource(TestConstants.TEST_SG_ID_1, TestConstants.TEST_SG_SCHEMA_1);
     }
 
-    public static ServiceGroupRO createROServiceGroupForDomains(DBDomain... domains) {
-        ServiceGroupRO sgo = createROServiceGroup(TestConstants.TEST_SG_ID_1, TestConstants.TEST_SG_SCHEMA_1);
-        Arrays.asList(domains).forEach(domain -> {
-            ServiceGroupDomainRO sgd = createServiceGroupDomain(domain);
-            sgo.getServiceGroupDomains().add(sgd);
-        });
-        return sgo;
-    }
 
-    public static ServiceGroupRO createROServiceGroupForDomains(String id, String sch, DBDomain... domains) {
-        ServiceGroupRO sgo = createROServiceGroup(id, sch);
-        Arrays.asList(domains).forEach(domain -> {
-            ServiceGroupDomainRO sgd = createServiceGroupDomain(domain);
-            sgo.getServiceGroupDomains().add(sgd);
-        });
-        return sgo;
-    }
 
-    public static ServiceGroupRO createROServiceGroup(String id, String sch) {
-        return createROServiceGroup(id, sch, true);
+    public static ResourceRO createResource(String id, String sch) {
+        return createResource(id, sch, null);
     }
 
-    public static ServiceGroupRO createROServiceGroup(String id, String sch, boolean withExtension) {
-        ServiceGroupRO grp = new ServiceGroupRO();
-        grp.setStatus(EntityROStatus.NEW.getStatusNumber());
-        grp.setParticipantIdentifier(id);
-        grp.setParticipantScheme(sch);
-        if (withExtension) {
-            grp.setExtensionStatus(EntityROStatus.NEW.getStatusNumber());
-            grp.setExtension(generateExtension());
-        }
-        return grp;
+    public static ResourceRO createResource(String id, String sch, String resourceType) {
+        ResourceRO resourceRO = new ResourceRO();
+        resourceRO.setStatus(EntityROStatus.NEW.getStatusNumber());
+        resourceRO.setIdentifierValue(id);
+        resourceRO.setIdentifierScheme(sch);
+        resourceRO.setVisibility(VisibilityType.PUBLIC);
+        resourceRO.setResourceTypeIdentifier(resourceType);
+        return resourceRO;
     }
 
     public static String generateExtension() {
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/edit/ResourceEditController.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/edit/ResourceEditController.java
index fd7e38fb999238e4d6d52f0de8629ac0f4183d54..5bc9ca164a5d72444a3131a5664a8a48708e6947 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/edit/ResourceEditController.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/edit/ResourceEditController.java
@@ -152,7 +152,7 @@ public class ResourceEditController {
             memberRO.setRoleType(MembershipRoleType.VIEWER);
         }
         // is user domain admin or system admin
-        return uiResourceService.addMemberToResource(resourceId, groupId, memberRO, memberId);
+        return uiResourceService.addUpdateMemberToResource(resourceId, groupId, memberRO, memberId);
     }
 
     @DeleteMapping(value = SUB_CONTEXT_PATH_EDIT_RESOURCE_MEMBER_DELETE)