diff --git a/authentication/source/java/ch/systemsx/cisd/authentication/DefaultSessionManager.java b/authentication/source/java/ch/systemsx/cisd/authentication/DefaultSessionManager.java
index 4b191d34b7ac42b81f12a978988f624b8593ea38..ebf3e9e400ba48b8d7ba5583bca60081ad8ba03d 100644
--- a/authentication/source/java/ch/systemsx/cisd/authentication/DefaultSessionManager.java
+++ b/authentication/source/java/ch/systemsx/cisd/authentication/DefaultSessionManager.java
@@ -37,7 +37,6 @@ import org.apache.commons.lang3.time.DurationFormatUtils;
 import org.apache.log4j.Logger;
 
 import ch.systemsx.cisd.authentication.pat.IPersonalAccessTokenDAO;
-import ch.systemsx.cisd.authentication.pat.PersonalAccessToken;
 import ch.systemsx.cisd.authentication.pat.PersonalAccessTokenSession;
 import ch.systemsx.cisd.common.collection.SimpleComparator;
 import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
@@ -95,17 +94,24 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa
 
     protected static final class FullSession<S extends BasicSession>
     {
-        /** Session data. */
+        /**
+         * Session data.
+         */
         private final S session;
 
-        /** The last time when this session has been used (in milliseconds since 1970-01-01). */
+        private final boolean isPATSession;
+
+        /**
+         * The last time when this session has been used (in milliseconds since 1970-01-01).
+         */
         private long lastActiveTime;
 
-        FullSession(final S session)
+        FullSession(final S session, final boolean isPATSession)
         {
             assert session != null : "Undefined session";
 
             this.session = session;
+            this.isPATSession = isPATSession;
             touch();
         }
 
@@ -117,6 +123,14 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa
             return session;
         }
 
+        /**
+         * Returns <code>true</code> if the session is a personal access token session.
+         */
+        public boolean isPATSession()
+        {
+            return isPATSession;
+        }
+
         /**
          * Sets the time of last activity (used to determine whether the session {@link #hasExpired(Long)}.
          */
@@ -133,6 +147,7 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa
             long sessionExpirationTime = sessionExpirationTimeOrNull == null ? session.getSessionExpirationTime() : sessionExpirationTimeOrNull;
             return System.currentTimeMillis() - lastActiveTime > sessionExpirationTime;
         }
+
     }
 
     private final ISessionFactory<T> sessionFactory;
@@ -145,9 +160,6 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa
     protected final Map<String, FullSession<T>> sessions =
             new LinkedHashMap<String, FullSession<T>>();
 
-    protected final Map<String, FullSession<T>> patSessions =
-            new LinkedHashMap<String, FullSession<T>>();
-
     private final IAuthenticationService authenticationService;
 
     private final IRemoteHostProvider remoteHostProvider;
@@ -227,6 +239,46 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa
         this.patDAO = patDAO;
     }
 
+    protected void init()
+    {
+        List<PersonalAccessTokenSession> patSessions = patDAO.listSessions();
+
+        synchronized (sessions)
+        {
+            for (PersonalAccessTokenSession patSession : patSessions)
+            {
+                try
+                {
+                    final Principal principal = authenticationService.getPrincipal(patSession.getUserId());
+
+                    if (principal == null)
+                    {
+                        sessions.remove(patSession.getHash());
+                        throw new InvalidSessionException("User '%s' not found by the authentication service.");
+                    } else
+                    {
+                        principal.setAuthenticated(true);
+                    }
+
+                    final FullSession<T> createdSession = createSession(patSession.getHash(), patSession.getUserId(), principal, getRemoteHost(),
+                            patSession.getValidFrom().getTime(), (int) (patSession.getValidUntil().getTime() - System.currentTimeMillis()), true);
+
+                    sessions.put(createdSession.getSession().getSessionToken(), createdSession);
+                } catch (InvalidSessionException e)
+                {
+                    operationLog.info("Invalid personal access session. Skipping it.", e);
+                }
+            }
+        }
+    }
+
+    protected FullSession<T> createSession(String sessionToken, String userName, Principal principal, String remoteHost, long sessionStart,
+            int sessionExpirationTime, boolean isPATSession)
+    {
+        T session = sessionFactory.create(sessionToken, userName, principal, remoteHost, sessionStart, sessionExpirationTime);
+        return new FullSession<>(session, isPATSession);
+    }
+
     private final T createAndStoreSession(final String user, final Principal principal,
             final long now)
     {
@@ -238,7 +290,7 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa
             int maxNumberOfSessions = getMaxNumberOfSessionsFor(user);
             if (maxNumberOfSessions > 0)
             {
-                List<FullSession<T>> openSessions = getOpenSessionsFor(user);
+                List<FullSession<T>> openSessions = getOpenSessionsForClosing(user);
                 while (openSessions.size() >= maxNumberOfSessions)
                 {
                     FullSession<T> session = openSessions.remove(0);
@@ -246,43 +298,25 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa
                 }
             }
 
-            final T session =
-                    sessionFactory.create(sessionToken, user, principal, getRemoteHost(), now,
-                            sessionExpirationPeriodMillis);
-            final FullSession<T> createdSession = new FullSession<T>(session);
+            final FullSession<T> createdSession = createSession(sessionToken, user, principal, getRemoteHost(), now,
+                    sessionExpirationPeriodMillis, false);
             sessions.put(createdSession.getSession().getSessionToken(), createdSession);
 
             getSessionMonitor().logSessionMonitoringInfo();
 
-            return session;
-        }
-    }
-
-    private final FullSession<T> createPersonalAccessTokenSession(final String userId, final String hash, final Date now, final Date validFrom,
-            final Date validUntil)
-    {
-        final Principal principal = tryGetAndAuthenticateUser(userId, null);
-
-        if (principal == null)
-        {
-            throw new InvalidSessionException(
-                    String.format("Personal access session cannot be created because personal access token user '%s' does not exist.",
-                            userId));
+            return createdSession.getSession();
         }
-
-        final T newSession = sessionFactory.create(hash, userId, principal, getRemoteHost(), validFrom.getTime(),
-                (int) (validUntil.getTime() - now.getTime()));
-
-        patSessions.put(newSession.getSessionToken(), new FullSession<>(newSession));
-
-        return new FullSession<>(newSession);
     }
 
-    private List<FullSession<T>> getOpenSessionsFor(String user)
+    private List<FullSession<T>> getOpenSessionsForClosing(String user)
     {
         List<FullSession<T>> userSessions = new ArrayList<>();
         for (FullSession<T> session : sessions.values())
         {
+            if (session.isPATSession())
+            {
+                continue;
+            }
             if (session.getSession().getUserName().equals(user))
             {
                 userSessions.add(session);
@@ -391,10 +425,11 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa
         public void logSessionMonitoringInfo()
         {
             int sessionsSize = sessions.size();
-            int patSessionsSize = patSessions.size();
+            long patSessionsSize =
+                    sessions.values().stream().filter(FullSession::isPATSession).count();
 
-            operationLog.info("Currently active sessions: " + sessionsSize);
-            operationLog.info("Currently active personal access token sessions: " + patSessionsSize);
+            operationLog.info("All currently active sessions: " + sessionsSize);
+            operationLog.info("Personal access token active sessions: " + patSessionsSize);
 
             if (sessionsSize > sessionNotifyThreshold)
             {
@@ -441,8 +476,19 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa
 
     private boolean doSessionExpiration(final FullSession<T> session)
     {
-        Long expTimeOrNull = NO_LOGIN_FILE.exists() ? (long) sessionExpirationPeriodMillisNoLogin : null;
-        return session != null && session.hasExpired(expTimeOrNull);
+        if (session == null)
+        {
+            return false;
+        }
+
+        if (session.isPATSession())
+        {
+            return session.hasExpired(null);
+        } else
+        {
+            Long expTimeOrNull = NO_LOGIN_FILE.exists() ? (long) sessionExpirationPeriodMillisNoLogin : null;
+            return session.hasExpired(expTimeOrNull);
+        }
     }
 
     private void logAuthenticed(final T session, final long timeToLoginMillis)
@@ -552,13 +598,6 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa
     @Override
     public T getSession(final String sessionToken) throws InvalidSessionException
     {
-        T patSession = getPersonalAccessTokenSession(sessionToken);
-
-        if (patSession != null)
-        {
-            return patSession;
-        }
-
         return getSession(sessionToken, true);
     }
 
@@ -630,97 +669,6 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa
         }
     }
 
-    private T getPersonalAccessTokenSession(String hash)
-    {
-        PersonalAccessToken patToken = patDAO.getTokenByHash(hash);
-        Date now = new Date();
-
-        if (patToken == null)
-        {
-            PersonalAccessTokenSession patSession = patDAO.getSessionByHash(hash);
-
-            if (patSession == null)
-            {
-                return null;
-            } else
-            {
-                if (now.before(patSession.getValidFrom()))
-                {
-                    throw new InvalidSessionException("Personal access token session is not yet valid.");
-                }
-
-                if (now.after(patSession.getValidUntil()))
-                {
-                    throw new InvalidSessionException("Personal access token session is no longer valid.");
-                }
-
-                patSession.setLastAccessedAt(now);
-                patDAO.updateSession(patSession);
-
-                FullSession<T> newSession =
-                        createPersonalAccessTokenSession(patSession.getUserId(), patSession.getHash(), now, patSession.getValidFrom(),
-                                patSession.getValidUntil());
-
-                return newSession.getSession();
-            }
-        } else
-        {
-            if (now.before(patToken.getValidFrom()))
-            {
-                throw new InvalidSessionException("Personal access token is not yet valid.");
-            }
-
-            if (now.after(patToken.getValidUntil()))
-            {
-                throw new InvalidSessionException("Personal access token is no longer valid.");
-            }
-
-            final PersonalAccessTokenSession patSession =
-                    patDAO.getSessionByUserIdAndSessionName(patToken.getUserId(), patToken.getSessionName());
-
-            synchronized (patSessions)
-            {
-                patToken.setLastAccessedAt(now);
-                patDAO.updateToken(patToken);
-
-                if (patSession == null)
-                {
-                    final String newSessionHash =
-                            patToken.getUserId() + SESSION_TOKEN_SEPARATOR + tokenGenerator.getNewToken(now.getTime(), TIMESTAMP_TOKEN_SEPARATOR);
-
-                    FullSession<T> newSession =
-                            createPersonalAccessTokenSession(patToken.getUserId(), newSessionHash, now, now,
-                                    patToken.getValidUntil());
-
-                    final PersonalAccessTokenSession newPatSession = new PersonalAccessTokenSession();
-                    newPatSession.setUserId(patToken.getUserId());
-                    newPatSession.setSessionName(patToken.getSessionName());
-                    newPatSession.setHash(newSession.getSession().getSessionToken());
-                    newPatSession.setValidFrom(now);
-                    newPatSession.setValidUntil(patToken.getValidUntil());
-                    newPatSession.setLastAccessedAt(now);
-                    patDAO.createSession(newPatSession);
-
-                    return newSession.getSession();
-                } else
-                {
-                    patSession.setLastAccessedAt(now);
-                    if (patToken.getValidUntil().after(patSession.getValidUntil()))
-                    {
-                        patSession.setValidUntil(patToken.getValidUntil());
-                    }
-                    patDAO.updateSession(patSession);
-
-                    FullSession<T> newSession =
-                            createPersonalAccessTokenSession(patSession.getUserId(), patSession.getHash(), now, patSession.getValidFrom(),
-                                    patSession.getValidUntil());
-
-                    return newSession.getSession();
-                }
-            }
-        }
-    }
-
     @Override
     public String tryToOpenSession(final String user, final String password)
     {
diff --git a/authentication/source/java/ch/systemsx/cisd/authentication/pat/FileBasedPersonalAccessTokenDAO.java b/authentication/source/java/ch/systemsx/cisd/authentication/pat/FileBasedPersonalAccessTokenDAO.java
index 5a78eeaa9949ffd65d7e7f26e2aba077f3379371..44da69eb9f18c9f5fb0c1ac189adccd946e2120d 100644
--- a/authentication/source/java/ch/systemsx/cisd/authentication/pat/FileBasedPersonalAccessTokenDAO.java
+++ b/authentication/source/java/ch/systemsx/cisd/authentication/pat/FileBasedPersonalAccessTokenDAO.java
@@ -1,73 +1,90 @@
 package ch.systemsx.cisd.authentication.pat;
 
-import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.lang3.time.DateUtils;
+
 public class FileBasedPersonalAccessTokenDAO implements IPersonalAccessTokenDAO
 {
 
-    private File file;
+    private final Map<String, PersonalAccessToken> tokens;
+
+    private final Map<String, PersonalAccessTokenSession> sessions;
 
-    public FileBasedPersonalAccessTokenDAO(File file)
+    public FileBasedPersonalAccessTokenDAO()
     {
-        if (file == null)
+        try
         {
-            throw new IllegalArgumentException("File cannot be null");
+            // TEST DATA
+            PersonalAccessToken token1 = new PersonalAccessToken();
+            token1.setUserId("admin");
+            token1.setSessionName("app1");
+            token1.setHash("admin-111111111111111x11111111111111111111111111111111");
+            token1.setValidFrom(DateUtils.parseDate("2022-01-01 10:00", "YYYY-MM-dd HH:mm"));
+            token1.setValidUntil(DateUtils.parseDate("2022-06-10 12:00", "YYYY-MM-dd HH:mm"));
+
+            PersonalAccessToken token2 = new PersonalAccessToken();
+            token2.setUserId("admin");
+            token2.setSessionName("app1");
+            token2.setHash("admin-222222222222222x22222222222222222222222222222222");
+            token2.setValidFrom(DateUtils.parseDate("2022-06-01 10:00", "YYYY-MM-dd HH:mm"));
+            token2.setValidUntil(DateUtils.parseDate("2022-10-10 12:00", "YYYY-MM-dd HH:mm"));
+
+            tokens = new HashMap<>();
+            tokens.put(token1.getHash(), token1);
+            tokens.put(token2.getHash(), token2);
+
+            PersonalAccessTokenSession session1 = new PersonalAccessTokenSession();
+            session1.setUserId("admin");
+            session1.setSessionName("app1");
+            session1.setHash("admin-999999999999999x99999999999999999999999999999999");
+            session1.setValidFrom(token1.getValidFrom());
+            session1.setValidUntil(token2.getValidUntil());
+
+            sessions = new HashMap<>();
+            sessions.put(session1.getHash(), session1);
+
+        } catch (Exception e)
+        {
+            throw new RuntimeException(e);
         }
-        this.file = file;
     }
 
     @Override public List<PersonalAccessToken> listTokens()
     {
-        return null;
+        return new ArrayList<>(tokens.values());
     }
 
     @Override public PersonalAccessToken getTokenByHash(final String hash)
     {
-        return null;
+        return tokens.get(hash);
     }
 
-    @Override public void createToken(final PersonalAccessToken creation)
+    @Override public void updateToken(final PersonalAccessToken patToken)
     {
-
+        tokens.put(patToken.getHash(), patToken);
     }
 
-    @Override public void updateToken(final PersonalAccessToken update)
+    @Override public List<PersonalAccessTokenSession> listSessions()
     {
-
-    }
-
-    @Override public void deleteToken(final String hash)
-    {
-
-    }
-
-    @Override public PersonalAccessTokenSession getSessionByHash(final String hash)
-    {
-        return null;
+        return new ArrayList<>(sessions.values());
     }
 
     @Override public PersonalAccessTokenSession getSessionByUserIdAndSessionName(final String userId, final String sessionName)
     {
+        for (PersonalAccessTokenSession session : sessions.values())
+        {
+            if (session.getUserId().equals(userId) && session.getSessionName().equals(sessionName))
+            {
+                return session;
+            }
+        }
         return null;
     }
 
-    @Override public void createSession(final PersonalAccessTokenSession creation)
-    {
-
-    }
-
-    @Override public void updateSession(final PersonalAccessTokenSession update)
-    {
-
-    }
-
-    @Override public void deleteSession(final String hash)
-    {
-
-    }
-
     private static class FileContent
     {
         private Map<String, PersonalAccessToken> tokens;
diff --git a/authentication/source/java/ch/systemsx/cisd/authentication/pat/IPersonalAccessTokenDAO.java b/authentication/source/java/ch/systemsx/cisd/authentication/pat/IPersonalAccessTokenDAO.java
index 7972561b6038b074e86c47d2b0e7d52d59ba1358..fa1324aaf145ea984a505e97b942df71289f4750 100644
--- a/authentication/source/java/ch/systemsx/cisd/authentication/pat/IPersonalAccessTokenDAO.java
+++ b/authentication/source/java/ch/systemsx/cisd/authentication/pat/IPersonalAccessTokenDAO.java
@@ -9,20 +9,11 @@ public interface IPersonalAccessTokenDAO
 
     PersonalAccessToken getTokenByHash(String hash);
 
-    void createToken(PersonalAccessToken creation);
+    void updateToken(PersonalAccessToken patToken);
 
-    void updateToken(PersonalAccessToken update);
-
-    void deleteToken(String hash);
-
-    PersonalAccessTokenSession getSessionByHash(String hash);
+    List<PersonalAccessTokenSession> listSessions();
 
     PersonalAccessTokenSession getSessionByUserIdAndSessionName(String userId, String sessionName);
 
-    void createSession(PersonalAccessTokenSession creation);
-
-    void updateSession(PersonalAccessTokenSession update);
-
-    void deleteSession(String hash);
 
 }
diff --git a/authentication/sourceTest/java/ch/systemsx/cisd/authentication/DefaultSessionManagerTest.java b/authentication/sourceTest/java/ch/systemsx/cisd/authentication/DefaultSessionManagerTest.java
index 8704bf905bc52b5709c2d374c306bad517d9c637..08495437c06eea6605766efe35d1b79b465cacef 100644
--- a/authentication/sourceTest/java/ch/systemsx/cisd/authentication/DefaultSessionManagerTest.java
+++ b/authentication/sourceTest/java/ch/systemsx/cisd/authentication/DefaultSessionManagerTest.java
@@ -36,6 +36,7 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Listeners;
 import org.testng.annotations.Test;
 
+import ch.systemsx.cisd.authentication.pat.IPersonalAccessTokenDAO;
 import ch.systemsx.cisd.base.utilities.OSUtilities;
 import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
@@ -82,6 +83,8 @@ public class DefaultSessionManagerTest
 
     private ISessionActionListener sessionActionListener;
 
+    private IPersonalAccessTokenDAO personalAccessTokenDAO;
+
     private void assertExceptionMessageForInvalidSessionToken(final UserFailureException ex)
     {
         final String message = ex.getMessage();
@@ -99,11 +102,14 @@ public class DefaultSessionManagerTest
         remoteHostProvider = context.mock(IRemoteHostProvider.class);
         principalProvider = context.mock(IPrincipalProvider.class);
         sessionActionListener = context.mock(ISessionActionListener.class);
+        personalAccessTokenDAO = context.mock(IPersonalAccessTokenDAO.class);
         sequence = context.sequence("sequence");
         context.checking(new Expectations()
             {
                 {
                     one(authenticationService).check();
+                    allowing(personalAccessTokenDAO).listSessions();
+                    will(returnValue(Collections.emptyList()));
                 }
             });
         sessionManager = createSessionManager(SESSION_EXPIRATION_PERIOD_MINUTES);
@@ -120,7 +126,7 @@ public class DefaultSessionManagerTest
             Map<String, Integer> maxNumberOfSessionByUser)
     {
         return new DefaultSessionManager(sessionFactory, prefixGenerator, authenticationService,
-                remoteHostProvider, sessionExpiration, 0, true)
+                remoteHostProvider, sessionExpiration, 0, true, personalAccessTokenDAO)
             {
 
                 @Override
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/common/get/GetServerInformationOperationExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/common/get/GetServerInformationOperationExecutor.java
index 9b1f9ec87aa2e793bdbfc60a5e75300f0c3e5860..7fc2c35f2e8f2bf0d6dec34781a6764d9de5a909 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/common/get/GetServerInformationOperationExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/common/get/GetServerInformationOperationExecutor.java
@@ -25,6 +25,7 @@ import javax.annotation.Resource;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.get.GetServerInformationOperation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.get.GetServerInformationOperationResult;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.get.GetServerPublicInformationOperation;
@@ -35,6 +36,7 @@ import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.common.OperationExecutor;
 import ch.systemsx.cisd.common.spring.ExposablePropertyPlaceholderConfigurer;
 import ch.systemsx.cisd.openbis.BuildAndEnvironmentInfo;
+import ch.systemsx.cisd.openbis.generic.server.CommonServiceProvider;
 import ch.systemsx.cisd.openbis.generic.shared.Constants;
 import ch.systemsx.cisd.openbis.generic.shared.IServer;
 
@@ -46,12 +48,6 @@ public class GetServerInformationOperationExecutor
         extends OperationExecutor<GetServerInformationOperation, GetServerInformationOperationResult>
         implements IGetServerInformationOperationExecutor
 {
-    @Autowired
-    private IApplicationServerInternalApi server;
-
-    @Resource(name = ApplicationServerApi.INTERNAL_SERVICE_NAME)
-    private IServer basicServer;
-
     @Resource(name = ExposablePropertyPlaceholderConfigurer.PROPERTY_CONFIGURER_BEAN_NAME)
     private ExposablePropertyPlaceholderConfigurer configurer;
 
@@ -70,9 +66,11 @@ public class GetServerInformationOperationExecutor
         Map<String, String> info = new TreeMap<>();
         info.putAll(getPublicInformation(context));
 
-        info.put("api-version", server.getMajorVersion() + "." + server.getMinorVersion());
-        info.put("project-samples-enabled", Boolean.toString(basicServer.isProjectSamplesEnabled(null)));
-        info.put("archiving-configured", Boolean.toString(basicServer.isArchivingConfigured(null)));
+        info.put("api-version",
+                CommonServiceProvider.getApplicationServerApi().getMajorVersion() + "." + CommonServiceProvider.getApplicationServerApi()
+                        .getMinorVersion());
+        info.put("project-samples-enabled", Boolean.toString(CommonServiceProvider.getCommonServer().isProjectSamplesEnabled(null)));
+        info.put("archiving-configured", Boolean.toString(CommonServiceProvider.getCommonServer().isArchivingConfigured(null)));
         info.put("enabled-technologies", configurer.getResolvedProps().getProperty(Constants.ENABLED_MODULES_KEY));
         info.put("create-continuous-sample-codes", configurer.getResolvedProps().getProperty(Constants.CREATE_CONTINUOUS_SAMPLES_CODES_KEY));
         info.put("openbis-version", BuildAndEnvironmentInfo.INSTANCE.getVersion());
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/pat/ApplicationServerApiPersonalAccessTokenDecorator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/pat/ApplicationServerApiPersonalAccessTokenDecorator.java
new file mode 100644
index 0000000000000000000000000000000000000000..0db34aacd44fecc40454cfec2d6868a65d4c8588
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/pat/ApplicationServerApiPersonalAccessTokenDecorator.java
@@ -0,0 +1,1214 @@
+package ch.ethz.sis.openbis.generic.server.asapi.v3.pat;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.AuthorizationGroup;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.create.AuthorizationGroupCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.delete.AuthorizationGroupDeletionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.fetchoptions.AuthorizationGroupFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.id.AuthorizationGroupPermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.id.IAuthorizationGroupId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.search.AuthorizationGroupSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.update.AuthorizationGroupUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.TableModel;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.IObjectId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.operation.IOperation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchResult;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSet;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSetType;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.archive.DataSetArchiveOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.create.DataSetCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.create.DataSetTypeCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.delete.DataSetDeletionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.delete.DataSetTypeDeletionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.fetchoptions.DataSetFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.fetchoptions.DataSetTypeFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.DataSetPermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.lock.DataSetLockOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.search.DataSetSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.search.DataSetTypeSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.unarchive.DataSetUnarchiveOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.unlock.DataSetUnlockOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.update.DataSetTypeUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.update.DataSetUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.datastore.DataStore;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.datastore.fetchoptions.DataStoreFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.datastore.search.DataStoreSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.deletion.Deletion;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.deletion.fetchoptions.DeletionFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.deletion.id.IDeletionId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.deletion.search.DeletionSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.EntityKind;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.id.EntityTypePermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.id.IEntityTypeId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.event.Event;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.event.fetchoptions.EventFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.event.search.EventSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.Experiment;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.ExperimentType;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.create.ExperimentCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.create.ExperimentTypeCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.delete.ExperimentDeletionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.delete.ExperimentTypeDeletionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.fetchoptions.ExperimentFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.fetchoptions.ExperimentTypeFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.ExperimentPermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.IExperimentId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.search.ExperimentSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.search.ExperimentTypeSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.update.ExperimentTypeUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.update.ExperimentUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.externaldms.ExternalDms;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.externaldms.create.ExternalDmsCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.externaldms.delete.ExternalDmsDeletionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.externaldms.fetchoptions.ExternalDmsFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.externaldms.id.ExternalDmsPermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.externaldms.id.IExternalDmsId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.externaldms.search.ExternalDmsSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.externaldms.update.ExternalDmsUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.GlobalSearchObject;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.fetchoptions.GlobalSearchObjectFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.search.GlobalSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.Material;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.MaterialType;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.create.MaterialCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.create.MaterialTypeCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.delete.MaterialDeletionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.delete.MaterialTypeDeletionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.fetchoptions.MaterialFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.fetchoptions.MaterialTypeFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.id.IMaterialId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.id.MaterialPermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.search.MaterialSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.search.MaterialTypeSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.update.MaterialTypeUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.update.MaterialUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.objectkindmodification.ObjectKindModification;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.objectkindmodification.fetchoptions.ObjectKindModificationFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.objectkindmodification.search.ObjectKindModificationSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.operation.IOperationExecutionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.operation.IOperationExecutionResults;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.operation.OperationExecution;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.operation.delete.OperationExecutionDeletionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.operation.fetchoptions.OperationExecutionFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.operation.id.IOperationExecutionId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.operation.search.OperationExecutionSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.operation.update.OperationExecutionUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.Person;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.create.PersonCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.delete.PersonDeletionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.fetchoptions.PersonFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.id.IPersonId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.id.PersonPermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.search.PersonSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.update.PersonUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.plugin.Plugin;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.plugin.create.PluginCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.plugin.delete.PluginDeletionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.plugin.evaluate.PluginEvaluationOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.plugin.evaluate.PluginEvaluationResult;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.plugin.fetchoptions.PluginFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.plugin.id.IPluginId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.plugin.id.PluginPermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.plugin.search.PluginSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.plugin.update.PluginUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.Project;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.create.ProjectCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.delete.ProjectDeletionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.fetchoptions.ProjectFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.id.IProjectId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.id.ProjectPermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.search.ProjectSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.update.ProjectUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.PropertyAssignment;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.PropertyType;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.create.PropertyTypeCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.delete.PropertyTypeDeletionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.fetchoptions.PropertyAssignmentFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.fetchoptions.PropertyTypeFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.id.IPropertyTypeId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.id.PropertyTypePermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.search.PropertyAssignmentSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.search.PropertyTypeSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.update.PropertyTypeUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.query.Query;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.query.QueryDatabase;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.query.create.QueryCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.query.delete.QueryDeletionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.query.execute.QueryExecutionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.query.execute.SqlExecutionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.query.fetchoptions.QueryDatabaseFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.query.fetchoptions.QueryFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.query.id.IQueryDatabaseId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.query.id.IQueryId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.query.id.QueryTechId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.query.search.QueryDatabaseSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.query.search.QuerySearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.query.update.QueryUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.rights.Rights;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.rights.fetchoptions.RightsFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.RoleAssignment;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.create.RoleAssignmentCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.delete.RoleAssignmentDeletionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.fetchoptions.RoleAssignmentFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.id.IRoleAssignmentId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.id.RoleAssignmentTechId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.search.RoleAssignmentSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.Sample;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.SampleType;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.create.SampleCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.create.SampleTypeCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.delete.SampleDeletionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.delete.SampleTypeDeletionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.fetchoptions.SampleFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.fetchoptions.SampleTypeFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.ISampleId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.SamplePermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.search.SampleSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.search.SampleTypeSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.update.SampleTypeUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.update.SampleUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.semanticannotation.SemanticAnnotation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.semanticannotation.create.SemanticAnnotationCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.semanticannotation.delete.SemanticAnnotationDeletionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.semanticannotation.fetchoptions.SemanticAnnotationFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.semanticannotation.id.ISemanticAnnotationId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.semanticannotation.id.SemanticAnnotationPermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.semanticannotation.search.SemanticAnnotationSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.semanticannotation.update.SemanticAnnotationUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.AggregationService;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.CustomASService;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.CustomASServiceExecutionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.ProcessingService;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.ReportingService;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.SearchDomainService;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.SearchDomainServiceExecutionResult;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.execute.AggregationServiceExecutionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.execute.ProcessingServiceExecutionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.execute.ReportingServiceExecutionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.execute.SearchDomainServiceExecutionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.fetchoptions.AggregationServiceFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.fetchoptions.CustomASServiceFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.fetchoptions.ProcessingServiceFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.fetchoptions.ReportingServiceFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.fetchoptions.SearchDomainServiceFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.id.ICustomASServiceId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.id.IDssServiceId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.search.AggregationServiceSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.search.CustomASServiceSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.search.ProcessingServiceSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.search.ReportingServiceSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.search.SearchDomainServiceSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.session.SessionInformation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.Space;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.create.SpaceCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.delete.SpaceDeletionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.fetchoptions.SpaceFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.ISpaceId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.SpacePermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.search.SpaceSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.update.SpaceUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.Tag;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.create.TagCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.delete.TagDeletionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.fetchoptions.TagFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.ITagId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.TagPermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.search.TagSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.update.TagUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.Vocabulary;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.VocabularyTerm;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyTermCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.delete.VocabularyDeletionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.delete.VocabularyTermDeletionOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions.VocabularyFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions.VocabularyTermFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.IVocabularyId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.IVocabularyTermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyPermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyTermPermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.search.VocabularySearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.search.VocabularyTermSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.update.VocabularyTermUpdate;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.update.VocabularyUpdate;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.IApplicationServerInternalApi;
+import ch.systemsx.cisd.authentication.pat.IPersonalAccessTokenDAO;
+import ch.systemsx.cisd.authentication.pat.PersonalAccessToken;
+import ch.systemsx.cisd.authentication.pat.PersonalAccessTokenSession;
+import ch.systemsx.cisd.common.exceptions.InvalidSessionException;
+import ch.systemsx.cisd.openbis.generic.server.CommonServiceProvider;
+
+public class ApplicationServerApiPersonalAccessTokenDecorator implements IApplicationServerInternalApi
+{
+
+    private final IApplicationServerInternalApi applicationServerApi;
+
+    public ApplicationServerApiPersonalAccessTokenDecorator(IApplicationServerInternalApi applicationServerApi)
+    {
+        this.applicationServerApi = applicationServerApi;
+    }
+
+    @Override public int getMajorVersion()
+    {
+        return applicationServerApi.getMajorVersion();
+    }
+
+    @Override public int getMinorVersion()
+    {
+        return applicationServerApi.getMinorVersion();
+    }
+
+    @Override public String login(final String userId, final String password)
+    {
+        return applicationServerApi.login(userId, password);
+    }
+
+    @Override public String loginAs(final String userId, final String password, final String asUserId)
+    {
+        return applicationServerApi.loginAs(userId, password, asUserId);
+    }
+
+    @Override public String loginAsSystem()
+    {
+        return applicationServerApi.loginAsSystem();
+    }
+
+    @Override public void registerUser(final String sessionTokenOrPAT)
+    {
+        // do not convert pat token
+        applicationServerApi.registerUser(sessionTokenOrPAT);
+    }
+
+    @Override public String loginAsAnonymousUser()
+    {
+        return applicationServerApi.loginAsAnonymousUser();
+    }
+
+    @Override public void logout(final String sessionTokenOrPAT)
+    {
+        // do not convert pat token
+        applicationServerApi.logout(sessionTokenOrPAT);
+    }
+
+    @Override public SessionInformation getSessionInformation(final String sessionTokenOrPAT)
+    {
+        return applicationServerApi.getSessionInformation(toSessionToken(sessionTokenOrPAT));
+    }
+
+    @Override public boolean isSessionActive(final String sessionTokenOrPAT)
+    {
+        return applicationServerApi.isSessionActive(toSessionToken(sessionTokenOrPAT));
+    }
+
+    @Override public List<SpacePermId> createSpaces(final String sessionTokenOrPAT, final List<SpaceCreation> newSpaces)
+    {
+        return createSpaces(toSessionToken(sessionTokenOrPAT), newSpaces);
+    }
+
+    @Override public List<ProjectPermId> createProjects(final String sessionTokenOrPAT, final List<ProjectCreation> newProjects)
+    {
+        return createProjects(toSessionToken(sessionTokenOrPAT), newProjects);
+    }
+
+    @Override public List<ExperimentPermId> createExperiments(final String sessionTokenOrPAT, final List<ExperimentCreation> newExperiments)
+    {
+        return createExperiments(toSessionToken(sessionTokenOrPAT), newExperiments);
+    }
+
+    @Override public List<EntityTypePermId> createExperimentTypes(final String sessionTokenOrPAT,
+            final List<ExperimentTypeCreation> newExperimentTypes)
+    {
+        return createExperimentTypes(toSessionToken(sessionTokenOrPAT), newExperimentTypes);
+    }
+
+    @Override public List<SamplePermId> createSamples(final String sessionTokenOrPAT,
+            final List<SampleCreation> newSamples)
+    {
+        return applicationServerApi.createSamples(toSessionToken(sessionTokenOrPAT), newSamples);
+    }
+
+    @Override public List<EntityTypePermId> createSampleTypes(final String sessionTokenOrPAT,
+            final List<SampleTypeCreation> newSampleTypes)
+    {
+        return applicationServerApi.createSampleTypes(toSessionToken(sessionTokenOrPAT), newSampleTypes);
+    }
+
+    @Override public List<DataSetPermId> createDataSets(final String sessionTokenOrPAT,
+            final List<DataSetCreation> newDataSets)
+    {
+        return applicationServerApi.createDataSets(toSessionToken(sessionTokenOrPAT), newDataSets);
+    }
+
+    @Override public List<EntityTypePermId> createDataSetTypes(final String sessionTokenOrPAT,
+            final List<DataSetTypeCreation> newDataSetTypes)
+    {
+        return applicationServerApi.createDataSetTypes(toSessionToken(sessionTokenOrPAT), newDataSetTypes);
+    }
+
+    @Override public List<MaterialPermId> createMaterials(final String sessionTokenOrPAT,
+            final List<MaterialCreation> newMaterials)
+    {
+        return applicationServerApi.createMaterials(toSessionToken(sessionTokenOrPAT), newMaterials);
+    }
+
+    @Override public List<EntityTypePermId> createMaterialTypes(final String sessionTokenOrPAT,
+            final List<MaterialTypeCreation> newMaterialTypes)
+    {
+        return applicationServerApi.createMaterialTypes(toSessionToken(sessionTokenOrPAT), newMaterialTypes);
+    }
+
+    @Override public List<PropertyTypePermId> createPropertyTypes(final String sessionTokenOrPAT,
+            final List<PropertyTypeCreation> newPropertyTypes)
+    {
+        return applicationServerApi.createPropertyTypes(toSessionToken(sessionTokenOrPAT), newPropertyTypes);
+    }
+
+    @Override public List<PluginPermId> createPlugins(final String sessionTokenOrPAT,
+            final List<PluginCreation> newPlugins)
+    {
+        return applicationServerApi.createPlugins(toSessionToken(sessionTokenOrPAT), newPlugins);
+    }
+
+    @Override public List<VocabularyPermId> createVocabularies(final String sessionTokenOrPAT,
+            final List<VocabularyCreation> newVocabularies)
+    {
+        return applicationServerApi.createVocabularies(toSessionToken(sessionTokenOrPAT), newVocabularies);
+    }
+
+    @Override public List<VocabularyTermPermId> createVocabularyTerms(final String sessionTokenOrPAT,
+            final List<VocabularyTermCreation> newVocabularyTerms)
+    {
+        return applicationServerApi.createVocabularyTerms(toSessionToken(sessionTokenOrPAT), newVocabularyTerms);
+    }
+
+    @Override public List<TagPermId> createTags(final String sessionTokenOrPAT, final List<TagCreation> newTags)
+    {
+        return applicationServerApi.createTags(toSessionToken(sessionTokenOrPAT), newTags);
+    }
+
+    @Override public List<AuthorizationGroupPermId> createAuthorizationGroups(final String sessionTokenOrPAT,
+            final List<AuthorizationGroupCreation> newAuthorizationGroups)
+    {
+        return applicationServerApi.createAuthorizationGroups(toSessionToken(sessionTokenOrPAT), newAuthorizationGroups);
+    }
+
+    @Override public List<RoleAssignmentTechId> createRoleAssignments(final String sessionTokenOrPAT,
+            final List<RoleAssignmentCreation> newRoleAssignments)
+    {
+        return applicationServerApi.createRoleAssignments(toSessionToken(sessionTokenOrPAT), newRoleAssignments);
+    }
+
+    @Override public List<PersonPermId> createPersons(final String sessionTokenOrPAT,
+            final List<PersonCreation> newPersons)
+    {
+        return applicationServerApi.createPersons(toSessionToken(sessionTokenOrPAT), newPersons);
+    }
+
+    @Override public List<ExternalDmsPermId> createExternalDataManagementSystems(final String sessionTokenOrPAT,
+            final List<ExternalDmsCreation> newExternalDataManagementSystems)
+    {
+        return applicationServerApi.createExternalDataManagementSystems(toSessionToken(sessionTokenOrPAT), newExternalDataManagementSystems);
+    }
+
+    @Override public List<QueryTechId> createQueries(final String sessionTokenOrPAT,
+            final List<QueryCreation> newQueries)
+    {
+        return applicationServerApi.createQueries(toSessionToken(sessionTokenOrPAT), newQueries);
+    }
+
+    @Override public List<SemanticAnnotationPermId> createSemanticAnnotations(final String sessionTokenOrPAT,
+            final List<SemanticAnnotationCreation> newAnnotations)
+    {
+        return applicationServerApi.createSemanticAnnotations(toSessionToken(sessionTokenOrPAT), newAnnotations);
+    }
+
+    @Override public void updateSpaces(final String sessionTokenOrPAT, final List<SpaceUpdate> spaceUpdates)
+    {
+        applicationServerApi.updateSpaces(toSessionToken(sessionTokenOrPAT), spaceUpdates);
+    }
+
+    @Override public void updateProjects(final String sessionTokenOrPAT, final List<ProjectUpdate> projectUpdates)
+    {
+        applicationServerApi.updateProjects(toSessionToken(sessionTokenOrPAT), projectUpdates);
+    }
+
+    @Override public void updateExperiments(final String sessionTokenOrPAT,
+            final List<ExperimentUpdate> experimentUpdates)
+    {
+        applicationServerApi.updateExperiments(toSessionToken(sessionTokenOrPAT), experimentUpdates);
+    }
+
+    @Override public void updateExperimentTypes(final String sessionTokenOrPAT,
+            final List<ExperimentTypeUpdate> experimentTypeUpdates)
+    {
+        applicationServerApi.updateExperimentTypes(toSessionToken(sessionTokenOrPAT), experimentTypeUpdates);
+    }
+
+    @Override public void updateSamples(final String sessionTokenOrPAT, final List<SampleUpdate> sampleUpdates)
+    {
+        applicationServerApi.updateSamples(toSessionToken(sessionTokenOrPAT), sampleUpdates);
+    }
+
+    @Override public void updateSampleTypes(final String sessionTokenOrPAT,
+            final List<SampleTypeUpdate> sampleTypeUpdates)
+    {
+        applicationServerApi.updateSampleTypes(toSessionToken(sessionTokenOrPAT), sampleTypeUpdates);
+    }
+
+    @Override public void updateDataSets(final String sessionTokenOrPAT, final List<DataSetUpdate> dataSetUpdates)
+    {
+        applicationServerApi.updateDataSets(toSessionToken(sessionTokenOrPAT), dataSetUpdates);
+    }
+
+    @Override public void updateDataSetTypes(final String sessionTokenOrPAT,
+            final List<DataSetTypeUpdate> dataSetTypeUpdates)
+    {
+        applicationServerApi.updateDataSetTypes(toSessionToken(sessionTokenOrPAT), dataSetTypeUpdates);
+    }
+
+    @Override public void updateMaterials(final String sessionTokenOrPAT,
+            final List<MaterialUpdate> materialUpdates)
+    {
+        applicationServerApi.updateMaterials(toSessionToken(sessionTokenOrPAT), materialUpdates);
+    }
+
+    @Override public void updateMaterialTypes(final String sessionTokenOrPAT,
+            final List<MaterialTypeUpdate> materialTypeUpdates)
+    {
+        applicationServerApi.updateMaterialTypes(toSessionToken(sessionTokenOrPAT), materialTypeUpdates);
+    }
+
+    @Override public void updateExternalDataManagementSystems(final String sessionTokenOrPAT,
+            final List<ExternalDmsUpdate> externalDmsUpdates)
+    {
+        applicationServerApi.updateExternalDataManagementSystems(toSessionToken(sessionTokenOrPAT), externalDmsUpdates);
+    }
+
+    @Override public void updatePropertyTypes(final String sessionTokenOrPAT,
+            final List<PropertyTypeUpdate> propertyTypeUpdates)
+    {
+        applicationServerApi.updatePropertyTypes(toSessionToken(sessionTokenOrPAT), propertyTypeUpdates);
+    }
+
+    @Override public void updatePlugins(final String sessionTokenOrPAT, final List<PluginUpdate> pluginUpdates)
+    {
+        applicationServerApi.updatePlugins(toSessionToken(sessionTokenOrPAT), pluginUpdates);
+    }
+
+    @Override public void updateVocabularies(final String sessionTokenOrPAT,
+            final List<VocabularyUpdate> vocabularyUpdates)
+    {
+        applicationServerApi.updateVocabularies(toSessionToken(sessionTokenOrPAT), vocabularyUpdates);
+    }
+
+    @Override public void updateVocabularyTerms(final String sessionTokenOrPAT,
+            final List<VocabularyTermUpdate> vocabularyTermUpdates)
+    {
+        applicationServerApi.updateVocabularyTerms(toSessionToken(sessionTokenOrPAT), vocabularyTermUpdates);
+    }
+
+    @Override public void updateTags(final String sessionTokenOrPAT, final List<TagUpdate> tagUpdates)
+    {
+        applicationServerApi.updateTags(toSessionToken(sessionTokenOrPAT), tagUpdates);
+    }
+
+    @Override public void updateAuthorizationGroups(final String sessionTokenOrPAT,
+            final List<AuthorizationGroupUpdate> authorizationGroupUpdates)
+    {
+        applicationServerApi.updateAuthorizationGroups(toSessionToken(sessionTokenOrPAT), authorizationGroupUpdates);
+    }
+
+    @Override public void updatePersons(final String sessionTokenOrPAT, final List<PersonUpdate> personUpdates)
+    {
+        applicationServerApi.updatePersons(toSessionToken(sessionTokenOrPAT), personUpdates);
+    }
+
+    @Override public void updateOperationExecutions(final String sessionTokenOrPAT,
+            final List<OperationExecutionUpdate> executionUpdates)
+    {
+        applicationServerApi.updateOperationExecutions(toSessionToken(sessionTokenOrPAT), executionUpdates);
+    }
+
+    @Override public void updateSemanticAnnotations(final String sessionTokenOrPAT,
+            final List<SemanticAnnotationUpdate> annotationUpdates)
+    {
+        applicationServerApi.updateSemanticAnnotations(toSessionToken(sessionTokenOrPAT), annotationUpdates);
+    }
+
+    @Override public void updateQueries(final String sessionTokenOrPAT, final List<QueryUpdate> queryUpdates)
+    {
+        applicationServerApi.updateQueries(toSessionToken(sessionTokenOrPAT), queryUpdates);
+    }
+
+    @Override public Map<IObjectId, Rights> getRights(final String sessionTokenOrPAT,
+            final List<? extends IObjectId> ids, final RightsFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getRights(toSessionToken(sessionTokenOrPAT), ids, fetchOptions);
+    }
+
+    @Override public Map<ISpaceId, Space> getSpaces(final String sessionTokenOrPAT,
+            final List<? extends ISpaceId> spaceIds, final SpaceFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getSpaces(toSessionToken(sessionTokenOrPAT), spaceIds, fetchOptions);
+    }
+
+    @Override public Map<IProjectId, Project> getProjects(final String sessionTokenOrPAT,
+            final List<? extends IProjectId> projectIds, final ProjectFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getProjects(toSessionToken(sessionTokenOrPAT), projectIds, fetchOptions);
+    }
+
+    @Override public Map<IExperimentId, Experiment> getExperiments(final String sessionTokenOrPAT,
+            final List<? extends IExperimentId> experimentIds,
+            final ExperimentFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getExperiments(toSessionToken(sessionTokenOrPAT), experimentIds, fetchOptions);
+    }
+
+    @Override public Map<IEntityTypeId, ExperimentType> getExperimentTypes(final String sessionTokenOrPAT,
+            final List<? extends IEntityTypeId> experimentTypeIds,
+            final ExperimentTypeFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getExperimentTypes(toSessionToken(sessionTokenOrPAT), experimentTypeIds, fetchOptions);
+    }
+
+    @Override public Map<ISampleId, Sample> getSamples(final String sessionTokenOrPAT,
+            final List<? extends ISampleId> sampleIds, final SampleFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getSamples(toSessionToken(sessionTokenOrPAT), sampleIds, fetchOptions);
+    }
+
+    @Override public Map<IEntityTypeId, SampleType> getSampleTypes(final String sessionTokenOrPAT,
+            final List<? extends IEntityTypeId> sampleTypeIds, final SampleTypeFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getSampleTypes(toSessionToken(sessionTokenOrPAT), sampleTypeIds, fetchOptions);
+    }
+
+    @Override public Map<IDataSetId, DataSet> getDataSets(final String sessionTokenOrPAT,
+            final List<? extends IDataSetId> dataSetIds, final DataSetFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getDataSets(toSessionToken(sessionTokenOrPAT), dataSetIds, fetchOptions);
+    }
+
+    @Override public Map<IEntityTypeId, DataSetType> getDataSetTypes(final String sessionTokenOrPAT,
+            final List<? extends IEntityTypeId> dataSetTypeIds,
+            final DataSetTypeFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getDataSetTypes(toSessionToken(sessionTokenOrPAT), dataSetTypeIds, fetchOptions);
+    }
+
+    @Override public Map<IMaterialId, Material> getMaterials(final String sessionTokenOrPAT,
+            final List<? extends IMaterialId> materialIds, final MaterialFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getMaterials(toSessionToken(sessionTokenOrPAT), materialIds, fetchOptions);
+    }
+
+    @Override public Map<IEntityTypeId, MaterialType> getMaterialTypes(final String sessionTokenOrPAT,
+            final List<? extends IEntityTypeId> materialTypeIds,
+            final MaterialTypeFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getMaterialTypes(toSessionToken(sessionTokenOrPAT), materialTypeIds, fetchOptions);
+    }
+
+    @Override public Map<IPropertyTypeId, PropertyType> getPropertyTypes(final String sessionTokenOrPAT,
+            final List<? extends IPropertyTypeId> typeIds, final PropertyTypeFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getPropertyTypes(toSessionToken(sessionTokenOrPAT), typeIds, fetchOptions);
+    }
+
+    @Override public Map<IPluginId, Plugin> getPlugins(final String sessionTokenOrPAT,
+            final List<? extends IPluginId> pluginIds, final PluginFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getPlugins(toSessionToken(sessionTokenOrPAT), pluginIds, fetchOptions);
+    }
+
+    @Override public Map<IVocabularyId, Vocabulary> getVocabularies(final String sessionTokenOrPAT,
+            final List<? extends IVocabularyId> vocabularyIds,
+            final VocabularyFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getVocabularies(toSessionToken(sessionTokenOrPAT), vocabularyIds, fetchOptions);
+    }
+
+    @Override public Map<IVocabularyTermId, VocabularyTerm> getVocabularyTerms(final String sessionTokenOrPAT,
+            final List<? extends IVocabularyTermId> vocabularyTermIds,
+            final VocabularyTermFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getVocabularyTerms(toSessionToken(sessionTokenOrPAT), vocabularyTermIds, fetchOptions);
+    }
+
+    @Override public Map<ITagId, Tag> getTags(final String sessionTokenOrPAT, final List<? extends ITagId> tagIds,
+            final TagFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getTags(toSessionToken(sessionTokenOrPAT), tagIds, fetchOptions);
+    }
+
+    @Override public Map<IAuthorizationGroupId, AuthorizationGroup> getAuthorizationGroups(final String sessionTokenOrPAT,
+            final List<? extends IAuthorizationGroupId> groupIds,
+            final AuthorizationGroupFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getAuthorizationGroups(toSessionToken(sessionTokenOrPAT), groupIds, fetchOptions);
+    }
+
+    @Override public Map<IRoleAssignmentId, RoleAssignment> getRoleAssignments(final String sessionTokenOrPAT,
+            final List<? extends IRoleAssignmentId> ids,
+            final RoleAssignmentFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getRoleAssignments(toSessionToken(sessionTokenOrPAT), ids, fetchOptions);
+    }
+
+    @Override public Map<IPersonId, Person> getPersons(final String sessionTokenOrPAT,
+            final List<? extends IPersonId> ids, final PersonFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getPersons(toSessionToken(sessionTokenOrPAT), ids, fetchOptions);
+    }
+
+    @Override public Map<IExternalDmsId, ExternalDms> getExternalDataManagementSystems(final String sessionTokenOrPAT,
+            final List<? extends IExternalDmsId> externalDmsIds,
+            final ExternalDmsFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getExternalDataManagementSystems(toSessionToken(sessionTokenOrPAT), externalDmsIds, fetchOptions);
+    }
+
+    @Override public Map<ISemanticAnnotationId, SemanticAnnotation> getSemanticAnnotations(final String sessionTokenOrPAT,
+            final List<? extends ISemanticAnnotationId> annotationIds,
+            final SemanticAnnotationFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getSemanticAnnotations(toSessionToken(sessionTokenOrPAT), annotationIds, fetchOptions);
+    }
+
+    @Override public Map<IOperationExecutionId, OperationExecution> getOperationExecutions(final String sessionTokenOrPAT,
+            final List<? extends IOperationExecutionId> executionIds,
+            final OperationExecutionFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getOperationExecutions(toSessionToken(sessionTokenOrPAT), executionIds, fetchOptions);
+    }
+
+    @Override public Map<IQueryId, Query> getQueries(final String sessionTokenOrPAT,
+            final List<? extends IQueryId> queryIds, final QueryFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getQueries(toSessionToken(sessionTokenOrPAT), queryIds, fetchOptions);
+    }
+
+    @Override public Map<IQueryDatabaseId, QueryDatabase> getQueryDatabases(final String sessionTokenOrPAT,
+            final List<? extends IQueryDatabaseId> queryDatabaseIds,
+            final QueryDatabaseFetchOptions fetchOptions)
+    {
+        return applicationServerApi.getQueryDatabases(toSessionToken(sessionTokenOrPAT), queryDatabaseIds, fetchOptions);
+    }
+
+    @Override public SearchResult<Space> searchSpaces(final String sessionTokenOrPAT, final SpaceSearchCriteria searchCriteria,
+            final SpaceFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchSpaces(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<Project> searchProjects(final String sessionTokenOrPAT,
+            final ProjectSearchCriteria searchCriteria, final ProjectFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchProjects(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<Experiment> searchExperiments(final String sessionTokenOrPAT,
+            final ExperimentSearchCriteria searchCriteria, final ExperimentFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchExperiments(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<ExperimentType> searchExperimentTypes(final String sessionTokenOrPAT,
+            final ExperimentTypeSearchCriteria searchCriteria,
+            final ExperimentTypeFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchExperimentTypes(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<Sample> searchSamples(final String sessionTokenOrPAT,
+            final SampleSearchCriteria searchCriteria, final SampleFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchSamples(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<SampleType> searchSampleTypes(final String sessionTokenOrPAT,
+            final SampleTypeSearchCriteria searchCriteria, final SampleTypeFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchSampleTypes(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<DataSet> searchDataSets(final String sessionTokenOrPAT,
+            final DataSetSearchCriteria searchCriteria, final DataSetFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchDataSets(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<DataSetType> searchDataSetTypes(final String sessionTokenOrPAT,
+            final DataSetTypeSearchCriteria searchCriteria, final DataSetTypeFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchDataSetTypes(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<Material> searchMaterials(final String sessionTokenOrPAT,
+            final MaterialSearchCriteria searchCriteria, final MaterialFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchMaterials(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<ExternalDms> searchExternalDataManagementSystems(final String sessionTokenOrPAT,
+            final ExternalDmsSearchCriteria searchCriteria,
+            final ExternalDmsFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchExternalDataManagementSystems(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<MaterialType> searchMaterialTypes(final String sessionTokenOrPAT,
+            final MaterialTypeSearchCriteria searchCriteria,
+            final MaterialTypeFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchMaterialTypes(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<Plugin> searchPlugins(final String sessionTokenOrPAT,
+            final PluginSearchCriteria searchCriteria, final PluginFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchPlugins(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<Vocabulary> searchVocabularies(final String sessionTokenOrPAT,
+            final VocabularySearchCriteria searchCriteria, final VocabularyFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchVocabularies(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<VocabularyTerm> searchVocabularyTerms(final String sessionTokenOrPAT,
+            final VocabularyTermSearchCriteria searchCriteria,
+            final VocabularyTermFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchVocabularyTerms(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<Tag> searchTags(final String sessionTokenOrPAT, final TagSearchCriteria searchCriteria,
+            final TagFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchTags(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<AuthorizationGroup> searchAuthorizationGroups(final String sessionTokenOrPAT,
+            final AuthorizationGroupSearchCriteria searchCriteria,
+            final AuthorizationGroupFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchAuthorizationGroups(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<RoleAssignment> searchRoleAssignments(final String sessionTokenOrPAT,
+            final RoleAssignmentSearchCriteria searchCriteria,
+            final RoleAssignmentFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchRoleAssignments(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<Person> searchPersons(final String sessionTokenOrPAT,
+            final PersonSearchCriteria searchCriteria, final PersonFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchPersons(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<CustomASService> searchCustomASServices(final String sessionTokenOrPAT,
+            final CustomASServiceSearchCriteria searchCriteria,
+            final CustomASServiceFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchCustomASServices(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<SearchDomainService> searchSearchDomainServices(final String sessionTokenOrPAT,
+            final SearchDomainServiceSearchCriteria searchCriteria,
+            final SearchDomainServiceFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchSearchDomainServices(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<AggregationService> searchAggregationServices(final String sessionTokenOrPAT,
+            final AggregationServiceSearchCriteria searchCriteria,
+            final AggregationServiceFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchAggregationServices(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<ReportingService> searchReportingServices(final String sessionTokenOrPAT,
+            final ReportingServiceSearchCriteria searchCriteria,
+            final ReportingServiceFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchReportingServices(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<ProcessingService> searchProcessingServices(final String sessionTokenOrPAT,
+            final ProcessingServiceSearchCriteria searchCriteria,
+            final ProcessingServiceFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchProcessingServices(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<ObjectKindModification> searchObjectKindModifications(final String sessionTokenOrPAT,
+            final ObjectKindModificationSearchCriteria searchCriteria,
+            final ObjectKindModificationFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchObjectKindModifications(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<GlobalSearchObject> searchGlobally(final String sessionTokenOrPAT,
+            final GlobalSearchCriteria searchCriteria, final GlobalSearchObjectFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchGlobally(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<OperationExecution> searchOperationExecutions(final String sessionTokenOrPAT,
+            final OperationExecutionSearchCriteria searchCriteria,
+            final OperationExecutionFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchOperationExecutions(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<DataStore> searchDataStores(final String sessionTokenOrPAT,
+            final DataStoreSearchCriteria searchCriteria, final DataStoreFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchDataStores(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<SemanticAnnotation> searchSemanticAnnotations(final String sessionTokenOrPAT,
+            final SemanticAnnotationSearchCriteria searchCriteria,
+            final SemanticAnnotationFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchSemanticAnnotations(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<PropertyType> searchPropertyTypes(final String sessionTokenOrPAT,
+            final PropertyTypeSearchCriteria searchCriteria,
+            final PropertyTypeFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchPropertyTypes(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<PropertyAssignment> searchPropertyAssignments(final String sessionTokenOrPAT,
+            final PropertyAssignmentSearchCriteria searchCriteria,
+            final PropertyAssignmentFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchPropertyAssignments(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<Query> searchQueries(final String sessionTokenOrPAT,
+            final QuerySearchCriteria searchCriteria, final QueryFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchQueries(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<QueryDatabase> searchQueryDatabases(final String sessionTokenOrPAT,
+            final QueryDatabaseSearchCriteria searchCriteria,
+            final QueryDatabaseFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchQueryDatabases(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public void deleteSpaces(final String sessionTokenOrPAT, final List<? extends ISpaceId> spaceIds,
+            final SpaceDeletionOptions deletionOptions)
+    {
+        applicationServerApi.deleteSpaces(toSessionToken(sessionTokenOrPAT), spaceIds, deletionOptions);
+    }
+
+    @Override public void deleteProjects(final String sessionTokenOrPAT, final List<? extends IProjectId> projectIds,
+            final ProjectDeletionOptions deletionOptions)
+    {
+        applicationServerApi.deleteProjects(toSessionToken(sessionTokenOrPAT), projectIds, deletionOptions);
+    }
+
+    @Override public IDeletionId deleteExperiments(final String sessionTokenOrPAT,
+            final List<? extends IExperimentId> experimentIds,
+            final ExperimentDeletionOptions deletionOptions)
+    {
+        return applicationServerApi.deleteExperiments(toSessionToken(sessionTokenOrPAT), experimentIds, deletionOptions);
+    }
+
+    @Override public IDeletionId deleteSamples(final String sessionTokenOrPAT,
+            final List<? extends ISampleId> sampleIds, final SampleDeletionOptions deletionOptions)
+    {
+        return applicationServerApi.deleteSamples(toSessionToken(sessionTokenOrPAT), sampleIds, deletionOptions);
+    }
+
+    @Override public IDeletionId deleteDataSets(final String sessionTokenOrPAT,
+            final List<? extends IDataSetId> dataSetIds, final DataSetDeletionOptions deletionOptions)
+    {
+        return applicationServerApi.deleteDataSets(toSessionToken(sessionTokenOrPAT), dataSetIds, deletionOptions);
+    }
+
+    @Override public void deleteMaterials(final String sessionTokenOrPAT,
+            final List<? extends IMaterialId> materialIds, final MaterialDeletionOptions deletionOptions)
+    {
+        applicationServerApi.deleteMaterials(toSessionToken(sessionTokenOrPAT), materialIds, deletionOptions);
+    }
+
+    @Override public void deletePlugins(final String sessionTokenOrPAT, final List<? extends IPluginId> pluginIds,
+            final PluginDeletionOptions deletionOptions)
+    {
+        applicationServerApi.deletePlugins(toSessionToken(sessionTokenOrPAT), pluginIds, deletionOptions);
+    }
+
+    @Override public void deletePropertyTypes(final String sessionTokenOrPAT,
+            final List<? extends IPropertyTypeId> propertyTypeIds,
+            final PropertyTypeDeletionOptions deletionOptions)
+    {
+        applicationServerApi.deletePropertyTypes(toSessionToken(sessionTokenOrPAT), propertyTypeIds, deletionOptions);
+    }
+
+    @Override public void deleteVocabularies(final String sessionTokenOrPAT,
+            final List<? extends IVocabularyId> ids, final VocabularyDeletionOptions deletionOptions)
+    {
+        applicationServerApi.deleteVocabularies(toSessionToken(sessionTokenOrPAT), ids, deletionOptions);
+    }
+
+    @Override public void deleteVocabularyTerms(final String sessionTokenOrPAT,
+            final List<? extends IVocabularyTermId> termIds,
+            final VocabularyTermDeletionOptions deletionOptions)
+    {
+        applicationServerApi.deleteVocabularyTerms(toSessionToken(sessionTokenOrPAT), termIds, deletionOptions);
+    }
+
+    @Override public void deleteExperimentTypes(final String sessionTokenOrPAT,
+            final List<? extends IEntityTypeId> experimentTypeIds,
+            final ExperimentTypeDeletionOptions deletionOptions)
+    {
+        applicationServerApi.deleteExperimentTypes(toSessionToken(sessionTokenOrPAT), experimentTypeIds, deletionOptions);
+    }
+
+    @Override public void deleteSampleTypes(final String sessionTokenOrPAT,
+            final List<? extends IEntityTypeId> sampleTypeIds, final SampleTypeDeletionOptions deletionOptions)
+    {
+        applicationServerApi.deleteSampleTypes(toSessionToken(sessionTokenOrPAT), sampleTypeIds, deletionOptions);
+    }
+
+    @Override public void deleteDataSetTypes(final String sessionTokenOrPAT,
+            final List<? extends IEntityTypeId> dataSetTypeIds,
+            final DataSetTypeDeletionOptions deletionOptions)
+    {
+        applicationServerApi.deleteDataSetTypes(toSessionToken(sessionTokenOrPAT), dataSetTypeIds, deletionOptions);
+    }
+
+    @Override public void deleteMaterialTypes(final String sessionTokenOrPAT,
+            final List<? extends IEntityTypeId> materialTypeIds,
+            final MaterialTypeDeletionOptions deletionOptions)
+    {
+        applicationServerApi.deleteMaterialTypes(toSessionToken(sessionTokenOrPAT), materialTypeIds, deletionOptions);
+    }
+
+    @Override public void deleteExternalDataManagementSystems(final String sessionTokenOrPAT,
+            final List<? extends IExternalDmsId> externalDmsIds,
+            final ExternalDmsDeletionOptions deletionOptions)
+    {
+        applicationServerApi.deleteExternalDataManagementSystems(toSessionToken(sessionTokenOrPAT), externalDmsIds, deletionOptions);
+    }
+
+    @Override public void deleteTags(final String sessionTokenOrPAT, final List<? extends ITagId> tagIds,
+            final TagDeletionOptions deletionOptions)
+    {
+        applicationServerApi.deleteTags(toSessionToken(sessionTokenOrPAT), tagIds, deletionOptions);
+    }
+
+    @Override public void deleteAuthorizationGroups(final String sessionTokenOrPAT,
+            final List<? extends IAuthorizationGroupId> groupIds,
+            final AuthorizationGroupDeletionOptions deletionOptions)
+    {
+        applicationServerApi.deleteAuthorizationGroups(toSessionToken(sessionTokenOrPAT), groupIds, deletionOptions);
+    }
+
+    @Override public void deleteRoleAssignments(final String sessionTokenOrPAT,
+            final List<? extends IRoleAssignmentId> assignmentIds,
+            final RoleAssignmentDeletionOptions deletionOptions)
+    {
+        applicationServerApi.deleteRoleAssignments(toSessionToken(sessionTokenOrPAT), assignmentIds, deletionOptions);
+    }
+
+    @Override public void deleteOperationExecutions(final String sessionTokenOrPAT,
+            final List<? extends IOperationExecutionId> executionIds,
+            final OperationExecutionDeletionOptions deletionOptions)
+    {
+        applicationServerApi.deleteOperationExecutions(toSessionToken(sessionTokenOrPAT), executionIds, deletionOptions);
+    }
+
+    @Override public void deleteSemanticAnnotations(final String sessionTokenOrPAT,
+            final List<? extends ISemanticAnnotationId> annotationIds,
+            final SemanticAnnotationDeletionOptions deletionOptions)
+    {
+        applicationServerApi.deleteSemanticAnnotations(toSessionToken(sessionTokenOrPAT), annotationIds, deletionOptions);
+    }
+
+    @Override public void deleteQueries(final String sessionTokenOrPAT, final List<? extends IQueryId> queryIds,
+            final QueryDeletionOptions deletionOptions)
+    {
+        applicationServerApi.deleteQueries(toSessionToken(sessionTokenOrPAT), queryIds, deletionOptions);
+    }
+
+    @Override public void deletePersons(final String sessionTokenOrPAT, final List<? extends IPersonId> personIds,
+            final PersonDeletionOptions deletionOptions)
+    {
+        applicationServerApi.deletePersons(toSessionToken(sessionTokenOrPAT), personIds, deletionOptions);
+    }
+
+    @Override public SearchResult<Deletion> searchDeletions(final String sessionTokenOrPAT,
+            final DeletionSearchCriteria searchCriteria, final DeletionFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchDeletions(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public SearchResult<Event> searchEvents(final String sessionTokenOrPAT, final EventSearchCriteria searchCriteria,
+            final EventFetchOptions fetchOptions)
+    {
+        return applicationServerApi.searchEvents(toSessionToken(sessionTokenOrPAT), searchCriteria, fetchOptions);
+    }
+
+    @Override public void revertDeletions(final String sessionTokenOrPAT,
+            final List<? extends IDeletionId> deletionIds)
+    {
+        applicationServerApi.revertDeletions(toSessionToken(sessionTokenOrPAT), deletionIds);
+    }
+
+    @Override public void confirmDeletions(final String sessionTokenOrPAT,
+            final List<? extends IDeletionId> deletionIds)
+    {
+        applicationServerApi.confirmDeletions(toSessionToken(sessionTokenOrPAT), deletionIds);
+    }
+
+    @Override public Object executeCustomASService(final String sessionTokenOrPAT, final ICustomASServiceId serviceId,
+            final CustomASServiceExecutionOptions options)
+    {
+        return applicationServerApi.executeCustomASService(toSessionToken(sessionTokenOrPAT), serviceId, options);
+    }
+
+    @Override public SearchResult<SearchDomainServiceExecutionResult> executeSearchDomainService(final String sessionTokenOrPAT,
+            final SearchDomainServiceExecutionOptions options)
+    {
+        return applicationServerApi.executeSearchDomainService(toSessionToken(sessionTokenOrPAT), options);
+    }
+
+    @Override public TableModel executeAggregationService(final String sessionTokenOrPAT, final IDssServiceId serviceId,
+            final AggregationServiceExecutionOptions options)
+    {
+        return applicationServerApi.executeAggregationService(toSessionToken(sessionTokenOrPAT), serviceId, options);
+    }
+
+    @Override public TableModel executeReportingService(final String sessionTokenOrPAT, final IDssServiceId serviceId,
+            final ReportingServiceExecutionOptions options)
+    {
+        return applicationServerApi.executeReportingService(toSessionToken(sessionTokenOrPAT), serviceId, options);
+    }
+
+    @Override public void executeProcessingService(final String sessionTokenOrPAT, final IDssServiceId serviceId,
+            final ProcessingServiceExecutionOptions options)
+    {
+        applicationServerApi.executeProcessingService(toSessionToken(sessionTokenOrPAT), serviceId, options);
+    }
+
+    @Override public TableModel executeQuery(final String sessionTokenOrPAT, final IQueryId queryId,
+            final QueryExecutionOptions options)
+    {
+        return applicationServerApi.executeQuery(toSessionToken(sessionTokenOrPAT), queryId, options);
+    }
+
+    @Override public TableModel executeSql(final String sessionTokenOrPAT, final String sql, final SqlExecutionOptions options)
+    {
+        return applicationServerApi.executeSql(toSessionToken(sessionTokenOrPAT), sql, options);
+    }
+
+    @Override public PluginEvaluationResult evaluatePlugin(final String sessionTokenOrPAT,
+            final PluginEvaluationOptions options)
+    {
+        return applicationServerApi.evaluatePlugin(toSessionToken(sessionTokenOrPAT), options);
+    }
+
+    @Override public void archiveDataSets(final String sessionTokenOrPAT, final List<? extends IDataSetId> dataSetIds,
+            final DataSetArchiveOptions options)
+    {
+        applicationServerApi.archiveDataSets(toSessionToken(sessionTokenOrPAT), dataSetIds, options);
+    }
+
+    @Override public void unarchiveDataSets(final String sessionTokenOrPAT,
+            final List<? extends IDataSetId> dataSetIds, final DataSetUnarchiveOptions options)
+    {
+        applicationServerApi.unarchiveDataSets(toSessionToken(sessionTokenOrPAT), dataSetIds, options);
+    }
+
+    @Override public void lockDataSets(final String sessionTokenOrPAT, final List<? extends IDataSetId> dataSetIds,
+            final DataSetLockOptions options)
+    {
+        applicationServerApi.lockDataSets(toSessionToken(sessionTokenOrPAT), dataSetIds, options);
+    }
+
+    @Override public void unlockDataSets(final String sessionTokenOrPAT, final List<? extends IDataSetId> dataSetIds,
+            final DataSetUnlockOptions options)
+    {
+        applicationServerApi.unlockDataSets(toSessionToken(sessionTokenOrPAT), dataSetIds, options);
+    }
+
+    @Override public IOperationExecutionResults executeOperations(final String sessionTokenOrPAT,
+            final List<? extends IOperation> operations, final IOperationExecutionOptions options)
+    {
+        return applicationServerApi.executeOperations(toSessionToken(sessionTokenOrPAT), operations, options);
+    }
+
+    @Override public Map<String, String> getServerInformation(final String sessionTokenOrPAT)
+    {
+        return applicationServerApi.getServerInformation(toSessionToken(sessionTokenOrPAT));
+    }
+
+    @Override public Map<String, String> getServerPublicInformation()
+    {
+        return applicationServerApi.getServerPublicInformation();
+    }
+
+    @Override public List<String> createPermIdStrings(final String sessionTokenOrPAT, final int count)
+    {
+        return applicationServerApi.createPermIdStrings(toSessionToken(sessionTokenOrPAT), count);
+    }
+
+    @Override public List<String> createCodes(final String sessionTokenOrPAT, final String prefix, final EntityKind entityKind, final int count)
+    {
+        return applicationServerApi.createCodes(toSessionToken(sessionTokenOrPAT), prefix, entityKind, count);
+    }
+
+    private String toSessionToken(String sessionTokenOrPAT)
+    {
+        IPersonalAccessTokenDAO patDAO = CommonServiceProvider.getDAOFactory().getPersonalAccessTokenDAO();
+        PersonalAccessToken patToken = patDAO.getTokenByHash(sessionTokenOrPAT);
+
+        if (patToken == null)
+        {
+            return sessionTokenOrPAT;
+        } else
+        {
+            Date now = new Date();
+
+            if (now.before(patToken.getValidFrom()))
+            {
+                throw new InvalidSessionException("Personal access token is not yet valid.");
+            }
+
+            if (now.after(patToken.getValidUntil()))
+            {
+                throw new InvalidSessionException("Personal access token is no longer valid.");
+            }
+
+            patToken.setLastAccessedAt(now);
+            patDAO.updateToken(patToken);
+
+            final PersonalAccessTokenSession patSession =
+                    patDAO.getSessionByUserIdAndSessionName(patToken.getUserId(), patToken.getSessionName());
+
+            if (patSession == null)
+            {
+                throw new InvalidSessionException("Personal access token session does not exist.");
+            } else
+            {
+                return patSession.getHash();
+            }
+        }
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/pat/ApplicationServerApiPersonalAccessTokenPostProcessor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/pat/ApplicationServerApiPersonalAccessTokenPostProcessor.java
new file mode 100644
index 0000000000000000000000000000000000000000..6f8189842f84f28b71e39bc9e08d1b4eaeb66715
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/pat/ApplicationServerApiPersonalAccessTokenPostProcessor.java
@@ -0,0 +1,26 @@
+package ch.ethz.sis.openbis.generic.server.asapi.v3.pat;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.IApplicationServerInternalApi;
+
+public class ApplicationServerApiPersonalAccessTokenPostProcessor implements BeanPostProcessor
+{
+
+    @Override public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException
+    {
+        if (!(bean instanceof IApplicationServerInternalApi))
+        {
+            return bean;
+        }
+
+        if (bean instanceof ApplicationServerApiPersonalAccessTokenDecorator)
+        {
+            return bean;
+        }
+
+        return new ApplicationServerApiPersonalAccessTokenDecorator((IApplicationServerInternalApi) bean);
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/OpenBisSessionManager.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/OpenBisSessionManager.java
index f438b240cc58b2b020bb1152eef1d7576a8b15b8..a7c28a76cd880ad12ff421cd5c4e15ffcfec90c6 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/OpenBisSessionManager.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/OpenBisSessionManager.java
@@ -19,10 +19,21 @@ package ch.systemsx.cisd.openbis.generic.server;
 import java.util.HashSet;
 import java.util.Set;
 
+import javax.annotation.PostConstruct;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.TransactionStatus;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.support.TransactionCallbackWithoutResult;
+import org.springframework.transaction.support.TransactionTemplate;
+
 import ch.systemsx.cisd.authentication.DefaultSessionManager;
 import ch.systemsx.cisd.authentication.IAuthenticationService;
 import ch.systemsx.cisd.authentication.ILogMessagePrefixGenerator;
 import ch.systemsx.cisd.authentication.ISessionFactory;
+import ch.systemsx.cisd.authentication.Principal;
+import ch.systemsx.cisd.common.exceptions.InvalidSessionException;
 import ch.systemsx.cisd.common.server.IRemoteHostProvider;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IPersonDAO;
@@ -50,7 +61,10 @@ public class OpenBisSessionManager extends DefaultSessionManager<Session> implem
         }
     }
 
-    IDAOFactory daoFactory;
+    @Autowired
+    private PlatformTransactionManager txManager;
+
+    private IDAOFactory daoFactory;
 
     private String userForAnonymousLogin;
 
@@ -64,7 +78,7 @@ public class OpenBisSessionManager extends DefaultSessionManager<Session> implem
     {
         super(sessionFactory, prefixGenerator, authenticationService, remoteHostProvider, sessionExpirationPeriodMinutes,
                 parseAsIntOrReturnDefaultValue(sessionExpirationPeriodMinutesForNoLogin, DEFAULT_SESSION_EXPIRATION_PERIOD_FOR_NO_LOGIN),
-                tryEmailAsUserName);
+                tryEmailAsUserName, daoFactory.getPersonalAccessTokenDAO());
         this.daoFactory = daoFactory;
     }
 
@@ -76,6 +90,43 @@ public class OpenBisSessionManager extends DefaultSessionManager<Session> implem
                 sessionExpirationPeriodMinutesForNoLogin, false, daoFactory);
     }
 
+    @PostConstruct
+    @Override protected void init()
+    {
+        TransactionTemplate tmpl = new TransactionTemplate(txManager);
+        tmpl.execute(new TransactionCallbackWithoutResult()
+        {
+            @Override
+            protected void doInTransactionWithoutResult(TransactionStatus status)
+            {
+                OpenBisSessionManager.super.init();
+            }
+        });
+    }
+
+    @Override protected FullSession<Session> createSession(final String sessionToken, final String userName, final Principal principal,
+            final String remoteHost, final long sessionStart, final int sessionExpirationTime, final boolean isPATSession)
+    {
+        FullSession<Session> session =
+                super.createSession(sessionToken, userName, principal, remoteHost, sessionStart, sessionExpirationTime, isPATSession);
+
+        if (session.isPATSession())
+        {
+            PersonPE person = daoFactory.getPersonDAO().tryFindPersonByUserId(userName);
+
+            if (person == null)
+            {
+                throw new InvalidSessionException(String.format("User '%s' not found in the database.", userName));
+            }
+
+            HibernateUtils.initialize(person.getAllPersonRoles());
+            session.getSession().setPerson(person);
+            session.getSession().setCreatorPerson(person);
+        }
+
+        return session;
+    }
+
     @Override
     protected int getMaxNumberOfSessionsFor(String user)
     {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceForDataStoreServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceForDataStoreServer.java
index cb22485c09853d59dbfd4b2eccb63ac20a4480ce..adf66070f00de075b5640c4049f1d0d0c2da685e 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceForDataStoreServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceForDataStoreServer.java
@@ -365,14 +365,14 @@ public class ServiceForDataStoreServer extends AbstractCommonServer<IServiceForD
                 dataSourceManager, new DefaultSessionManager<Session>(new SessionFactory(),
                         new LogMessagePrefixGenerator(), new DummyAuthenticationService(),
                         new RequestContextProviderAdapter(new IRequestContextProvider()
+                        {
+                            @Override
+                            public HttpServletRequest getHttpServletRequest()
                             {
-                                @Override
-                                public HttpServletRequest getHttpServletRequest()
-                                {
-                                    return null;
-                                }
-                            }),
-                        30),
+                                return null;
+                            }
+                        }),
+                        30, daoFactory.getPersonalAccessTokenDAO()),
                 managedPropertyEvaluatorFactory, null, null);
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBusinessObject.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBusinessObject.java
index 84c8a380bbfd7b49b67e1c5ea6a67974cce20c45..5b8b7089e5a45d11ce3c5d0093c0a20a2c90c8a5 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBusinessObject.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBusinessObject.java
@@ -26,6 +26,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import ch.systemsx.cisd.authentication.pat.IPersonalAccessTokenDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.*;
 import org.apache.commons.lang3.StringUtils;
 import org.hibernate.LockMode;
@@ -579,6 +580,11 @@ abstract class AbstractBusinessObject implements IDAOFactory
         return daoFactory.getSemanticAnnotationDAO();
     }
 
+    @Override public IPersonalAccessTokenDAO getPersonalAccessTokenDAO()
+    {
+        return daoFactory.getPersonalAccessTokenDAO();
+    }
+
     @Override
     public final IOperationExecutionDAO getOperationExecutionDAO()
     {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDAOFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDAOFactory.java
index 5425650990d83eff51aacda8697cca531e32749d..64a9bdec6b94d07f1e833e6535eda12f98b5dc51 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDAOFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDAOFactory.java
@@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.generic.server.dataaccess;
 
 import java.util.Date;
 
+import ch.systemsx.cisd.authentication.pat.IPersonalAccessTokenDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.ICodeSequenceDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.IPermIdDAO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
@@ -119,13 +120,21 @@ public interface IDAOFactory extends IAuthorizationDAOFactory
     /** Returns an implementation of {@link IEntityOperationsLogDAO}. */
     public IEntityOperationsLogDAO getEntityOperationsLogDAO();
 
-    /** Returns an implementation of {@link IExternalDataManagementSystemDAO}. */
+    /**
+     * Returns an implementation of {@link IExternalDataManagementSystemDAO}.
+     */
     public IExternalDataManagementSystemDAO getExternalDataManagementSystemDAO();
 
-    /** Returns an implementation of {@link IOperationExecutionDAO}. */
+    /**
+     * Returns an implementation of {@link IOperationExecutionDAO}.
+     */
     public IOperationExecutionDAO getOperationExecutionDAO();
 
-    /** Returns an implementation of {@link ISemanticAnnotationDAO}. */
+    /**
+     * Returns an implementation of {@link ISemanticAnnotationDAO}.
+     */
     public ISemanticAnnotationDAO getSemanticAnnotationDAO();
 
+    public IPersonalAccessTokenDAO getPersonalAccessTokenDAO();
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DAOFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DAOFactory.java
index 32b49d421129c4e13b7977c0e32d9f8201e367df..414b4287f5af0d594deed9704e304909aab58e95 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DAOFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DAOFactory.java
@@ -23,7 +23,10 @@ import java.util.*;
 
 import javax.annotation.Resource;
 
+import ch.systemsx.cisd.authentication.pat.FileBasedPersonalAccessTokenDAO;
+import ch.systemsx.cisd.authentication.pat.IPersonalAccessTokenDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.*;
+
 import org.apache.log4j.Logger;
 import org.hibernate.SessionFactory;
 import org.springframework.beans.factory.InitializingBean;
@@ -115,6 +118,8 @@ public final class DAOFactory extends AuthorizationDAOFactory implements IDAOFac
 
     private final ISemanticAnnotationDAO semanticAnnotationDAO;
 
+    private final IPersonalAccessTokenDAO personalAccessTokenDAO;
+
     private DatabaseConfigurationContext context;
 
     public static final boolean USE_NEW_SQL_ENGINE = true;
@@ -164,6 +169,7 @@ public final class DAOFactory extends AuthorizationDAOFactory implements IDAOFac
         operationExecutionDAO =
                 new OperationExecutionDAO(sessionFactory, historyCreator);
         semanticAnnotationDAO = new SemanticAnnotationDAO(sessionFactory, historyCreator);
+        personalAccessTokenDAO = new FileBasedPersonalAccessTokenDAO();
     }
 
     //
@@ -337,6 +343,11 @@ public final class DAOFactory extends AuthorizationDAOFactory implements IDAOFac
         return semanticAnnotationDAO;
     }
 
+    @Override public IPersonalAccessTokenDAO getPersonalAccessTokenDAO()
+    {
+        return personalAccessTokenDAO;
+    }
+
     private static String projectConstraintFunction =
             "CREATE FUNCTION check_project_is_defined_for_experiment_level_samples() " +
                     "  RETURNS trigger AS " +
diff --git a/openbis/source/java/genericApplicationContext.xml b/openbis/source/java/genericApplicationContext.xml
index d58a85f7cab4d5a5a479b555fe5f9750042caca0..5662defdcdc00198868ea3865f521d9617291385 100644
--- a/openbis/source/java/genericApplicationContext.xml
+++ b/openbis/source/java/genericApplicationContext.xml
@@ -581,29 +581,31 @@
 	</bean>
 
 	<bean id="objectMapper-v1"
-		class="ch.systemsx.cisd.openbis.generic.shared.api.v1.json.GenericObjectMapper" />
+		  class="ch.systemsx.cisd.openbis.generic.shared.api.v1.json.GenericObjectMapper"/>
 	<bean id="objectMapper-v3"
-		class="ch.ethz.sis.openbis.generic.server.sharedapi.v3.json.GenericObjectMapper" />
+		  class="ch.ethz.sis.openbis.generic.server.sharedapi.v3.json.GenericObjectMapper"/>
 
 	<!-- // Plugins -->
 
 	<bean
-		class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
+			class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
 	<bean
-		class="ch.systemsx.cisd.openbis.common.spring.AnnotationBeanPostProcessorIgnoringMissingBeans" />
+			class="ch.systemsx.cisd.openbis.common.spring.AnnotationBeanPostProcessorIgnoringMissingBeans"/>
+	<bean
+			class="ch.ethz.sis.openbis.generic.server.asapi.v3.pat.ApplicationServerApiPersonalAccessTokenPostProcessor"/>
 
 	<plugins:component-scan base-package="ch.systemsx.cisd.openbis"
-		annotation-config="false">
+							annotation-config="false">
 		<plugins:exclude-filter type="annotation"
-			expression="org.springframework.stereotype.Controller" />
+								expression="org.springframework.stereotype.Controller"/>
 	</plugins:component-scan>
 
 	<plugins:component-scan base-package="ch.ethz.sis.openbis"
-		annotation-config="false">
+							annotation-config="false">
 		<plugins:exclude-filter type="regex"
-			expression="ch\.ethz\.sis\.openbis\.generic\.server\.dssapi\..*" />
+								expression="ch\.ethz\.sis\.openbis\.generic\.server\.dssapi\..*"/>
 		<plugins:exclude-filter type="annotation"
-			expression="org.springframework.stereotype.Controller" />
+								expression="org.springframework.stereotype.Controller"/>
 	</plugins:component-scan>