diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/component/DssComponentFactory.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/component/DssComponentFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..aaad87287e795884461c64ec6f66ab30c9a59861
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/component/DssComponentFactory.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2010 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.dss.component;
+
+import ch.systemsx.cisd.openbis.dss.component.impl.DssComponent;
+
+/**
+ * A class that creates DssComponents.
+ * 
+ * @author Chandrasekhar Ramakrishnan
+ */
+public class DssComponentFactory
+{
+    /**
+     * Public factory method for creating an IDssComponent with a username and password.
+     * 
+     * @param user The user name
+     * @param password The user's password
+     * @param openBISUrl The URL to openBIS
+     */
+    public static IDssComponent tryCreate(String user, String password, String openBISUrl)
+    {
+        return DssComponent.tryCreate(user, password, openBISUrl);
+    }
+
+    /**
+     * Public factory method for creating an IDssComponent for a user that has already been
+     * authenticated.
+     * 
+     * @param sessionToken The session token provided by authentication
+     * @param openBISUrl The URL to openBIS
+     */
+    public static IDssComponent tryCreate(String sessionToken, String openBISUrl)
+    {
+        return DssComponent.tryCreate(sessionToken, openBISUrl);
+    }
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/component/IDssComponent.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/component/IDssComponent.java
index 347153aef1e5484ab04211efa3ffcfd3c4f5d9ae..f3f2229381baf58e569200a561e45daba6154690 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/component/IDssComponent.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/component/IDssComponent.java
@@ -16,7 +16,6 @@
 
 package ch.systemsx.cisd.openbis.dss.component;
 
-import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
 import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
 import ch.systemsx.cisd.common.exceptions.InvalidSessionException;
 
@@ -40,21 +39,19 @@ import ch.systemsx.cisd.common.exceptions.InvalidSessionException;
 public interface IDssComponent
 {
     /**
-     * Authenticates the <code>user</code> with given <code>password</code>.
+     * Checks whether the session is alive.
      * 
-     * @throws AuthorizationFailureException Thrown if the username / password do not authenticate.
-     * @throws EnvironmentFailureException Thrown in cases where it is not possible to connect to
-     *             the server.
+     * @throws InvalidSessionException If the session is not alive.
      */
-    public void login(final String user, final String password)
-            throws AuthorizationFailureException, EnvironmentFailureException;
+    public void checkSession() throws InvalidSessionException;
 
     /**
-     * Checks whether the session is alive.
+     * Returns the session token.
      * 
-     * @throws InvalidSessionException If the session is not alive.
+     * @return The session token for an authenticated user.
+     * @throws IllegalStateException Thrown if the user has not yet been authenticated.
      */
-    public void checkSession() throws InvalidSessionException;
+    public String getSessionToken() throws IllegalStateException;
 
     /**
      * Get a proxy to the data set designated by the given data set code.
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/component/impl/DssComponent.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/component/impl/DssComponent.java
index 1b8c14adcaf2279147b30cac72d3b01449b1e755..55170179799cba2a39d659554f7ae2171baa16e7 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/component/impl/DssComponent.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/component/impl/DssComponent.java
@@ -59,6 +59,40 @@ public class DssComponent implements IDssComponent
 
     private AbstractDssComponentState state;
 
+    /**
+     * Public factory method for creating a DssComponent with a username and password.
+     * 
+     * @param user The user name
+     * @param password The user's password
+     * @param openBISUrl The URL to openBIS
+     */
+    public static DssComponent tryCreate(String user, String password, String openBISUrl)
+    {
+        DssComponent component = new DssComponent(openBISUrl, null);
+        try
+        {
+            component.login(user, password);
+        } catch (AuthorizationFailureException e)
+        {
+            // User name / Password is incorrect.
+            return null;
+        }
+        return component;
+    }
+
+    /**
+     * Public factory method for creating a DssComponent for a user that has already been
+     * authenticated.
+     * 
+     * @param sessionToken The session token provided by authentication
+     * @param openBISUrl The URL to openBIS
+     */
+    public static DssComponent tryCreate(String sessionToken, String openBISUrl)
+    {
+        DssComponent component = new DssComponent(openBISUrl, sessionToken);
+        return component;
+    }
+
     /**
      * Create a DSS component that connects to the openBIS instance specified by the URL.
      * <p>
@@ -66,31 +100,40 @@ public class DssComponent implements IDssComponent
      * Once it has a connection to openBIS, it can figure out how to connect to DSS servers itself.
      * 
      * @param openBISURL The url to connect to openBIS
+     * @param sessionTokenOrNull A session token; If null is passed in, then login needs to be
+     *            called.
      */
-    public DssComponent(String openBISURL)
+    private DssComponent(String openBISURL, String sessionTokenOrNull)
     {
         this(HttpInvokerUtils.createServiceStub(IETLLIMSService.class, openBISURL + "/rmi-etl",
-                SERVIER_TIMEOUT_MIN), new DssServiceRpcFactory());
+                SERVIER_TIMEOUT_MIN), new DssServiceRpcFactory(), sessionTokenOrNull);
     }
 
     /**
-     * Internal constructor used for testing.
+     * Internal constructor, also used for testing.
      * 
-     * @param service
+     * @param service A proxy to the openBIS application server.
+     * @param dssServiceFactory A proxy to the DSS server.
+     * @param sessionTokenOrNull A session token, if the user has already logged in, or null
+     *            otherwise.
      */
-    protected DssComponent(IETLLIMSService service, IDssServiceRpcFactory dssServiceFactory)
+    protected DssComponent(IETLLIMSService service, IDssServiceRpcFactory dssServiceFactory,
+            String sessionTokenOrNull)
     {
         this.openBisService = service;
         this.dssServiceFactory = dssServiceFactory;
-        this.state = new UnauthenticatedState(service);
+        if (sessionTokenOrNull == null)
+        {
+            this.state = new UnauthenticatedState(service);
+        } else
+        {
+            this.state = new AuthenticatedState(service, dssServiceFactory, sessionTokenOrNull);
+        }
     }
 
-    public void login(String user, String password) throws AuthorizationFailureException,
-            EnvironmentFailureException
+    public String getSessionToken()
     {
-        // login and transition to the authenticated state
-        state.login(user, password);
-        state = new AuthenticatedState(openBisService, dssServiceFactory, state.getSession());
+        return state.getSessionToken();
     }
 
     public void checkSession() throws InvalidSessionException
@@ -110,6 +153,21 @@ public class DssComponent implements IDssComponent
         state.logout();
         state = new UnauthenticatedState(openBisService);
     }
+
+    /**
+     * Authenticates the <code>user</code> with given <code>password</code>.
+     * 
+     * @throws AuthorizationFailureException Thrown if the username / password do not authenticate.
+     * @throws EnvironmentFailureException Thrown in cases where it is not possible to connect to
+     *             the server.
+     */
+    void login(String user, String password) throws AuthorizationFailureException,
+            EnvironmentFailureException
+    {
+        // login and transition to the authenticated state
+        state.login(user, password);
+        state = new AuthenticatedState(openBisService, dssServiceFactory, state.getSessionToken());
+    }
 }
 
 /**
@@ -139,10 +197,20 @@ abstract class AbstractDssComponentState implements IDssComponent
         throw new IllegalStateException("Please log in");
     }
 
+    /**
+     * Authenticates the <code>user</code> with given <code>password</code>.
+     * 
+     * @throws AuthorizationFailureException Thrown if the username / password do not authenticate.
+     * @throws EnvironmentFailureException Thrown in cases where it is not possible to connect to
+     *             the server.
+     */
+    abstract void login(final String user, final String password)
+            throws AuthorizationFailureException, EnvironmentFailureException;
+
     /**
      * Package visible method used to transfer context information between states.
      */
-    abstract SessionContextDTO getSession();
+    public abstract String getSessionToken();
 }
 
 /**
@@ -161,14 +229,15 @@ class UnauthenticatedState extends AbstractDssComponentState
     }
 
     @Override
-    SessionContextDTO getSession()
+    public String getSessionToken()
     {
         if (sessionOrNull == null)
-            throw new UserFailureException("Please log in");
-        return sessionOrNull;
+            throw new IllegalStateException("Please log in");
+        return sessionOrNull.getSessionToken();
     }
 
-    public void login(String user, String password) throws AuthorizationFailureException,
+    @Override
+    void login(String user, String password) throws AuthorizationFailureException,
             EnvironmentFailureException
     {
         try
@@ -196,7 +265,7 @@ class UnauthenticatedState extends AbstractDssComponentState
  */
 class AuthenticatedState extends AbstractDssComponentState
 {
-    private final SessionContextDTO session;
+    private final String sessionToken;
 
     private final IDssServiceRpcFactory dssServiceFactory;
 
@@ -204,20 +273,15 @@ class AuthenticatedState extends AbstractDssComponentState
      * @param service
      */
     AuthenticatedState(IETLLIMSService service, IDssServiceRpcFactory dssServiceFactory,
-            SessionContextDTO session)
+            String sessionToken)
     {
         super(service);
         this.dssServiceFactory = dssServiceFactory;
-        this.session = session;
+        this.sessionToken = sessionToken;
     }
 
     @Override
-    SessionContextDTO getSession()
-    {
-        return session;
-    }
-
-    public void login(String user, String password) throws AuthorizationFailureException
+    void login(String user, String password) throws AuthorizationFailureException
     {
         throw new UserFailureException("Already logged in.");
     }
@@ -324,8 +388,9 @@ class AuthenticatedState extends AbstractDssComponentState
                 + IDssServiceRpcGeneric.DSS_SERVICE_NAME + " interface.");
     }
 
-    private String getSessionToken()
+    @Override
+    public String getSessionToken()
     {
-        return session.getSessionToken();
+        return sessionToken;
     }
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/AbstractCommand.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/AbstractCommand.java
index 559c6a53e5c32529b8d03022bf8b739ec3def623..577fa5b1ec855ac8a463b026318e769e4f78ea09 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/AbstractCommand.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/AbstractCommand.java
@@ -81,8 +81,9 @@ abstract class AbstractCommand implements ICommand
      */
     protected IDssComponent login(GlobalArguments arguments)
     {
-        IDssComponent component = new DssComponent(arguments.getServerBaseUrl());
-        component.login(arguments.getUsername(), arguments.getPassword());
+        IDssComponent component =
+                DssComponent.tryCreate(arguments.getUsername(), arguments.getPassword(), arguments
+                        .getServerBaseUrl());
         return component;
     }
 
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/component/impl/DssComponentTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/component/impl/DssComponentTest.java
index c92e1e41387b90748280ffa7bbee48020ca7a91e..c473f2c27ebffe73e4940e838f40b8edaff9e00f 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/component/impl/DssComponentTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/component/impl/DssComponentTest.java
@@ -75,7 +75,7 @@ public class DssComponentTest extends AbstractFileSystemTestCase
         context = new Mockery();
         openBisService = context.mock(IETLLIMSService.class);
         dssServiceFactory = context.mock(IDssServiceRpcFactory.class);
-        dssComponent = new DssComponent(openBisService, dssServiceFactory);
+        dssComponent = new DssComponent(openBisService, dssServiceFactory, null);
         randomDataFile = getFileWithRandomData(1);
     }
 
@@ -110,10 +110,22 @@ public class DssComponentTest extends AbstractFileSystemTestCase
         context.assertIsSatisfied();
     }
 
+    @Test
+    public void testListDataSetFilesNoLogin() throws IOException
+    {
+        dssComponent = new DssComponent(openBisService, dssServiceFactory, DUMMY_SESSSION_TOKEN);
+        setupExpectationsNoLogin();
+        IDataSetDss dataSetProxy = dssComponent.getDataSet("DummyDataSetCode");
+        FileInfoDssDTO[] fileInfos = dataSetProxy.listFiles("/", true);
+        assertEquals(1, fileInfos.length);
+
+        context.assertIsSatisfied();
+    }
+
     @Test
     public void testUnsupportedInterface() throws IOException
     {
-        setupExpectations("Some Server Interface");
+        setupExpectations("Some Server Interface", true);
 
         dssComponent.login("foo", "bar");
         try
@@ -163,10 +175,15 @@ public class DssComponentTest extends AbstractFileSystemTestCase
 
     private void setupExpectations() throws IOException
     {
-        setupExpectations(IDssServiceRpcGeneric.DSS_SERVICE_NAME);
+        setupExpectations(IDssServiceRpcGeneric.DSS_SERVICE_NAME, true);
     }
 
-    private void setupExpectations(String serviceName) throws IOException
+    private void setupExpectationsNoLogin() throws IOException
+    {
+        setupExpectations(IDssServiceRpcGeneric.DSS_SERVICE_NAME, false);
+    }
+
+    private void setupExpectations(String serviceName, final boolean needsLogin) throws IOException
     {
         final SessionContextDTO session = getDummySession();
         final ExternalData dataSetExternalData = new ExternalData();
@@ -200,8 +217,11 @@ public class DssComponentTest extends AbstractFileSystemTestCase
                 {
                     final String dataSetCode = "DummyDataSetCode";
 
-                    one(openBisService).tryToAuthenticate("foo", "bar");
-                    will(returnValue(session));
+                    if (needsLogin)
+                    {
+                        one(openBisService).tryToAuthenticate("foo", "bar");
+                        will(returnValue(session));
+                    }
                     allowing(openBisService).tryGetDataSet(DUMMY_SESSSION_TOKEN, dataSetCode);
                     will(returnValue(dataSetExternalData));
                     allowing(dssServiceFactory).getSupportedInterfaces(DUMMY_DSS_URL, false);
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/component/impl/DssComponentTestClient.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/component/impl/DssComponentTestClient.java
new file mode 100644
index 0000000000000000000000000000000000000000..afee477100a8e8a368064d08b04de8892d6ece1b
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/component/impl/DssComponentTestClient.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2010 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.dss.component.impl;
+
+import java.util.Properties;
+
+import org.apache.log4j.PropertyConfigurator;
+
+/**
+ * @author Chandrasekhar Ramakrishnan
+ */
+public class DssComponentTestClient
+{
+
+    public static void main(String[] args)
+    {
+        configureLogging();
+        System.out.println("Logging in");
+        DssComponent component =
+                DssComponent.tryCreate("test", "foobar", "http://localhost:8888/openbis");
+        component.getDataSet("20100318094819344-4");
+        component.logout();
+        System.out.println("Logging out");
+    }
+
+    private static void configureLogging()
+    {
+        Properties props = new Properties();
+        props.put("log4j.appender.STDOUT", "org.apache.log4j.ConsoleAppender");
+        props.put("log4j.appender.STDOUT.layout", "org.apache.log4j.PatternLayout");
+        props.put("log4j.appender.STDOUT.layout.ConversionPattern", "%d %-5p [%t] %c - %m%n");
+        props.put("log4j.rootLogger", "INFO, STDOUT");
+        PropertyConfigurator.configure(props);
+    }
+
+}