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
new file mode 100644
index 0000000000000000000000000000000000000000..bb23ee2b878e39d8a225bf7f2e56db8b25416de0
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/AbstractCommand.java
@@ -0,0 +1,43 @@
+/*
+ * 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.rpc.client.cli;
+
+/**
+ * Superclass for dss command-line client commands.
+ * 
+ * @author Chandrasekhar Ramakrishnan
+ */
+abstract class AbstractCommand implements ICommand
+{
+
+    /**
+     * How is the program invoked from the command line? Used for displaying help.
+     */
+    protected String getProgramCallString()
+    {
+        return "dss " + getName();
+    }
+
+    /**
+     * The text "usage: " + the program call string. Used for displaying help.
+     */
+    protected String getUsagePrefixString()
+    {
+        return "usage: " + getProgramCallString();
+    }
+
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/CommandFactory.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/CommandFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..e213cdab4b1c5a99e99110915c48ab9f8452dfd6
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/CommandFactory.java
@@ -0,0 +1,47 @@
+/*
+ * 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.rpc.client.cli;
+
+import java.io.PrintStream;
+
+import ch.systemsx.cisd.openbis.dss.component.IDataSetDss;
+
+/**
+ * @author Chandrasekhar Ramakrishnan
+ */
+class CommandFactory
+{
+
+    ICommand tryCommandForName(String name, IDataSetDss dataSet)
+    {
+        if ("ls".equals(name))
+        {
+            return new CommandLs(dataSet);
+        }
+
+        return null;
+    }
+
+    void printHelpForName(String name, PrintStream out)
+    {
+        if ("ls".equals(name))
+        {
+            CommandLs command = new CommandLs(null);
+            command.printHelp(out);
+        }
+    }
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/CommandLs.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/CommandLs.java
new file mode 100644
index 0000000000000000000000000000000000000000..31af08de28e76f3b7f956e9d03b1a132c286a37b
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/CommandLs.java
@@ -0,0 +1,138 @@
+/*
+ * 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.rpc.client.cli;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import ch.systemsx.cisd.args4j.Argument;
+import ch.systemsx.cisd.args4j.CmdLineParser;
+import ch.systemsx.cisd.args4j.ExampleMode;
+import ch.systemsx.cisd.args4j.Option;
+import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.openbis.dss.component.IDataSetDss;
+import ch.systemsx.cisd.openbis.dss.rpc.shared.FileInfoDss;
+
+/**
+ * Comand that lists files in the data set.
+ * 
+ * @author Chandrasekhar Ramakrishnan
+ */
+class CommandLs extends AbstractCommand
+{
+    private static class CommandLsArguments
+    {
+        @Option(name = "r", longName = "recursive", usage = "Recurse into directories")
+        private boolean recursive = false;
+
+        @Argument
+        private final List<String> arguments = new ArrayList<String>();
+
+        public boolean isRecursive()
+        {
+            return recursive;
+        }
+
+        // Accessed via reflection
+        @SuppressWarnings("unused")
+        public void setRecursive(boolean recursive)
+        {
+            this.recursive = recursive;
+        }
+
+        public List<String> getArguments()
+        {
+            return arguments;
+        }
+    }
+
+    private final CommandLsArguments arguments;
+
+    private final CmdLineParser parser;
+
+    private final IDataSetDss dataSet;
+
+    /**
+     * Constructor for the command. The dataSet may be null if this command will only be used to
+     * print help.
+     * 
+     * @param dataSet
+     */
+    CommandLs(IDataSetDss dataSet)
+    {
+        arguments = new CommandLsArguments();
+        parser = new CmdLineParser(arguments);
+        this.dataSet = dataSet;
+    }
+
+    public int execute(String[] args) throws UserFailureException, EnvironmentFailureException
+    {
+        FileInfoDss[] fileInfos = getFileInfos(args);
+        printFileInfos(fileInfos);
+
+        return 0;
+    }
+
+    private FileInfoDss[] getFileInfos(String[] args)
+    {
+        parser.parseArgument(args);
+
+        String path;
+        if (arguments.getArguments().isEmpty())
+        {
+            path = "/";
+        } else
+        {
+            path = arguments.getArguments().get(0);
+        }
+
+        return dataSet.listFiles(path, arguments.isRecursive());
+    }
+
+    private void printFileInfos(FileInfoDss[] fileInfos)
+    {
+        for (FileInfoDss fileInfo : fileInfos)
+        {
+            StringBuilder sb = new StringBuilder();
+            sb.append(fileInfo.getPath());
+            sb.append(" -- ");
+            if (fileInfo.isDirectory())
+            {
+                sb.append("Directory");
+            } else
+            {
+                sb.append(fileInfo.getFileSize());
+            }
+            System.out.println(sb.toString());
+        }
+    }
+
+    public String getName()
+    {
+        return "ls";
+    }
+
+    public void printHelp(PrintStream out)
+    {
+        out.println(getProgramCallString() + " [options] <path>");
+        parser.printUsage(out);
+        out.println("  Example : " + getProgramCallString() + " "
+                + parser.printExample(ExampleMode.ALL));
+    }
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/GlobalArguments.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/GlobalArguments.java
new file mode 100644
index 0000000000000000000000000000000000000000..803361d96617a1e7c8d827a9ce3feac1b62c1da0
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/GlobalArguments.java
@@ -0,0 +1,163 @@
+/*
+ * 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.rpc.client.cli;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import ch.systemsx.cisd.args4j.Argument;
+import ch.systemsx.cisd.args4j.Option;
+
+/**
+ * Command line arguments for the dss command. The format is:
+ * <p>
+ * <code>
+ * [options] DATA_SET_CODE COMMAND [COMMAND_ARGS]
+ * </code>
+ * 
+ * @author Chandrasekhar Ramakrishnan
+ */
+class GlobalArguments
+{
+    @Option(name = "u", longName = "username", usage = "User login name (required)")
+    private String username = "";
+
+    @Option(name = "p", longName = "password", usage = "User login password (required)")
+    private String password = "";
+
+    @Option(name = "s", longName = "server-base-url", usage = "URL for openBIS Server (required)")
+    private String serverBaseUrl = "";
+
+    @Option(name = "h", longName = "help", skipForExample = true)
+    private boolean isHelp = false;
+
+    @Argument
+    private List<String> arguments = new ArrayList<String>();
+
+    public boolean isHelp()
+    {
+        return isHelp;
+    }
+
+    public void setHelp(boolean isHelp)
+    {
+        this.isHelp = isHelp;
+    }
+
+    public String getUsername()
+    {
+        return username;
+    }
+
+    public void setUsername(String username)
+    {
+        this.username = username;
+    }
+
+    public String getPassword()
+    {
+        return password;
+    }
+
+    public void setPassword(String password)
+    {
+        this.password = password;
+    }
+
+    public String getServerBaseUrl()
+    {
+        return serverBaseUrl;
+    }
+
+    public void setServerBaseUrl(String serverBaseUrl)
+    {
+        this.serverBaseUrl = serverBaseUrl;
+    }
+
+    public String getDataSetCode()
+    {
+        List<String> args = getArguments();
+        if (args.size() < 1)
+        {
+            return "";
+        }
+        return args.get(0);
+    }
+
+    public String getCommand()
+    {
+        List<String> args = getArguments();
+        if (args.size() < 2)
+        {
+            return "";
+        }
+        return args.get(1);
+    }
+
+    public boolean hasCommand()
+    {
+        return getArguments().size() > 1;
+    }
+
+    public List<String> getCommandArguments()
+    {
+        List<String> args = getArguments();
+        if (args.size() < 3)
+        {
+            return new ArrayList<String>();
+        }
+        return args.subList(2, args.size());
+    }
+
+    private List<String> getArguments()
+    {
+        return arguments;
+    }
+
+    /**
+     * Check that the arguments make sense.
+     */
+    public boolean isComplete()
+    {
+        if (isHelp)
+        {
+            return true;
+        }
+
+        // At the moment, username, passowrd, and server base url should all be non-empty
+        if (username.length() < 1)
+        {
+            return false;
+        }
+
+        if (password.length() < 1)
+        {
+            return false;
+        }
+        if (serverBaseUrl.length() < 1)
+        {
+            return false;
+        }
+        if (getDataSetCode().length() < 1)
+        {
+            return false;
+        }
+
+        return true;
+
+    }
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/ICommand.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/ICommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..9cba24a76fd0f4e381541cef2eccb596a6f86465
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/ICommand.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2009 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.rpc.client.cli;
+
+import java.io.PrintStream;
+
+import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+
+/**
+ * A <code>ICommand</code> encapsulates one action that gets called on the client side using the
+ * prompt or terminal window.
+ * 
+ * @author Bernd Rinn
+ */
+public interface ICommand
+{
+
+    /**
+     * Calls this <code>ICommand</code> with given <code>arguments</code>.
+     * <p>
+     * The arguments are the <code>main(String[])</code> method ones.
+     * </p>
+     * Note that this method is expected to throw given <code>RuntimeException</code>
+     * (<i>unchecked</i>) exceptions. So do not catch them and let the <i>caller</i> handle them.
+     * 
+     * @return exit code, will be used in <code>System.exit()</code>.
+     */
+    public int execute(final String[] arguments) throws UserFailureException,
+            EnvironmentFailureException;
+
+    /**
+     * Returns the name of this command.
+     * <p>
+     * On the client side, this <code>ICommand</code> is registered with this name. This is kind of
+     * unique identifier of this <code>ICommand</code>.
+     * </p>
+     */
+    public String getName();
+
+    /**
+     * Prints usage information for this command.
+     * 
+     * @param out The stream to which help is printed
+     */
+    public void printHelp(PrintStream out);
+
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/dss.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/dss.java
index 9c5bd1ef1b0dace91cd77372f9bbc6122398836f..2177e4bd4832183620d472f289d29539dce95418 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/dss.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/dss.java
@@ -16,10 +16,35 @@
 
 package ch.systemsx.cisd.openbis.dss.rpc.client.cli;
 
+import java.io.PrintStream;
+import java.net.UnknownHostException;
+
+import javax.net.ssl.SSLHandshakeException;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.remoting.RemoteAccessException;
+import org.springframework.remoting.RemoteConnectFailureException;
+
+import ch.systemsx.cisd.args4j.CmdLineParser;
+import ch.systemsx.cisd.args4j.ExampleMode;
+import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
+import ch.systemsx.cisd.common.exceptions.InvalidSessionException;
+import ch.systemsx.cisd.common.exceptions.MasqueradingException;
+import ch.systemsx.cisd.common.exceptions.SystemExitException;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.common.utilities.IExitHandler;
+import ch.systemsx.cisd.common.utilities.SystemExit;
+import ch.systemsx.cisd.openbis.dss.component.IDataSetDss;
 import ch.systemsx.cisd.openbis.dss.component.IDssComponent;
 import ch.systemsx.cisd.openbis.dss.component.impl.DssComponent;
 
 /**
+ * The dss command which supports
+ * <ul>
+ * <li>ls &mdash; list files in a data set</li>
+ * <li>get &mdash; get files in a data set</li>
+ * </ul>
+ * 
  * @author Chandrasekhar Ramakrishnan
  */
 public class dss
@@ -31,24 +56,230 @@ public class dss
                 "org.apache.commons.logging.impl.NoOpLog");
     }
 
-    private final IDssComponent component;
+    private final GlobalArguments arguments;
+
+    private final CmdLineParser parser;
+
+    private final CommandFactory commandFactory;
+
+    private final IExitHandler exitHandler;
 
     private dss()
     {
-        this.component = new DssComponent("http://localhost:8888/openbis");
+        this.exitHandler = SystemExit.SYSTEM_EXIT;
+        this.arguments = new GlobalArguments();
+        this.parser = new CmdLineParser(arguments);
+        this.commandFactory = new CommandFactory();
     }
 
     private void runWithArgs(String[] args)
     {
-        component.login("test", "foo");
-        System.out.println("" + component.getDataSet("20100318094819344-4"));
+        parser.parseArgument(args);
+
+        // Show help and exit
+        if (arguments.isHelp())
+        {
+            printHelp(System.out);
+            exitHandler.exit(0);
+        }
+
+        // Show usage and exit
+        if (arguments.isComplete() == false)
+        {
+            printUsage(System.err);
+            exitHandler.exit(1);
+        }
+
+        // Login to DSS
+        IDssComponent component = loginOrDie();
+
+        int resultCode = 0;
+
+        try
+        {
+            // Get the data set
+            IDataSetDss dataSet = component.getDataSet(arguments.getDataSetCode());
+
+            // Find the command and run it
+            ICommand cmd = commandFactory.tryCommandForName(arguments.getCommand(), dataSet);
+            String[] cmdArgs = new String[arguments.getCommandArguments().size()];
+            arguments.getCommandArguments().toArray(cmdArgs);
+            resultCode = cmd.execute(cmdArgs);
+        } catch (final InvalidSessionException ex)
+        {
+            System.err
+                    .println("Your session is no longer valid. Please login again. [server said: '"
+                            + ex.getMessage() + "']");
+            resultCode = 1;
+        } catch (final UserFailureException ex)
+        {
+            System.err.println();
+            System.err.println(ex.getMessage());
+            resultCode = 1;
+        } catch (final EnvironmentFailureException ex)
+        {
+            System.err.println();
+            System.err.println(ex.getMessage() + " (environment failure)");
+            resultCode = 1;
+        } catch (final RemoteConnectFailureException ex)
+        {
+            System.err.println();
+            System.err.println("Remote server cannot be reached (environment failure)");
+            resultCode = 1;
+        } catch (final RemoteAccessException ex)
+        {
+            System.err.println();
+            final Throwable cause = ex.getCause();
+            if (cause != null)
+            {
+                if (cause instanceof UnknownHostException)
+                {
+                    System.err.println(String.format(
+                            "Given host '%s' can not be reached  (environment failure)", cause
+                                    .getMessage()));
+                } else if (cause instanceof IllegalArgumentException)
+                {
+                    System.err.println(cause.getMessage());
+                } else if (cause instanceof SSLHandshakeException)
+                {
+                    final String property = "javax.net.ssl.trustStore";
+                    System.err.println(String.format(
+                            "Validation of SSL certificate failed [%s=%s] (configuration failure)",
+                            property, StringUtils.defaultString(System.getProperty(property))));
+                } else
+                {
+                    ex.printStackTrace();
+                }
+            } else
+            {
+                ex.printStackTrace();
+            }
+            resultCode = 1;
+        } catch (final SystemExitException e)
+        {
+            resultCode = 1;
+        } catch (MasqueradingException e)
+        {
+            System.err.println(e);
+            resultCode = 1;
+        } catch (IllegalArgumentException e)
+        {
+            System.err.println(e.getMessage());
+            resultCode = 1;
+        } catch (final Exception e)
+        {
+            System.err.println();
+            e.printStackTrace();
+            resultCode = 1;
+        } finally
+        {
+            // Cleanup
+            component.logout();
+        }
+
+        exitHandler.exit(resultCode);
+    }
+
+    /**
+     * Log in to openBIS or exit if login fails.
+     */
+    private IDssComponent loginOrDie()
+    {
+        try
+        {
+            IDssComponent component = new DssComponent(arguments.getServerBaseUrl());
+            component.login(arguments.getUsername(), arguments.getPassword());
+            return component;
+        } catch (final InvalidSessionException ex)
+        {
+            System.err
+                    .println("Your session is no longer valid. Please login again. [server said: '"
+                            + ex.getMessage() + "']");
+            exitHandler.exit(1);
+        } catch (final UserFailureException ex)
+        {
+            System.err.println();
+            System.err.println(ex.getMessage());
+            exitHandler.exit(1);
+        } catch (final EnvironmentFailureException ex)
+        {
+            System.err.println();
+            System.err.println(ex.getMessage() + " (environment failure)");
+            exitHandler.exit(1);
+        } catch (final RemoteConnectFailureException ex)
+        {
+            System.err.println();
+            System.err.println("Remote server cannot be reached (environment failure)");
+            exitHandler.exit(1);
+        } catch (final RemoteAccessException ex)
+        {
+            System.err.println();
+            final Throwable cause = ex.getCause();
+            if (cause != null)
+            {
+                if (cause instanceof UnknownHostException)
+                {
+                    System.err.println(String.format(
+                            "Given host '%s' can not be reached  (environment failure)", cause
+                                    .getMessage()));
+                } else if (cause instanceof IllegalArgumentException)
+                {
+                    System.err.println(cause.getMessage());
+                } else if (cause instanceof SSLHandshakeException)
+                {
+                    final String property = "javax.net.ssl.trustStore";
+                    System.err.println(String.format(
+                            "Validation of SSL certificate failed [%s=%s] (configuration failure)",
+                            property, StringUtils.defaultString(System.getProperty(property))));
+                } else
+                {
+                    ex.printStackTrace();
+                }
+            } else
+            {
+                ex.printStackTrace();
+            }
+            exitHandler.exit(1);
+        } catch (final SystemExitException e)
+        {
+            exitHandler.exit(1);
+        } catch (MasqueradingException e)
+        {
+            System.err.println(e);
+            exitHandler.exit(1);
+        } catch (final Exception e)
+        {
+            System.err.println();
+            e.printStackTrace();
+            exitHandler.exit(1);
+        }
+
+        // never reached
+        return null;
+    }
+
+    private void printHelp(PrintStream out)
+    {
+        if (arguments.hasCommand())
+        {
+            commandFactory.printHelpForName(arguments.getCommand(), out);
+        } else
+        {
+            printUsage(out);
+        }
+    }
+
+    private void printUsage(PrintStream out)
+    {
+        out.println("usage: dss [options...] COMMAND [ARGS]");
+        parser.printUsage(out);
+        out.println("  Example : dss " + parser.printExample(ExampleMode.ALL));
     }
 
     public static void main(String[] args)
     {
         dss newMe = new dss();
         newMe.runWithArgs(args);
-
     }
 
 }
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/GlobalArgumentsTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/GlobalArgumentsTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..4bca23cc9244be7ad918b0eb329de7d97765b70f
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/rpc/client/cli/GlobalArgumentsTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.rpc.client.cli;
+
+import org.testng.AssertJUnit;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.args4j.CmdLineException;
+import ch.systemsx.cisd.args4j.CmdLineParser;
+
+/**
+ * @author Chandrasekhar Ramakrishnan
+ */
+public class GlobalArgumentsTest extends AssertJUnit
+{
+
+    private GlobalArguments arguments;
+
+    private CmdLineParser parser;
+
+    @BeforeMethod
+    public void setUp()
+    {
+        arguments = new GlobalArguments();
+        parser = new CmdLineParser(arguments);
+    }
+
+    @Test
+    public void testParseBasicArguments()
+    {
+        String[] args =
+                    { "-u", "foo", "-p", "bar", "-s", "http://localhost:8888/openbis",
+                            "20100318094819344-4" };
+        try
+        {
+            parser.parseArgument(args);
+            assertEquals("foo", arguments.getUsername());
+            assertEquals("bar", arguments.getPassword());
+            assertEquals("http://localhost:8888/openbis", arguments.getServerBaseUrl());
+            assertEquals("20100318094819344-4", arguments.getDataSetCode());
+            assertTrue(arguments.isComplete());
+        } catch (CmdLineException c)
+        {
+            fail("Should have parsed arguments");
+        }
+    }
+
+    @Test
+    public void testParseIncompleteArguments()
+    {
+        String[] args =
+            { "-u", "foo", "-p", "bar", "-s", "http://localhost:8888/openbis" };
+        try
+        {
+            parser.parseArgument(args);
+            assertFalse(arguments.isComplete());
+        } catch (CmdLineException c)
+        {
+            fail("Should have parsed arguments");
+        }
+    }
+
+    @Test
+    public void testHelp()
+    {
+        String[] args =
+            { "-h" };
+        try
+        {
+            parser.parseArgument(args);
+            assertTrue(arguments.isComplete());
+        } catch (CmdLineException c)
+        {
+            fail("Should have parsed arguments");
+        }
+    }
+}