diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Session.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Session.java
index c35b9b11699941f998e0e4cd8c5c6c80ca620f55..704cd49e8ba5018f93b4af16ff630ee42ffd3bb8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Session.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Session.java
@@ -16,6 +16,9 @@
 
 package ch.systemsx.cisd.openbis.generic.shared.dto;
 
+import java.util.LinkedHashSet;
+import java.util.Set;
+
 import org.apache.commons.lang.time.DateFormatUtils;
 
 import ch.systemsx.cisd.authentication.BasicSession;
@@ -32,6 +35,14 @@ public final class Session extends BasicSession implements IAuthSession
 
     final private static long serialVersionUID = 1L;
 
+    public interface ISessionCleaner
+    {
+        /**
+         * Method called at the end of a session to perform some sort of cleanup.
+         */
+        public void cleanup();
+    }
+
     /**
      * The {@link PersonPE} represented by this <code>Session</code> or <code>null</code> if it is
      * not defined.
@@ -43,6 +54,8 @@ public final class Session extends BasicSession implements IAuthSession
      */
     private String baseIndexURL;
 
+    private final Set<ISessionCleaner> cleanupListeners = new LinkedHashSet<ISessionCleaner>();
+
     @Deprecated
     public Session()
     {
@@ -61,6 +74,16 @@ public final class Session extends BasicSession implements IAuthSession
         super(sessionToken, userName, principal, remoteHost, sessionStart, expirationTime);
     }
 
+    @Override
+    public void cleanup()
+    {
+        super.cleanup();
+        for (ISessionCleaner cleaner : cleanupListeners)
+        {
+            cleaner.cleanup();
+        }
+    }
+
     public final void setPerson(final PersonPE person)
     {
         this.personOrNull = person;
@@ -125,6 +148,22 @@ public final class Session extends BasicSession implements IAuthSession
         return personOrNull == null ? super.getUserName() : personOrNull.getUserId();
     }
 
+    /**
+     * Adds a new listener for session cleanup.
+     */
+    public void addCleanupListener(ISessionCleaner sessionCleaner)
+    {
+        cleanupListeners.add(sessionCleaner);
+    }
+
+    /**
+     * Removes a registered listener for session cleanup.
+     */
+    public void removeCleanupListener(ISessionCleaner sessionCleaner)
+    {
+        cleanupListeners.remove(sessionCleaner);
+    }
+
     //
     // Object
     //