diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/api/v1/client/impl/DssComponent.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/api/v1/client/impl/DssComponent.java
index 46b3d0e70c101e5ea9c8989b72b409a3f41ce9c4..174a346e7a660f1cea415aa2f823df62aca88f2c 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/api/v1/client/impl/DssComponent.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/api/v1/client/impl/DssComponent.java
@@ -28,10 +28,10 @@ import ch.systemsx.cisd.common.api.RpcServiceInterfaceVersionDTO;
 import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
 import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
 import ch.systemsx.cisd.common.exceptions.InvalidSessionException;
-import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.common.spring.HttpInvokerUtils;
 import ch.systemsx.cisd.openbis.dss.api.v1.client.IDataSetDss;
 import ch.systemsx.cisd.openbis.dss.api.v1.client.IDssComponent;
+import ch.systemsx.cisd.openbis.dss.api.v1.client.impl.OpenBisServiceFactory.ILimsServiceStubFactory;
 import ch.systemsx.cisd.openbis.dss.api.v1.shared.FileInfoDssDTO;
 import ch.systemsx.cisd.openbis.dss.api.v1.shared.IDssServiceRpcGeneric;
 import ch.systemsx.cisd.openbis.generic.shared.IETLLIMSService;
@@ -50,7 +50,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SessionContextDTO;
  */
 public class DssComponent implements IDssComponent
 {
-    private static final int SERVIER_TIMEOUT_MIN = 5;
+    private static final int SERVER_TIMEOUT_MIN = 5;
 
     private final IETLLIMSService openBisService;
 
@@ -89,9 +89,31 @@ public class DssComponent implements IDssComponent
     public static DssComponent tryCreate(String sessionToken, String openBISUrl)
     {
         DssComponent component = new DssComponent(openBISUrl, sessionToken);
+        try
+        {
+            component.checkSession();
+        } catch (InvalidSessionException e)
+        {
+            // Session has expired
+            return null;
+        }
         return component;
     }
 
+    private static IETLLIMSService createOpenBisService(String openBISURL)
+    {
+        ILimsServiceStubFactory stubFactory = new ILimsServiceStubFactory()
+            {
+                public IETLLIMSService createServiceStub(String serverUrl)
+                {
+                    return HttpInvokerUtils.createServiceStub(IETLLIMSService.class, serverUrl,
+                            SERVER_TIMEOUT_MIN);
+                }
+
+            };
+        return new OpenBisServiceFactory(openBISURL, stubFactory).createService();
+    }
+
     /**
      * Create a DSS component that connects to the openBIS instance specified by the URL.
      * <p>
@@ -104,8 +126,7 @@ public class DssComponent implements IDssComponent
      */
     private DssComponent(String openBISURL, String sessionTokenOrNull)
     {
-        this(HttpInvokerUtils.createServiceStub(IETLLIMSService.class, openBISURL + "/rmi-etl",
-                SERVIER_TIMEOUT_MIN), new DssServiceRpcFactory(), sessionTokenOrNull);
+        this(createOpenBisService(openBISURL), new DssServiceRpcFactory(), sessionTokenOrNull);
     }
 
     /**
@@ -282,7 +303,16 @@ class AuthenticatedState extends AbstractDssComponentState
     @Override
     void login(String user, String password) throws AuthorizationFailureException
     {
-        throw new UserFailureException("Already logged in.");
+        throw new IllegalStateException("Already logged in.");
+    }
+
+    @Override
+    public void checkSession()
+    {
+        if (null == service.tryGetSession(getSessionToken()))
+        {
+            throw new InvalidSessionException("Session has expired");
+        }
     }
 
     public void logout()
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/api/v1/client/impl/OpenBisServiceFactory.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/api/v1/client/impl/OpenBisServiceFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..6896419bc286e8eeb1d98e39be791e4042147bf5
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/api/v1/client/impl/OpenBisServiceFactory.java
@@ -0,0 +1,155 @@
+/*
+ * 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.api.v1.client.impl;
+
+import ch.systemsx.cisd.openbis.generic.shared.IETLLIMSService;
+
+/**
+ * A factory for creating proxies to the openBIS application server.
+ * <p>
+ * The OpenBisServiceFactory will create a proxy by trying several possible locations for the
+ * service.
+ * 
+ * @author Chandrasekhar Ramakrishnan
+ */
+public class OpenBisServiceFactory
+{
+    /**
+     * An interface that can create a {@link IETLLIMSService} proxy to a service located at a given
+     * a URL.
+     * 
+     * @author Chandrasekhar Ramakrishnan
+     */
+    public static interface ILimsServiceStubFactory
+    {
+        /**
+         * Create a proxy to the service located at the serverURL. Implementations should not alter
+         * the url, e.g., by appending something to it.
+         * 
+         * @param serverUrl The URL of of the IETLLIMSService service
+         * @return IETLLIMSService The service located at the serverUrl
+         */
+        public IETLLIMSService createServiceStub(String serverUrl);
+    }
+
+    private final String initialServerUrl;
+
+    private final ILimsServiceStubFactory stubFactory;
+
+    /**
+     * Constructor for the OpenBisServiceFactory. The service factory works best when the serverUrl
+     * is simply the protocol://machine:port of the openBIS application server. It will
+     * automatically append likely locations of the openBIS service to the url.
+     * <p>
+     * Examples:
+     * <ul>
+     * <li>OpenBisServiceFactory("http://localhost:8888/", stubFactory)</li>
+     * <li>OpenBisServiceFactory("https://openbis.ethz.ch:8443/", stubFactory)</li>
+     * </ul>
+     * 
+     * @param serverUrl The Url where the openBIS server is assumed to be.
+     * @param stubFactory A factory that, given a url, returns an IETLLIMSService proxy to the url
+     */
+    public OpenBisServiceFactory(String serverUrl, ILimsServiceStubFactory stubFactory)
+    {
+        this.initialServerUrl = serverUrl;
+        this.stubFactory = stubFactory;
+    }
+
+    /**
+     * Create a IETLLIMSService by trying several possible locations for the service until one that
+     * works is found. If the service cannot be found, a proxy to the constructor-provided serverUrl
+     * will be returned.
+     */
+    public IETLLIMSService createService()
+    {
+        IETLLIMSService service;
+        // Try the url that ends in openbis/openbis
+        service =
+                stubFactory.createServiceStub(computeOpenbisOpenbisServerUrl(initialServerUrl)
+                        + "/rmi-etl");
+        if (canConnectToService(service))
+        {
+            return service;
+        }
+
+        // Try the url that ends in just one openbis
+        service =
+                stubFactory.createServiceStub(computeOpenbisServerUrl(initialServerUrl)
+                        + "/rmi-etl");
+        if (canConnectToService(service))
+        {
+            return service;
+        }
+
+        // Try the url as provided
+        service = stubFactory.createServiceStub(initialServerUrl + "/rmi-etl");
+        return service;
+    }
+
+    private boolean canConnectToService(IETLLIMSService service)
+    {
+        try
+        {
+            service.getVersion();
+        } catch (Exception e)
+        {
+            return false;
+        }
+        return true;
+    }
+
+    private String computeOpenbisOpenbisServerUrl(String serverUrl)
+    {
+        if (serverUrl.endsWith("/openbis/openbis"))
+        {
+            return serverUrl;
+        }
+
+        if (serverUrl.endsWith("/openbis"))
+        {
+            return serverUrl + "/openbis";
+        }
+
+        String myServerUrl = serverUrl;
+        if (false == serverUrl.endsWith("/"))
+        {
+            myServerUrl = myServerUrl + "/";
+        }
+        return myServerUrl + "openbis/openbis";
+    }
+
+    private String computeOpenbisServerUrl(String serverUrl)
+    {
+        if (serverUrl.endsWith("/openbis/openbis"))
+        {
+            return serverUrl.substring(0, serverUrl.length() - "/openbis".length());
+        }
+
+        if (serverUrl.endsWith("/openbis"))
+        {
+            return serverUrl;
+        }
+
+        String myServerUrl = serverUrl;
+        if (false == serverUrl.endsWith("/"))
+        {
+            myServerUrl = myServerUrl + "/";
+        }
+        return myServerUrl + "openbis";
+    }
+}
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/api/v1/client/impl/DssComponentTestClient.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/api/v1/client/impl/DssComponentTestClient.java
index 297d8fdb5aebb322253b038bc8f76af8f0ea19d9..c8644fd6d2ba90236dbc34d5ff6b9bfda05138b5 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/api/v1/client/impl/DssComponentTestClient.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/api/v1/client/impl/DssComponentTestClient.java
@@ -36,7 +36,7 @@ public class DssComponentTestClient
         configureLogging();
         System.out.println("Logging in");
         IDssComponent component =
-                DssComponentFactory.tryCreate("test", "foobar", "http://localhost:8888/openbis");
+                DssComponentFactory.tryCreate("test", "foobar", "http://localhost:8888");
         IDataSetDss dataSet = component.getDataSet("20100318094819344-4");
         FileInfoDssDTO fileInfos[] = dataSet.listFiles("/", true);
         for (FileInfoDssDTO fileInfo : fileInfos)
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/api/v1/client/impl/OpenBisServiceFactoryTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/api/v1/client/impl/OpenBisServiceFactoryTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..387e68e968e5df90706f634d9feeb898ef4889c0
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/api/v1/client/impl/OpenBisServiceFactoryTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.api.v1.client.impl;
+
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.testng.AssertJUnit;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.openbis.dss.api.v1.client.impl.OpenBisServiceFactory.ILimsServiceStubFactory;
+import ch.systemsx.cisd.openbis.generic.shared.IETLLIMSService;
+
+/**
+ * @author Chandrasekhar Ramakrishnan
+ */
+public class OpenBisServiceFactoryTest extends AssertJUnit
+{
+    private Mockery context;
+
+    private IETLLIMSService openBisService;
+
+    private ILimsServiceStubFactory stubFactory;
+
+    @BeforeMethod
+    public void setUp()
+    {
+        context = new Mockery();
+        openBisService = context.mock(IETLLIMSService.class);
+        stubFactory = context.mock(ILimsServiceStubFactory.class);
+    }
+
+    @Test
+    public void testBasicUse()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    one(stubFactory).createServiceStub(
+                            "http://localhost:8888/openbis/openbis/rmi-etl");
+                    will(returnValue(openBisService));
+                    one(openBisService).getVersion();
+                }
+            });
+        OpenBisServiceFactory factory =
+                new OpenBisServiceFactory("http://localhost:8888", stubFactory);
+        factory.createService();
+        context.assertIsSatisfied();
+    }
+
+    @Test
+    public void testAlternateLocation()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    one(stubFactory).createServiceStub(
+                            "http://localhost:8888/openbis/openbis/rmi-etl");
+                    will(returnValue(openBisService));
+                    one(openBisService).getVersion();
+                    will(throwException(new Exception()));
+                    one(stubFactory).createServiceStub("http://localhost:8888/openbis/rmi-etl");
+                    will(returnValue(openBisService));
+                    one(openBisService).getVersion();
+                }
+            });
+        OpenBisServiceFactory factory =
+                new OpenBisServiceFactory("http://localhost:8888", stubFactory);
+        factory.createService();
+        context.assertIsSatisfied();
+    }
+
+    @Test
+    public void testLocationAlreadySpecified()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    one(stubFactory).createServiceStub(
+                            "http://localhost:8888/openbis/openbis/rmi-etl");
+                    will(returnValue(openBisService));
+                    one(openBisService).getVersion();
+                }
+            });
+        OpenBisServiceFactory factory =
+                new OpenBisServiceFactory("http://localhost:8888/openbis/openbis", stubFactory);
+        factory.createService();
+        context.assertIsSatisfied();
+    }
+}